summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/comedi/Kconfig1355
-rw-r--r--drivers/staging/comedi/Makefile15
-rw-r--r--drivers/staging/comedi/TODO12
-rw-r--r--drivers/staging/comedi/comedi.h1528
-rw-r--r--drivers/staging/comedi/comedi_buf.c692
-rw-r--r--drivers/staging/comedi/comedi_fops.c3436
-rw-r--r--drivers/staging/comedi/comedi_internal.h73
-rw-r--r--drivers/staging/comedi/comedi_pci.c228
-rw-r--r--drivers/staging/comedi/comedi_pci.h57
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.c209
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.h49
-rw-r--r--drivers/staging/comedi/comedi_usb.c151
-rw-r--r--drivers/staging/comedi/comedi_usb.h42
-rw-r--r--drivers/staging/comedi/comedidev.h1054
-rw-r--r--drivers/staging/comedi/comedilib.h26
-rw-r--r--drivers/staging/comedi/drivers.c1184
-rw-r--r--drivers/staging/comedi/drivers/8255.c125
-rw-r--r--drivers/staging/comedi/drivers/8255.h42
-rw-r--r--drivers/staging/comedi/drivers/8255_pci.c295
-rw-r--r--drivers/staging/comedi/drivers/Makefile175
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c396
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c887
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c216
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c820
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_16xx.c178
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2032.c330
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2200.c143
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c1117
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c417
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c961
-rw-r--r--drivers/staging/comedi/drivers/addi_tcw.h64
-rw-r--r--drivers/staging/comedi/drivers/addi_watchdog.c140
-rw-r--r--drivers/staging/comedi/drivers/addi_watchdog.h10
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c201
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7x3x.c542
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c154
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c747
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c1736
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c243
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c963
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1720.c186
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c227
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1724.c208
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1760.c424
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c801
-rw-r--r--drivers/staging/comedi/drivers/aio_aio12_8.c277
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c235
-rw-r--r--drivers/staging/comedi/drivers/amcc_s5933.h175
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c265
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.h46
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_common.c858
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_pci.c415
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c76
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.h33
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236_common.c193
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c102
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c1143
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c2575
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci236.c144
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci263.c111
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c298
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c456
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c1499
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c4119
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c421
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c475
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c192
-rw-r--r--drivers/staging/comedi/drivers/comedi_8254.c655
-rw-r--r--drivers/staging/comedi/drivers/comedi_8254.h134
-rw-r--r--drivers/staging/comedi/drivers/comedi_8255.c276
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c347
-rw-r--r--drivers/staging/comedi/drivers/comedi_isadma.c267
-rw-r--r--drivers/staging/comedi/drivers/comedi_isadma.h114
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c306
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c849
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c117
-rw-r--r--drivers/staging/comedi/drivers/dac02.c137
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c787
-rw-r--r--drivers/staging/comedi/drivers/das08.c470
-rw-r--r--drivers/staging/comedi/drivers/das08.h46
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c104
-rw-r--r--drivers/staging/comedi/drivers/das08_isa.c190
-rw-r--r--drivers/staging/comedi/drivers/das08_pci.c96
-rw-r--r--drivers/staging/comedi/drivers/das16.c1200
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c622
-rw-r--r--drivers/staging/comedi/drivers/das1800.c1364
-rw-r--r--drivers/staging/comedi/drivers/das6402.c669
-rw-r--r--drivers/staging/comedi/drivers/das800.c744
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c616
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c645
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c645
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c372
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c217
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c140
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c1172
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c740
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c871
-rw-r--r--drivers/staging/comedi/drivers/dyna_pci10xx.c265
-rw-r--r--drivers/staging/comedi/drivers/fl512.c143
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c723
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c336
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c524
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c816
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h735
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c232
-rw-r--r--drivers/staging/comedi/drivers/me4000.c1278
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c556
-rw-r--r--drivers/staging/comedi/drivers/mf6x4.c311
-rw-r--r--drivers/staging/comedi/drivers/mite.c938
-rw-r--r--drivers/staging/comedi/drivers/mite.h93
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c311
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c332
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c493
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c823
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c1255
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c282
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c782
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c374
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c360
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c729
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c280
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c82
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c116
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h55
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_common.c1363
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c112
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.c181
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.h43
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_pci.c132
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_regs.h76
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c6341
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c218
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c1010
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c1477
-rw-r--r--drivers/staging/comedi/drivers/ni_routes.c562
-rw-r--r--drivers/staging/comedi/drivers/ni_routes.h330
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/README240
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes.c51
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes.h32
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/all.h54
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c639
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6220.c1418
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6221.c1602
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6229.c1602
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6251.c1652
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6254.c1464
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6259.c1652
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6534.c290
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6602.c3378
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6713.c400
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6723.c400
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6733.c428
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c608
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c1432
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c1613
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c1655
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c428
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c1656
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c575
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c3083
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_route_values.c42
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_route_values.h98
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_route_values/all.h37
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_660x.c650
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_eseries.c602
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_mseries.c1752
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/tools/.gitignore8
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/tools/Makefile80
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/tools/convert_c_to_py.c159
-rwxr-xr-xdrivers/staging/comedi/drivers/ni_routing/tools/convert_csv_to_c.py503
-rwxr-xr-xdrivers/staging/comedi/drivers/ni_routing/tools/convert_py_to_csv.py67
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/tools/csv_collection.py40
-rwxr-xr-xdrivers/staging/comedi/drivers/ni_routing/tools/make_blank_csv.py32
-rw-r--r--drivers/staging/comedi/drivers/ni_routing/tools/ni_names.py56
-rw-r--r--drivers/staging/comedi/drivers/ni_stc.h1142
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c1842
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h181
-rw-r--r--drivers/staging/comedi/drivers/ni_tio_internal.h176
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c510
-rw-r--r--drivers/staging/comedi/drivers/ni_usb6501.c602
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c513
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c153
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c425
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c350
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c1336
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c696
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c1137
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c227
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c149
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c165
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c777
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c624
-rw-r--r--drivers/staging/comedi/drivers/plx9052.h70
-rw-r--r--drivers/staging/comedi/drivers/plx9080.h656
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c842
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c1365
-rw-r--r--drivers/staging/comedi/drivers/rti800.c357
-rw-r--r--drivers/staging/comedi/drivers/rti802.c120
-rw-r--r--drivers/staging/comedi/drivers/s526.c629
-rw-r--r--drivers/staging/comedi/drivers/s626.c2605
-rw-r--r--drivers/staging/comedi/drivers/s626.h869
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c180
-rw-r--r--drivers/staging/comedi/drivers/tests/Makefile8
-rw-r--r--drivers/staging/comedi/drivers/tests/comedi_example_test.c72
-rw-r--r--drivers/staging/comedi/drivers/tests/ni_routes_test.c611
-rw-r--r--drivers/staging/comedi/drivers/tests/unittest.h63
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c1729
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c1039
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c1616
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c880
-rw-r--r--drivers/staging/comedi/drivers/z8536.h210
-rw-r--r--drivers/staging/comedi/kcomedilib/Makefile6
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c255
-rw-r--r--drivers/staging/comedi/proc.c74
-rw-r--r--drivers/staging/comedi/range.c131
217 files changed, 0 insertions, 132821 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 7b57b755bfa3..808e78d6cd98 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -26,8 +26,6 @@ if STAGING
source "drivers/staging/wlan-ng/Kconfig"
-source "drivers/staging/comedi/Kconfig"
-
source "drivers/staging/olpc_dcon/Kconfig"
source "drivers/staging/rtl8192u/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 4350423f65aa..5a871f0ff2f4 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -3,7 +3,6 @@
obj-y += media/
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
-obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
deleted file mode 100644
index 3cb61fa2c5c3..000000000000
--- a/drivers/staging/comedi/Kconfig
+++ /dev/null
@@ -1,1355 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config COMEDI
- tristate "Data acquisition support (comedi)"
- help
- Enable support for a wide range of data acquisition devices
- for Linux.
-
-if COMEDI
-
-config COMEDI_DEBUG
- bool "Comedi debugging"
- help
- This is an option for use by developers; most people should
- say N here. This enables comedi core and driver debugging.
-
-config COMEDI_DEFAULT_BUF_SIZE_KB
- int "Comedi default initial asynchronous buffer size in KiB"
- default "2048"
- help
- This is the default asynchronous buffer size which is used for
- commands running in the background in kernel space. This
- defaults to 2048 KiB of memory so that a 16 channel card
- running at 10 kHz has of 2-4 seconds of buffer.
-
-config COMEDI_DEFAULT_BUF_MAXSIZE_KB
- int "Comedi default maximum asynchronous buffer size in KiB"
- default "20480"
- help
- This is the default maximum asynchronous buffer size which can
- be requested by a userspace program without root privileges.
- This is set to 20480 KiB so that a fast I/O card with 16
- channels running at 100 kHz has 2-4 seconds of buffer.
-
-menuconfig COMEDI_MISC_DRIVERS
- bool "Comedi misc drivers"
- help
- Enable comedi misc drivers to be built
-
- Note that the answer to this question won't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about misc non-hardware comedi drivers.
-
-if COMEDI_MISC_DRIVERS
-
-config COMEDI_BOND
- tristate "Comedi device bonding support"
- select COMEDI_KCOMEDILIB
- help
- Enable support for a driver to 'bond' (merge) multiple subdevices
- from multiple devices together as one.
-
- Currently, it only handles digital I/O subdevices.
-
- To compile this driver as a module, choose M here: the module will be
- called comedi_bond.
-
-config COMEDI_TEST
- tristate "Fake waveform generator support"
- help
- Enable support for the fake waveform generator.
- This driver is mainly for testing purposes, but can also be used to
- generate sample waveforms on systems that don't have data acquisition
- hardware.
-
- To compile this driver as a module, choose M here: the module will be
- called comedi_test.
-
-config COMEDI_PARPORT
- tristate "Parallel port support"
- help
- Enable support for the standard parallel port.
- A cheap and easy way to get a few more digital I/O lines. Steal
- additional parallel ports from old computers or your neighbors'
- computers.
-
- To compile this driver as a module, choose M here: the module will be
- called comedi_parport.
-
-config COMEDI_SSV_DNP
- tristate "SSV Embedded Systems DIL/Net-PC support"
- depends on X86_32 || COMPILE_TEST
- help
- Enable support for SSV Embedded Systems DIL/Net-PC
-
- To compile this driver as a module, choose M here: the module will be
- called ssv_dnp.
-
-endif # COMEDI_MISC_DRIVERS
-
-menuconfig COMEDI_ISA_DRIVERS
- bool "Comedi ISA and PC/104 drivers"
- help
- Enable comedi ISA and PC/104 drivers to be built
-
- Note that the answer to this question won't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about ISA and PC/104 comedi drivers.
-
-if COMEDI_ISA_DRIVERS
-
-config COMEDI_PCL711
- tristate "Advantech PCL-711/711b and ADlink ACL-8112 ISA card support"
- select COMEDI_8254
- help
- Enable support for Advantech PCL-711 and 711b, ADlink ACL-8112
-
- To compile this driver as a module, choose M here: the module will be
- called pcl711.
-
-config COMEDI_PCL724
- tristate "Advantech PCL-722/724/731 and ADlink ACL-7122/7124/PET-48DIO"
- select COMEDI_8255
- help
- Enable support for ISA and PC/104 based 8255 digital i/o boards. This
- driver provides a legacy comedi driver wrapper for the generic 8255
- support driver.
-
- Supported boards include:
- Advantech PCL-724 24 channels
- Advantech PCL-722 144 (or 96) channels
- Advantech PCL-731 48 channels
- ADlink ACL-7122 144 (or 96) channels
- ADlink ACL-7124 24 channels
- ADlink PET-48DIO 48 channels
- WinSystems PCM-IO48 48 channels (PC/104)
- Diamond Systems ONYX-MM-DIO 48 channels (PC/104)
-
- To compile this driver as a module, choose M here: the module will be
- called pcl724.
-
-config COMEDI_PCL726
- tristate "Advantech PCL-726 and compatible ISA card support"
- help
- Enable support for Advantech PCL-726 and compatible ISA cards.
-
- To compile this driver as a module, choose M here: the module will be
- called pcl726.
-
-config COMEDI_PCL730
- tristate "Simple Digital I/O board support (8-bit ports)"
- help
- Enable support for various simple ISA or PC/104 Digital I/O boards.
- These boards all use 8-bit I/O ports.
-
- Advantech PCL-730 iso - 16 in/16 out ttl - 16 in/16 out
- ICP ISO-730 iso - 16 in/16 out ttl - 16 in/16 out
- ADlink ACL-7130 iso - 16 in/16 out ttl - 16 in/16 out
- Advantech PCM-3730 iso - 8 in/8 out ttl - 16 in/16 out
- Advantech PCL-725 iso - 8 in/8 out
- ICP P8R8-DIO iso - 8 in/8 out
- ADlink ACL-7225b iso - 16 in/16 out
- ICP P16R16-DIO iso - 16 in/16 out
- Advantech PCL-733 iso - 32 in
- Advantech PCL-734 iso - 32 out
- Diamond Systems OPMM-1616-XT iso - 16 in/16 out
- Diamond Systems PEARL-MM-P iso - 16 out
- Diamond Systems IR104-PBF iso - 20 in/20 out
-
- To compile this driver as a module, choose M here: the module will be
- called pcl730.
-
-config COMEDI_PCL812
- tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216"
- select COMEDI_ISADMA if ISA_DMA_API
- select COMEDI_8254
- help
- Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink
- ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA,
- A-822PGH/PGL, A-823PGH/PGL, A-826PG and ICP DAS ISO-813 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called pcl812.
-
-config COMEDI_PCL816
- tristate "Advantech PCL-814 and PCL-816 ISA card support"
- select COMEDI_ISADMA if ISA_DMA_API
- select COMEDI_8254
- help
- Enable support for Advantech PCL-814 and PCL-816 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called pcl816.
-
-config COMEDI_PCL818
- tristate "Advantech PCL-718 and PCL-818 ISA card support"
- select COMEDI_ISADMA if ISA_DMA_API
- select COMEDI_8254
- help
- Enable support for Advantech PCL-818 ISA cards
- PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718
-
- To compile this driver as a module, choose M here: the module will be
- called pcl818.
-
-config COMEDI_PCM3724
- tristate "Advantech PCM-3724 PC/104 card support"
- select COMEDI_8255
- help
- Enable support for Advantech PCM-3724 PC/104 cards.
-
- To compile this driver as a module, choose M here: the module will be
- called pcm3724.
-
-config COMEDI_AMPLC_DIO200_ISA
- tristate "Amplicon PC212E/PC214E/PC215E/PC218E/PC272E"
- select COMEDI_AMPLC_DIO200
- help
- Enable support for Amplicon PC212E, PC214E, PC215E, PC218E and
- PC272E ISA DIO boards
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_dio200.
-
-config COMEDI_AMPLC_PC236_ISA
- tristate "Amplicon PC36AT DIO board support"
- select COMEDI_AMPLC_PC236
- help
- Enable support for Amplicon PC36AT ISA DIO board.
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_pc236.
-
-config COMEDI_AMPLC_PC263_ISA
- tristate "Amplicon PC263 relay board support"
- help
- Enable support for Amplicon PC263 ISA relay board. This board has
- 16 reed relay output channels.
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_pc263.
-
-config COMEDI_RTI800
- tristate "Analog Devices RTI-800/815 ISA card support"
- help
- Enable support for Analog Devices RTI-800/815 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called rti800.
-
-config COMEDI_RTI802
- tristate "Analog Devices RTI-802 ISA card support"
- help
- Enable support for Analog Devices RTI-802 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called rti802.
-
-config COMEDI_DAC02
- tristate "Keithley Metrabyte DAC02 compatible ISA card support"
- help
- Enable support for Keithley Metrabyte DAC02 compatible ISA cards.
-
- To compile this driver as a module, choose M here: the module will be
- called dac02.
-
-config COMEDI_DAS16M1
- tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support"
- select COMEDI_8254
- select COMEDI_8255
- help
- Enable support for Measurement Computing CIO-DAS16/M1 ISA cards.
-
- To compile this driver as a module, choose M here: the module will be
- called das16m1.
-
-config COMEDI_DAS08_ISA
- tristate "DAS-08 compatible ISA and PC/104 card support"
- select COMEDI_DAS08
- help
- Enable support for Keithley Metrabyte/ComputerBoards DAS08
- and compatible ISA and PC/104 cards:
- Keithley Metrabyte/ComputerBoards DAS08, DAS08-PGM, DAS08-PGH,
- DAS08-PGL, DAS08-AOH, DAS08-AOL, DAS08-AOM, DAS08/JR-AO,
- DAS08/JR-16-AO, PC104-DAS08, DAS08/JR/16.
-
- To compile this driver as a module, choose M here: the module will be
- called das08_isa.
-
-config COMEDI_DAS16
- tristate "DAS-16 compatible ISA and PC/104 card support"
- select COMEDI_ISADMA if ISA_DMA_API
- select COMEDI_8254
- select COMEDI_8255
- help
- Enable support for Keithley Metrabyte/ComputerBoards DAS16
- and compatible ISA and PC/104 cards:
- Keithley Metrabyte DAS-16, DAS-16G, DAS-16F, DAS-1201, DAS-1202,
- DAS-1401, DAS-1402, DAS-1601, DAS-1602 and
- ComputerBoards/MeasurementComputing PC104-DAS16/JR/,
- PC104-DAS16JR/16, CIO-DAS16JR/16, CIO-DAS16/JR, CIO-DAS1401/12,
- CIO-DAS1402/12, CIO-DAS1402/16, CIO-DAS1601/12, CIO-DAS1602/12,
- CIO-DAS1602/16, CIO-DAS16/330
-
- To compile this driver as a module, choose M here: the module will be
- called das16.
-
-config COMEDI_DAS800
- tristate "DAS800 and compatible ISA card support"
- select COMEDI_8254
- help
- Enable support for Keithley Metrabyte DAS800 and compatible ISA cards
- Keithley Metrabyte DAS-800, DAS-801, DAS-802
- Measurement Computing CIO-DAS800, CIO-DAS801, CIO-DAS802 and
- CIO-DAS802/16
-
- To compile this driver as a module, choose M here: the module will be
- called das800.
-
-config COMEDI_DAS1800
- tristate "DAS1800 and compatible ISA card support"
- select COMEDI_ISADMA if ISA_DMA_API
- select COMEDI_8254
- help
- Enable support for DAS1800 and compatible ISA cards
- Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO,
- DAS-1702ST, DAS-1702ST-DA, DAS-1702HR, DAS-1702HR-DA, DAS-1702/AO,
- DAS-1801ST, DAS-1801ST-DA, DAS-1801HC, DAS-1801AO, DAS-1802ST,
- DAS-1802ST-DA, DAS-1802HR, DAS-1802HR-DA, DAS-1802HC and
- DAS-1802AO
-
- To compile this driver as a module, choose M here: the module will be
- called das1800.
-
-config COMEDI_DAS6402
- tristate "DAS6402 and compatible ISA card support"
- select COMEDI_8254
- help
- Enable support for DAS6402 and compatible ISA cards
- Computerboards, Keithley Metrabyte DAS6402 and compatibles
-
- To compile this driver as a module, choose M here: the module will be
- called das6402.
-
-config COMEDI_DT2801
- tristate "Data Translation DT2801 ISA card support"
- help
- Enable support for Data Translation DT2801 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called dt2801.
-
-config COMEDI_DT2811
- tristate "Data Translation DT2811 ISA card support"
- help
- Enable support for Data Translation DT2811 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called dt2811.
-
-config COMEDI_DT2814
- tristate "Data Translation DT2814 ISA card support"
- help
- Enable support for Data Translation DT2814 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called dt2814.
-
-config COMEDI_DT2815
- tristate "Data Translation DT2815 ISA card support"
- help
- Enable support for Data Translation DT2815 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called dt2815.
-
-config COMEDI_DT2817
- tristate "Data Translation DT2817 ISA card support"
- help
- Enable support for Data Translation DT2817 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called dt2817.
-
-config COMEDI_DT282X
- tristate "Data Translation DT2821 series and DT-EZ ISA card support"
- select COMEDI_ISADMA if ISA_DMA_API
- help
- Enable support for Data Translation DT2821 series including DT-EZ
- DT2821, DT2821-F-16SE, DT2821-F-8DI, DT2821-G-16SE, DT2821-G-8DI,
- DT2823 (dt2823), DT2824-PGH, DT2824-PGL, DT2825, DT2827, DT2828,
- DT21-EZ, DT23-EZ, DT24-EZ and DT24-EZ-PGL
-
- To compile this driver as a module, choose M here: the module will be
- called dt282x.
-
-config COMEDI_DMM32AT
- tristate "Diamond Systems MM-32-AT PC/104 board support"
- select COMEDI_8255
- help
- Enable support for Diamond Systems MM-32-AT PC/104 boards
-
- To compile this driver as a module, choose M here: the module will be
- called dmm32at.
-
-config COMEDI_FL512
- tristate "FL512 ISA card support"
- help
- Enable support for FL512 ISA card
-
- To compile this driver as a module, choose M here: the module will be
- called fl512.
-
-config COMEDI_AIO_AIO12_8
- tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support"
- select COMEDI_8254
- select COMEDI_8255
- help
- Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board
-
- To compile this driver as a module, choose M here: the module will be
- called aio_aio12_8.
-
-config COMEDI_AIO_IIRO_16
- tristate "I/O Products PC/104 IIRO16 Board support"
- help
- Enable support for I/O Products PC/104 IIRO16 Relay And Isolated
- Input Board
-
- To compile this driver as a module, choose M here: the module will be
- called aio_iiro_16.
-
-config COMEDI_II_PCI20KC
- tristate "Intelligent Instruments PCI-20001C carrier support"
- depends on HAS_IOMEM
- help
- Enable support for Intelligent Instruments PCI-20001C carrier
- PCI-20001, PCI-20006 and PCI-20341
-
- To compile this driver as a module, choose M here: the module will be
- called ii_pci20kc.
-
-config COMEDI_C6XDIGIO
- tristate "Mechatronic Systems Inc. C6x_DIGIO DSP daughter card support"
- help
- Enable support for Mechatronic Systems Inc. C6x_DIGIO DSP daughter
- card
-
- To compile this driver as a module, choose M here: the module will be
- called c6xdigio.
-
-config COMEDI_MPC624
- tristate "Micro/sys MPC-624 PC/104 board support"
- help
- Enable support for Micro/sys MPC-624 PC/104 board
-
- To compile this driver as a module, choose M here: the module will be
- called mpc624.
-
-config COMEDI_ADQ12B
- tristate "MicroAxial ADQ12-B data acquisition and control card support"
- help
- Enable MicroAxial ADQ12-B daq and control card support.
-
- To compile this driver as a module, choose M here: the module will be
- called adq12b.
-
-config COMEDI_NI_AT_A2150
- tristate "NI AT-A2150 ISA card support"
- select COMEDI_ISADMA if ISA_DMA_API
- select COMEDI_8254
- help
- Enable support for National Instruments AT-A2150 cards
-
- To compile this driver as a module, choose M here: the module will be
- called ni_at_a2150.
-
-config COMEDI_NI_AT_AO
- tristate "NI AT-AO-6/10 EISA card support"
- select COMEDI_8254
- help
- Enable support for National Instruments AT-AO-6/10 cards
-
- To compile this driver as a module, choose M here: the module will be
- called ni_at_ao.
-
-config COMEDI_NI_ATMIO
- tristate "NI AT-MIO E series ISA-PNP card support"
- select COMEDI_8255
- select COMEDI_NI_TIO
- help
- Enable support for National Instruments AT-MIO E series cards
- National Instruments AT-MIO-16E-1 (ni_atmio),
- AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
- AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
-
- To compile this driver as a module, choose M here: the module will be
- called ni_atmio.
-
-config COMEDI_NI_ATMIO16D
- tristate "NI AT-MIO-16/AT-MIO-16D series ISA card support"
- select COMEDI_8255
- help
- Enable support for National Instruments AT-MIO-16/AT-MIO-16D cards.
-
- To compile this driver as a module, choose M here: the module will be
- called ni_atmio16d.
-
-config COMEDI_NI_LABPC_ISA
- tristate "NI Lab-PC and compatibles ISA support"
- select COMEDI_NI_LABPC
- help
- Enable support for National Instruments Lab-PC and compatibles
- Lab-PC-1200, Lab-PC-1200AI, Lab-PC+.
- Kernel-level ISA plug-and-play support for the lab-pc-1200 boards has
- not yet been added to the driver.
-
- To compile this driver as a module, choose M here: the module will be
- called ni_labpc.
-
-config COMEDI_PCMAD
- tristate "Winsystems PCM-A/D12 and PCM-A/D16 PC/104 board support"
- help
- Enable support for Winsystems PCM-A/D12 and PCM-A/D16 PC/104 boards.
-
- To compile this driver as a module, choose M here: the module will be
- called pcmad.
-
-config COMEDI_PCMDA12
- tristate "Winsystems PCM-D/A-12 8-channel AO PC/104 board support"
- help
- Enable support for Winsystems PCM-D/A-12 8-channel AO PC/104 boards.
- Note that the board is not ISA-PNP capable and thus needs the I/O
- port comedi_config parameter.
-
- To compile this driver as a module, choose M here: the module will be
- called pcmda12.
-
-config COMEDI_PCMMIO
- tristate "Winsystems PCM-MIO PC/104 board support"
- help
- Enable support for Winsystems PCM-MIO multifunction PC/104 boards.
-
- To compile this driver as a module, choose M here: the module will be
- called pcmmio.
-
-config COMEDI_PCMUIO
- tristate "Winsystems PCM-UIO48A and PCM-UIO96A PC/104 board support"
- help
- Enable support for PCM-UIO48A and PCM-UIO96A PC/104 boards.
-
- To compile this driver as a module, choose M here: the module will be
- called pcmuio.
-
-config COMEDI_MULTIQ3
- tristate "Quanser Consulting MultiQ-3 ISA card support"
- help
- Enable support for Quanser Consulting MultiQ-3 ISA cards
-
- To compile this driver as a module, choose M here: the module will be
- called multiq3.
-
-config COMEDI_S526
- tristate "Sensoray s526 support"
- help
- Enable support for Sensoray s526
-
- To compile this driver as a module, choose M here: the module will be
- called s526.
-
-endif # COMEDI_ISA_DRIVERS
-
-menuconfig COMEDI_PCI_DRIVERS
- tristate "Comedi PCI drivers"
- depends on PCI
- help
- Enable support for comedi PCI drivers.
-
- To compile this support as a module, choose M here: the module will
- be called comedi_pci.
-
-if COMEDI_PCI_DRIVERS
-
-config COMEDI_8255_PCI
- tristate "Generic PCI based 8255 digital i/o board support"
- select COMEDI_8255
- help
- Enable support for PCI based 8255 digital i/o boards. This driver
- provides a PCI wrapper around the generic 8255 driver.
-
- Supported boards:
- ADlink - PCI-7224, PCI-7248, and PCI-7296
- Measurement Computing - PCI-DIO24, PCI-DIO24H, PCI-DIO48H and
- PCI-DIO96H
- National Instruments - PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503,
- PCI-6503B, PCI-6503X, and PXI-6503
-
- To compile this driver as a module, choose M here: the module will
- be called 8255_pci.
-
-config COMEDI_ADDI_WATCHDOG
- tristate
- help
- Provides support for the watchdog subdevice found on many ADDI-DATA
- boards. This module will be automatically selected when needed. The
- module will be called addi_watchdog.
-
-config COMEDI_ADDI_APCI_1032
- tristate "ADDI-DATA APCI_1032 support"
- help
- Enable support for ADDI-DATA APCI_1032 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_1032.
-
-config COMEDI_ADDI_APCI_1500
- tristate "ADDI-DATA APCI_1500 support"
- help
- Enable support for ADDI-DATA APCI_1500 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_1500.
-
-config COMEDI_ADDI_APCI_1516
- tristate "ADDI-DATA APCI-1016/1516/2016 support"
- select COMEDI_ADDI_WATCHDOG
- help
- Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards.
- These are 16 channel, optically isolated, digital I/O boards. The 1516
- and 2016 boards also have a watchdog for resetting the outputs to "0".
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_1516.
-
-config COMEDI_ADDI_APCI_1564
- tristate "ADDI-DATA APCI_1564 support"
- select COMEDI_ADDI_WATCHDOG
- help
- Enable support for ADDI-DATA APCI_1564 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_1564.
-
-config COMEDI_ADDI_APCI_16XX
- tristate "ADDI-DATA APCI_16xx support"
- help
- Enable support for ADDI-DATA APCI_16xx cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_16xx.
-
-config COMEDI_ADDI_APCI_2032
- tristate "ADDI-DATA APCI_2032 support"
- select COMEDI_ADDI_WATCHDOG
- help
- Enable support for ADDI-DATA APCI_2032 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_2032.
-
-config COMEDI_ADDI_APCI_2200
- tristate "ADDI-DATA APCI_2200 support"
- select COMEDI_ADDI_WATCHDOG
- help
- Enable support for ADDI-DATA APCI_2200 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_2200.
-
-config COMEDI_ADDI_APCI_3120
- tristate "ADDI-DATA APCI_3120/3001 support"
- depends on HAS_DMA
- help
- Enable support for ADDI-DATA APCI_3120/3001 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_3120.
-
-config COMEDI_ADDI_APCI_3501
- tristate "ADDI-DATA APCI_3501 support"
- help
- Enable support for ADDI-DATA APCI_3501 cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_3501.
-
-config COMEDI_ADDI_APCI_3XXX
- tristate "ADDI-DATA APCI_3xxx support"
- help
- Enable support for ADDI-DATA APCI_3xxx cards
-
- To compile this driver as a module, choose M here: the module will be
- called addi_apci_3xxx.
-
-config COMEDI_ADL_PCI6208
- tristate "ADLink PCI-6208A support"
- help
- Enable support for ADLink PCI-6208A cards
-
- To compile this driver as a module, choose M here: the module will be
- called adl_pci6208.
-
-config COMEDI_ADL_PCI7X3X
- tristate "ADLink PCI-723X/743X isolated digital i/o board support"
- help
- Enable support for ADlink PCI-723X/743X isolated digital i/o boards.
- Supported boards include the 32-channel PCI-7230 (16 in/16 out),
- PCI-7233 (32 in), and PCI-7234 (32 out) as well as the 64-channel
- PCI-7432 (32 in/32 out), PCI-7433 (64 in), and PCI-7434 (64 out).
-
- To compile this driver as a module, choose M here: the module will be
- called adl_pci7x3x.
-
-config COMEDI_ADL_PCI8164
- tristate "ADLink PCI-8164 4 Axes Motion Control board support"
- help
- Enable support for ADlink PCI-8164 4 Axes Motion Control board
-
- To compile this driver as a module, choose M here: the module will be
- called adl_pci8164.
-
-config COMEDI_ADL_PCI9111
- tristate "ADLink PCI-9111HR support"
- select COMEDI_8254
- help
- Enable support for ADlink PCI9111 cards
-
- To compile this driver as a module, choose M here: the module will be
- called adl_pci9111.
-
-config COMEDI_ADL_PCI9118
- tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support"
- depends on HAS_DMA
- select COMEDI_8254
- help
- Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards
-
- To compile this driver as a module, choose M here: the module will be
- called adl_pci9118.
-
-config COMEDI_ADV_PCI1710
- tristate "Advantech PCI-171x and PCI-1731 support"
- select COMEDI_8254
- help
- Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711,
- PCI-1713 and PCI-1731
-
- To compile this driver as a module, choose M here: the module will be
- called adv_pci1710.
-
-config COMEDI_ADV_PCI1720
- tristate "Advantech PCI-1720 support"
- help
- Enable support for Advantech PCI-1720 Analog Output board.
-
- To compile this driver as a module, choose M here: the module will be
- called adv_pci1720.
-
-config COMEDI_ADV_PCI1723
- tristate "Advantech PCI-1723 support"
- help
- Enable support for Advantech PCI-1723 cards
-
- To compile this driver as a module, choose M here: the module will be
- called adv_pci1723.
-
-config COMEDI_ADV_PCI1724
- tristate "Advantech PCI-1724U support"
- help
- Enable support for Advantech PCI-1724U cards. These are 32-channel
- analog output cards with voltage and current loop output ranges and
- 14-bit resolution.
-
- To compile this driver as a module, choose M here: the module will be
- called adv_pci1724.
-
-config COMEDI_ADV_PCI1760
- tristate "Advantech PCI-1760 support"
- help
- Enable support for Advantech PCI-1760 board.
-
- To compile this driver as a module, choose M here: the module will be
- called adv_pci1760.
-
-config COMEDI_ADV_PCI_DIO
- tristate "Advantech PCI DIO card support"
- select COMEDI_8254
- select COMEDI_8255
- help
- Enable support for Advantech PCI DIO cards
- PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U,
- PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756,
- PCI-1761 and PCI-1762
-
- To compile this driver as a module, choose M here: the module will be
- called adv_pci_dio.
-
-config COMEDI_AMPLC_DIO200_PCI
- tristate "Amplicon PCI215/PCI272/PCIe215/PCIe236/PCIe296 DIO support"
- select COMEDI_AMPLC_DIO200
- help
- Enable support for Amplicon PCI215, PCI272, PCIe215, PCIe236
- and PCIe296 DIO boards.
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_dio200_pci.
-
-config COMEDI_AMPLC_PC236_PCI
- tristate "Amplicon PCI236 DIO board support"
- select COMEDI_AMPLC_PC236
- help
- Enable support for Amplicon PCI236 DIO board.
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_pci236.
-
-config COMEDI_AMPLC_PC263_PCI
- tristate "Amplicon PCI263 relay board support"
- help
- Enable support for Amplicon PCI263 relay board. This is a PCI board
- with 16 reed relay output channels.
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_pci263.
-
-config COMEDI_AMPLC_PCI224
- tristate "Amplicon PCI224 and PCI234 support"
- select COMEDI_8254
- help
- Enable support for Amplicon PCI224 and PCI234 AO boards
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_pci224.
-
-config COMEDI_AMPLC_PCI230
- tristate "Amplicon PCI230 and PCI260 support"
- select COMEDI_8254
- select COMEDI_8255
- help
- Enable support for Amplicon PCI230 and PCI260 Multifunction I/O
- boards
-
- To compile this driver as a module, choose M here: the module will be
- called amplc_pci230.
-
-config COMEDI_CONTEC_PCI_DIO
- tristate "Contec PIO1616L digital I/O board support"
- help
- Enable support for the Contec PIO1616L digital I/O board
-
- To compile this driver as a module, choose M here: the module will be
- called contec_pci_dio.
-
-config COMEDI_DAS08_PCI
- tristate "DAS-08 PCI support"
- select COMEDI_DAS08
- help
- Enable support for PCI DAS-08 cards.
-
- To compile this driver as a module, choose M here: the module will be
- called das08_pci.
-
-config COMEDI_DT3000
- tristate "Data Translation DT3000 series support"
- help
- Enable support for Data Translation DT3000 series
- DT3001, DT3001-PGL, DT3002, DT3003, DT3003-PGL, DT3004, DT3005 and
- DT3004-200
-
- To compile this driver as a module, choose M here: the module will be
- called dt3000.
-
-config COMEDI_DYNA_PCI10XX
- tristate "Dynalog PCI DAQ series support"
- help
- Enable support for Dynalog PCI DAQ series
- PCI-1050
-
- To compile this driver as a module, choose M here: the module will be
- called dyna_pci10xx.
-
-config COMEDI_GSC_HPDI
- tristate "General Standards PCI-HPDI32 / PMC-HPDI32 support"
- help
- Enable support for General Standards Corporation high speed parallel
- digital interface rs485 boards PCI-HPDI32 and PMC-HPDI32.
- Only receive mode works, transmit not supported.
-
- To compile this driver as a module, choose M here: the module will be
- called gsc_hpdi.
-
-config COMEDI_MF6X4
- tristate "Humusoft MF634 and MF624 DAQ Card support"
- help
- This driver supports both Humusoft MF634 and MF624 Data acquisition
- cards. The legacy Humusoft MF614 card is not supported.
-
-config COMEDI_ICP_MULTI
- tristate "Inova ICP_MULTI support"
- help
- Enable support for Inova ICP_MULTI card
-
- To compile this driver as a module, choose M here: the module will be
- called icp_multi.
-
-config COMEDI_DAQBOARD2000
- tristate "IOtech DAQboard/2000 support"
- select COMEDI_8255
- help
- Enable support for the IOtech DAQboard/2000
-
- To compile this driver as a module, choose M here: the module will be
- called daqboard2000.
-
-config COMEDI_JR3_PCI
- tristate "JR3/PCI force sensor board support"
- help
- Enable support for JR3/PCI force sensor boards
-
- To compile this driver as a module, choose M here: the module will be
- called jr3_pci.
-
-config COMEDI_KE_COUNTER
- tristate "Kolter-Electronic PCI Counter 1 card support"
- help
- Enable support for Kolter-Electronic PCI Counter 1 cards
-
- To compile this driver as a module, choose M here: the module will be
- called ke_counter.
-
-config COMEDI_CB_PCIDAS64
- tristate "MeasurementComputing PCI-DAS 64xx, 60xx, and 4020 support"
- select COMEDI_8255
- help
- Enable support for ComputerBoards/MeasurementComputing PCI-DAS 64xx,
- 60xx, and 4020 series with the PLX 9080 PCI controller
-
- To compile this driver as a module, choose M here: the module will be
- called cb_pcidas64.
-
-config COMEDI_CB_PCIDAS
- tristate "MeasurementComputing PCI-DAS support"
- select COMEDI_8254
- select COMEDI_8255
- help
- Enable support for ComputerBoards/MeasurementComputing PCI-DAS with
- AMCC S5933 PCIcontroller: PCI-DAS1602/16, PCI-DAS1602/16jr,
- PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr, PCI-DAS1000, PCI-DAS1001
- and PCI_DAS1002.
-
- To compile this driver as a module, choose M here: the module will be
- called cb_pcidas.
-
-config COMEDI_CB_PCIDDA
- tristate "MeasurementComputing PCI-DDA series support"
- select COMEDI_8255
- help
- Enable support for ComputerBoards/MeasurementComputing PCI-DDA
- series: PCI-DDA08/12, PCI-DDA04/12, PCI-DDA02/12, PCI-DDA08/16,
- PCI-DDA04/16 and PCI-DDA02/16
-
- To compile this driver as a module, choose M here: the module will be
- called cb_pcidda.
-
-config COMEDI_CB_PCIMDAS
- tristate "MeasurementComputing PCIM-DAS1602/16, PCIe-DAS1602/16 support"
- select COMEDI_8254
- select COMEDI_8255
- help
- Enable support for ComputerBoards/MeasurementComputing PCI Migration
- series PCIM-DAS1602/16 and PCIe-DAS1602/16.
-
- To compile this driver as a module, choose M here: the module will be
- called cb_pcimdas.
-
-config COMEDI_CB_PCIMDDA
- tristate "MeasurementComputing PCIM-DDA06-16 support"
- select COMEDI_8255
- help
- Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16
-
- To compile this driver as a module, choose M here: the module will be
- called cb_pcimdda.
-
-config COMEDI_ME4000
- tristate "Meilhaus ME-4000 support"
- select COMEDI_8254
- help
- Enable support for Meilhaus PCI data acquisition cards
- ME-4650, ME-4670i, ME-4680, ME-4680i and ME-4680is
-
- To compile this driver as a module, choose M here: the module will be
- called me4000.
-
-config COMEDI_ME_DAQ
- tristate "Meilhaus ME-2000i, ME-2600i, ME-3000vm1 support"
- help
- Enable support for Meilhaus PCI data acquisition cards
- ME-2000i, ME-2600i and ME-3000vm1
-
- To compile this driver as a module, choose M here: the module will be
- called me_daq.
-
-config COMEDI_NI_6527
- tristate "NI 6527 support"
- help
- Enable support for the National Instruments 6527 PCI card
-
- To compile this driver as a module, choose M here: the module will be
- called ni_6527.
-
-config COMEDI_NI_65XX
- tristate "NI 65xx static dio PCI card support"
- help
- Enable support for National Instruments 65xx static dio boards.
- Supported devices: National Instruments PCI-6509 (ni_65xx),
- PXI-6509, PCI-6510, PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513,
- PXI-6513, PCI-6514, PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517,
- PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
-
- To compile this driver as a module, choose M here: the module will be
- called ni_65xx.
-
-config COMEDI_NI_660X
- tristate "NI 660x counter/timer PCI card support"
- depends on HAS_DMA
- select COMEDI_NI_TIOCMD
- help
- Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602,
- PXI-6602, PXI-6608, PCI-6624, and PXI-6624.
-
- To compile this driver as a module, choose M here: the module will be
- called ni_660x.
-
-config COMEDI_NI_670X
- tristate "NI 670x PCI card support"
- help
- Enable support for National Instruments PCI-6703 and PCI-6704
-
- To compile this driver as a module, choose M here: the module will be
- called ni_670x.
-
-config COMEDI_NI_LABPC_PCI
- tristate "NI Lab-PC PCI-1200 support"
- select COMEDI_NI_LABPC
- help
- Enable support for National Instruments Lab-PC PCI-1200.
-
- To compile this driver as a module, choose M here: the module will be
- called ni_labpc_pci.
-
-config COMEDI_NI_PCIDIO
- tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support"
- depends on HAS_DMA
- select COMEDI_MITE
- select COMEDI_8255
- help
- Enable support for National Instruments PCI-DIO-32HS, PXI-6533,
- PCI-6533 and PCI-6534
-
- To compile this driver as a module, choose M here: the module will be
- called ni_pcidio.
-
-config COMEDI_NI_PCIMIO
- tristate "NI PCI-MIO-E series and M series support"
- depends on HAS_DMA
- select COMEDI_NI_TIOCMD
- select COMEDI_8255
- help
- Enable support for National Instruments PCI-MIO-E series and M series
- (all boards): PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1,
- PCI-MIO-16E-4, PCI-6014, PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E,
- PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E,
- PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E, PCI-6110, PCI-6111,
- PCI-6220, PXI-6220, PCI-6221, PXI-6221, PCI-6224, PXI-6224, PCI-6225,
- PXI-6225, PCI-6229, PXI-6229, PCI-6250, PXI-6250, PCI-6251, PXI-6251,
- PCIe-6251, PXIe-6251, PCI-6254, PXI-6254, PCI-6259, PXI-6259,
- PCIe-6259, PXIe-6259, PCI-6280, PXI-6280, PCI-6281, PXI-6281,
- PCI-6284, PXI-6284, PCI-6289, PXI-6289, PCI-6711, PXI-6711,
- PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E, PXI-6052E,
- PCI-6036E, PCI-6731, PCI-6733, PXI-6733, PCI-6143, PXI-6143
-
- To compile this driver as a module, choose M here: the module will be
- called ni_pcimio.
-
-config COMEDI_RTD520
- tristate "Real Time Devices PCI4520/DM7520 support"
- select COMEDI_8254
- help
- Enable support for Real Time Devices PCI4520/DM7520
-
- To compile this driver as a module, choose M here: the module will be
- called rtd520.
-
-config COMEDI_S626
- tristate "Sensoray 626 support"
- help
- Enable support for Sensoray 626
-
- To compile this driver as a module, choose M here: the module will be
- called s626.
-
-config COMEDI_MITE
- depends on HAS_DMA
- tristate
-
-config COMEDI_NI_TIOCMD
- tristate
- depends on HAS_DMA
- select COMEDI_NI_TIO
- select COMEDI_MITE
-
-endif # COMEDI_PCI_DRIVERS
-
-menuconfig COMEDI_PCMCIA_DRIVERS
- tristate "Comedi PCMCIA drivers"
- depends on PCMCIA
- help
- Enable support for comedi PCMCIA drivers.
-
- To compile this support as a module, choose M here: the module will
- be called comedi_pcmcia.
-
-if COMEDI_PCMCIA_DRIVERS
-
-config COMEDI_CB_DAS16_CS
- tristate "CB DAS16 series PCMCIA support"
- select COMEDI_8254
- help
- Enable support for the ComputerBoards/MeasurementComputing PCMCIA
- cards DAS16/16, PCM-DAS16D/12 and PCM-DAS16s/16
-
- To compile this driver as a module, choose M here: the module will be
- called cb_das16_cs.
-
-config COMEDI_DAS08_CS
- tristate "CB DAS08 PCMCIA support"
- select COMEDI_DAS08
- help
- Enable support for the ComputerBoards/MeasurementComputing DAS-08
- PCMCIA card
-
- To compile this driver as a module, choose M here: the module will be
- called das08_cs.
-
-config COMEDI_NI_DAQ_700_CS
- tristate "NI DAQCard-700 PCMCIA support"
- help
- Enable support for the National Instruments PCMCIA DAQCard-700 DIO
-
- To compile this driver as a module, choose M here: the module will be
- called ni_daq_700.
-
-config COMEDI_NI_DAQ_DIO24_CS
- tristate "NI DAQ-Card DIO-24 PCMCIA support"
- select COMEDI_8255
- help
- Enable support for the National Instruments PCMCIA DAQ-Card DIO-24
-
- To compile this driver as a module, choose M here: the module will be
- called ni_daq_dio24.
-
-config COMEDI_NI_LABPC_CS
- tristate "NI DAQCard-1200 PCMCIA support"
- select COMEDI_NI_LABPC
- help
- Enable support for the National Instruments PCMCIA DAQCard-1200
-
- To compile this driver as a module, choose M here: the module will be
- called ni_labpc_cs.
-
-config COMEDI_NI_MIO_CS
- tristate "NI DAQCard E series PCMCIA support"
- select COMEDI_NI_TIO
- select COMEDI_8255
- help
- Enable support for the National Instruments PCMCIA DAQCard E series
- DAQCard-ai-16xe-50, DAQCard-ai-16e-4, DAQCard-6062E, DAQCard-6024E
- and DAQCard-6036E
-
- To compile this driver as a module, choose M here: the module will be
- called ni_mio_cs.
-
-config COMEDI_QUATECH_DAQP_CS
- tristate "Quatech DAQP PCMCIA data capture card support"
- help
- Enable support for the Quatech DAQP PCMCIA data capture cards
- DAQP-208 and DAQP-308
-
- To compile this driver as a module, choose M here: the module will be
- called quatech_daqp_cs.
-
-endif # COMEDI_PCMCIA_DRIVERS
-
-menuconfig COMEDI_USB_DRIVERS
- tristate "Comedi USB drivers"
- depends on USB
- help
- Enable support for comedi USB drivers.
-
- To compile this support as a module, choose M here: the module will
- be called comedi_usb.
-
-if COMEDI_USB_DRIVERS
-
-config COMEDI_DT9812
- tristate "DataTranslation DT9812 USB module support"
- help
- Enable support for the Data Translation DT9812 USB module
-
- To compile this driver as a module, choose M here: the module will be
- called dt9812.
-
-config COMEDI_NI_USB6501
- tristate "NI USB-6501 support"
- help
- Enable support for the National Instruments USB-6501 module.
-
- The NI USB-6501 is a Full-Speed USB 2.0 (12 Mbit/s) device that
- provides 24 digital I/O lines channels and one 32-bit counter.
-
- To compile this driver as a module, choose M here: the module will be
- called ni_usb6501.
-
-config COMEDI_USBDUX
- tristate "ITL USB-DUX-D support"
- help
- Enable support for the Incite Technology Ltd USB-DUX-D Board
-
- To compile this driver as a module, choose M here: the module will be
- called usbdux.
-
-config COMEDI_USBDUXFAST
- tristate "ITL USB-DUXfast support"
- help
- Enable support for the Incite Technology Ltd USB-DUXfast Board
-
- To compile this driver as a module, choose M here: the module will be
- called usbduxfast.
-
-config COMEDI_USBDUXSIGMA
- tristate "ITL USB-DUXsigma support"
- help
- Enable support for the Incite Technology Ltd USB-DUXsigma Board
-
- To compile this driver as a module, choose M here: the module will be
- called usbduxsigma.
-
-config COMEDI_VMK80XX
- tristate "Velleman VM110/VM140 USB Board support"
- help
- Build the Velleman USB Board Low-Level Driver supporting the
- K8055/K8061 aka VM110/VM140 devices
-
- To compile this driver as a module, choose M here: the module will be
- called vmk80xx.
-
-endif # COMEDI_USB_DRIVERS
-
-config COMEDI_8254
- tristate
-
-config COMEDI_8255
- tristate
-
-config COMEDI_8255_SA
- tristate "Standalone 8255 support"
- select COMEDI_8255
- help
- Enable support for 8255 digital I/O as a standalone driver.
-
- You should enable compilation this driver if you plan to use a board
- that has an 8255 chip at a known I/O base address and there are no
- other Comedi drivers for the board.
-
- Note that Comedi drivers for most multi-function boards incorporating
- an 8255 chip use the 'comedi_8255' module. Most PCI-based 8255
- boards use the 8255_pci driver as a wrapper around the 'comedi_8255'
- module.
-
- To compile this driver as a module, choose M here: the module will be
- called 8255.
-
-config COMEDI_KCOMEDILIB
- tristate "Comedi kcomedilib"
- help
- Build the kcomedilib.
-
- This is a kernel module used to open and manipulate Comedi devices
- from within kernel code. It is currently only used by the
- comedi_bond driver, and its functionality has been stripped down to
- the needs of that driver, so is currently not very useful for
- anything else.
-
- To compile kcomedilib as a module, choose M here: the module will be
- called kcomedilib.
-
-config COMEDI_AMPLC_DIO200
- select COMEDI_8254
- tristate
-
-config COMEDI_AMPLC_PC236
- tristate
- select COMEDI_8255
-
-config COMEDI_DAS08
- tristate
- select COMEDI_8254
- select COMEDI_8255
-
-config COMEDI_ISADMA
- tristate
-
-config COMEDI_NI_LABPC
- tristate
- select COMEDI_8254
- select COMEDI_8255
-
-config COMEDI_NI_LABPC_ISADMA
- tristate
- default COMEDI_NI_LABPC
- depends on COMEDI_NI_LABPC_ISA != n
- depends on ISA_DMA_API
- select COMEDI_ISADMA
-
-config COMEDI_NI_TIO
- tristate
- select COMEDI_NI_ROUTING
-
-config COMEDI_NI_ROUTING
- tristate
-
-config COMEDI_TESTS
- tristate "Comedi unit tests"
- help
- Enable comedi unit-test modules to be built.
-
- Note that the answer to this question won't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about comedi unit-test modules.
-
-if COMEDI_TESTS
-
-config COMEDI_TESTS_EXAMPLE
- tristate "Comedi example unit-test module"
- help
- Enable support for an example unit-test module. This is just a
- silly example to be used as a basis for writing other unit-test
- modules.
-
- To compile this as a module, choose M here: the module will be called
- comedi_example_test.
-
-config COMEDI_TESTS_NI_ROUTES
- tristate "NI routing unit-test module"
- select COMEDI_NI_ROUTING
- help
- Enable support for a unit-test module to test the signal routing
- code used by comedi drivers for various National Instruments cards.
-
- To compile this as a module, choose M here: the module will be called
- ni_routes_test.
-
-endif # COMEDI_TESTS
-
-endif # COMEDI
diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile
deleted file mode 100644
index 072ed83a5a6a..000000000000
--- a/drivers/staging/comedi/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG
-
-comedi-y := comedi_fops.o range.o drivers.o \
- comedi_buf.o
-comedi-$(CONFIG_PROC_FS) += proc.o
-
-obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o
-obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += comedi_pcmcia.o
-obj-$(CONFIG_COMEDI_USB_DRIVERS) += comedi_usb.o
-
-obj-$(CONFIG_COMEDI) += comedi.o
-
-obj-$(CONFIG_COMEDI) += kcomedilib/
-obj-$(CONFIG_COMEDI) += drivers/
diff --git a/drivers/staging/comedi/TODO b/drivers/staging/comedi/TODO
deleted file mode 100644
index f733c017f181..000000000000
--- a/drivers/staging/comedi/TODO
+++ /dev/null
@@ -1,12 +0,0 @@
-TODO:
- - checkpatch.pl cleanups
- - Lindent
- - remove all wrappers
- - audit userspace interface
- - Fix coverity 1195261
- - cleanup the individual comedi drivers as well
-
-Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
-copy:
- Ian Abbott <abbotti@mev.co.uk>
- H Hartley Sweeten <hsweeten@visionengravers.com>
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
deleted file mode 100644
index b5d00a006dbb..000000000000
--- a/drivers/staging/comedi/comedi.h
+++ /dev/null
@@ -1,1528 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.0+ */
-/*
- * comedi.h
- * header file for COMEDI user API
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _COMEDI_H
-#define _COMEDI_H
-
-#define COMEDI_MAJORVERSION 0
-#define COMEDI_MINORVERSION 7
-#define COMEDI_MICROVERSION 76
-#define VERSION "0.7.76"
-
-/* comedi's major device number */
-#define COMEDI_MAJOR 98
-
-/*
- * maximum number of minor devices. This can be increased, although
- * kernel structures are currently statically allocated, thus you
- * don't want this to be much more than you actually use.
- */
-#define COMEDI_NDEVICES 16
-
-/* number of config options in the config structure */
-#define COMEDI_NDEVCONFOPTS 32
-
-/*
- * NOTE: 'comedi_config --init-data' is deprecated
- *
- * The following indexes in the config options were used by
- * comedi_config to pass firmware blobs from user space to the
- * comedi drivers. The request_firmware() hotplug interface is
- * now used by all comedi drivers instead.
- */
-
-/* length of nth chunk of firmware data -*/
-#define COMEDI_DEVCONF_AUX_DATA3_LENGTH 25
-#define COMEDI_DEVCONF_AUX_DATA2_LENGTH 26
-#define COMEDI_DEVCONF_AUX_DATA1_LENGTH 27
-#define COMEDI_DEVCONF_AUX_DATA0_LENGTH 28
-/* most significant 32 bits of pointer address (if needed) */
-#define COMEDI_DEVCONF_AUX_DATA_HI 29
-/* least significant 32 bits of pointer address */
-#define COMEDI_DEVCONF_AUX_DATA_LO 30
-#define COMEDI_DEVCONF_AUX_DATA_LENGTH 31 /* total data length */
-
-/* max length of device and driver names */
-#define COMEDI_NAMELEN 20
-
-/* packs and unpacks a channel/range number */
-
-#define CR_PACK(chan, rng, aref) \
- ((((aref) & 0x3) << 24) | (((rng) & 0xff) << 16) | (chan))
-#define CR_PACK_FLAGS(chan, range, aref, flags) \
- (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK))
-
-#define CR_CHAN(a) ((a) & 0xffff)
-#define CR_RANGE(a) (((a) >> 16) & 0xff)
-#define CR_AREF(a) (((a) >> 24) & 0x03)
-
-#define CR_FLAGS_MASK 0xfc000000
-#define CR_ALT_FILTER 0x04000000
-#define CR_DITHER CR_ALT_FILTER
-#define CR_DEGLITCH CR_ALT_FILTER
-#define CR_ALT_SOURCE 0x08000000
-#define CR_EDGE 0x40000000
-#define CR_INVERT 0x80000000
-
-#define AREF_GROUND 0x00 /* analog ref = analog ground */
-#define AREF_COMMON 0x01 /* analog ref = analog common */
-#define AREF_DIFF 0x02 /* analog ref = differential */
-#define AREF_OTHER 0x03 /* analog ref = other (undefined) */
-
-/* counters -- these are arbitrary values */
-#define GPCT_RESET 0x0001
-#define GPCT_SET_SOURCE 0x0002
-#define GPCT_SET_GATE 0x0004
-#define GPCT_SET_DIRECTION 0x0008
-#define GPCT_SET_OPERATION 0x0010
-#define GPCT_ARM 0x0020
-#define GPCT_DISARM 0x0040
-#define GPCT_GET_INT_CLK_FRQ 0x0080
-
-#define GPCT_INT_CLOCK 0x0001
-#define GPCT_EXT_PIN 0x0002
-#define GPCT_NO_GATE 0x0004
-#define GPCT_UP 0x0008
-#define GPCT_DOWN 0x0010
-#define GPCT_HWUD 0x0020
-#define GPCT_SIMPLE_EVENT 0x0040
-#define GPCT_SINGLE_PERIOD 0x0080
-#define GPCT_SINGLE_PW 0x0100
-#define GPCT_CONT_PULSE_OUT 0x0200
-#define GPCT_SINGLE_PULSE_OUT 0x0400
-
-/* instructions */
-
-#define INSN_MASK_WRITE 0x8000000
-#define INSN_MASK_READ 0x4000000
-#define INSN_MASK_SPECIAL 0x2000000
-
-#define INSN_READ (0 | INSN_MASK_READ)
-#define INSN_WRITE (1 | INSN_MASK_WRITE)
-#define INSN_BITS (2 | INSN_MASK_READ | INSN_MASK_WRITE)
-#define INSN_CONFIG (3 | INSN_MASK_READ | INSN_MASK_WRITE)
-#define INSN_DEVICE_CONFIG (INSN_CONFIG | INSN_MASK_SPECIAL)
-#define INSN_GTOD (4 | INSN_MASK_READ | INSN_MASK_SPECIAL)
-#define INSN_WAIT (5 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
-#define INSN_INTTRIG (6 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
-
-/* command flags */
-/* These flags are used in comedi_cmd structures */
-
-#define CMDF_BOGUS 0x00000001 /* do the motions */
-
-/* try to use a real-time interrupt while performing command */
-#define CMDF_PRIORITY 0x00000008
-
-/* wake up on end-of-scan events */
-#define CMDF_WAKE_EOS 0x00000020
-
-#define CMDF_WRITE 0x00000040
-
-#define CMDF_RAWDATA 0x00000080
-
-/* timer rounding definitions */
-#define CMDF_ROUND_MASK 0x00030000
-#define CMDF_ROUND_NEAREST 0x00000000
-#define CMDF_ROUND_DOWN 0x00010000
-#define CMDF_ROUND_UP 0x00020000
-#define CMDF_ROUND_UP_NEXT 0x00030000
-
-#define COMEDI_EV_START 0x00040000
-#define COMEDI_EV_SCAN_BEGIN 0x00080000
-#define COMEDI_EV_CONVERT 0x00100000
-#define COMEDI_EV_SCAN_END 0x00200000
-#define COMEDI_EV_STOP 0x00400000
-
-/* compatibility definitions */
-#define TRIG_BOGUS CMDF_BOGUS
-#define TRIG_RT CMDF_PRIORITY
-#define TRIG_WAKE_EOS CMDF_WAKE_EOS
-#define TRIG_WRITE CMDF_WRITE
-#define TRIG_ROUND_MASK CMDF_ROUND_MASK
-#define TRIG_ROUND_NEAREST CMDF_ROUND_NEAREST
-#define TRIG_ROUND_DOWN CMDF_ROUND_DOWN
-#define TRIG_ROUND_UP CMDF_ROUND_UP
-#define TRIG_ROUND_UP_NEXT CMDF_ROUND_UP_NEXT
-
-/* trigger sources */
-
-#define TRIG_ANY 0xffffffff
-#define TRIG_INVALID 0x00000000
-
-#define TRIG_NONE 0x00000001 /* never trigger */
-#define TRIG_NOW 0x00000002 /* trigger now + N ns */
-#define TRIG_FOLLOW 0x00000004 /* trigger on next lower level trig */
-#define TRIG_TIME 0x00000008 /* trigger at time N ns */
-#define TRIG_TIMER 0x00000010 /* trigger at rate N ns */
-#define TRIG_COUNT 0x00000020 /* trigger when count reaches N */
-#define TRIG_EXT 0x00000040 /* trigger on external signal N */
-#define TRIG_INT 0x00000080 /* trigger on comedi-internal signal N */
-#define TRIG_OTHER 0x00000100 /* driver defined */
-
-/* subdevice flags */
-
-#define SDF_BUSY 0x0001 /* device is busy */
-#define SDF_BUSY_OWNER 0x0002 /* device is busy with your job */
-#define SDF_LOCKED 0x0004 /* subdevice is locked */
-#define SDF_LOCK_OWNER 0x0008 /* you own lock */
-#define SDF_MAXDATA 0x0010 /* maxdata depends on channel */
-#define SDF_FLAGS 0x0020 /* flags depend on channel */
-#define SDF_RANGETYPE 0x0040 /* range type depends on channel */
-#define SDF_PWM_COUNTER 0x0080 /* PWM can automatically switch off */
-#define SDF_PWM_HBRIDGE 0x0100 /* PWM is signed (H-bridge) */
-#define SDF_CMD 0x1000 /* can do commands (deprecated) */
-#define SDF_SOFT_CALIBRATED 0x2000 /* subdevice uses software calibration */
-#define SDF_CMD_WRITE 0x4000 /* can do output commands */
-#define SDF_CMD_READ 0x8000 /* can do input commands */
-
-/* subdevice can be read (e.g. analog input) */
-#define SDF_READABLE 0x00010000
-/* subdevice can be written (e.g. analog output) */
-#define SDF_WRITABLE 0x00020000
-#define SDF_WRITEABLE SDF_WRITABLE /* spelling error in API */
-/* subdevice does not have externally visible lines */
-#define SDF_INTERNAL 0x00040000
-#define SDF_GROUND 0x00100000 /* can do aref=ground */
-#define SDF_COMMON 0x00200000 /* can do aref=common */
-#define SDF_DIFF 0x00400000 /* can do aref=diff */
-#define SDF_OTHER 0x00800000 /* can do aref=other */
-#define SDF_DITHER 0x01000000 /* can do dithering */
-#define SDF_DEGLITCH 0x02000000 /* can do deglitching */
-#define SDF_MMAP 0x04000000 /* can do mmap() */
-#define SDF_RUNNING 0x08000000 /* subdevice is acquiring data */
-#define SDF_LSAMPL 0x10000000 /* subdevice uses 32-bit samples */
-#define SDF_PACKED 0x20000000 /* subdevice can do packed DIO */
-
-/* subdevice types */
-
-/**
- * enum comedi_subdevice_type - COMEDI subdevice types
- * @COMEDI_SUBD_UNUSED: Unused subdevice.
- * @COMEDI_SUBD_AI: Analog input.
- * @COMEDI_SUBD_AO: Analog output.
- * @COMEDI_SUBD_DI: Digital input.
- * @COMEDI_SUBD_DO: Digital output.
- * @COMEDI_SUBD_DIO: Digital input/output.
- * @COMEDI_SUBD_COUNTER: Counter.
- * @COMEDI_SUBD_TIMER: Timer.
- * @COMEDI_SUBD_MEMORY: Memory, EEPROM, DPRAM.
- * @COMEDI_SUBD_CALIB: Calibration DACs.
- * @COMEDI_SUBD_PROC: Processor, DSP.
- * @COMEDI_SUBD_SERIAL: Serial I/O.
- * @COMEDI_SUBD_PWM: Pulse-Width Modulation output.
- */
-enum comedi_subdevice_type {
- COMEDI_SUBD_UNUSED,
- COMEDI_SUBD_AI,
- COMEDI_SUBD_AO,
- COMEDI_SUBD_DI,
- COMEDI_SUBD_DO,
- COMEDI_SUBD_DIO,
- COMEDI_SUBD_COUNTER,
- COMEDI_SUBD_TIMER,
- COMEDI_SUBD_MEMORY,
- COMEDI_SUBD_CALIB,
- COMEDI_SUBD_PROC,
- COMEDI_SUBD_SERIAL,
- COMEDI_SUBD_PWM
-};
-
-/* configuration instructions */
-
-/**
- * enum comedi_io_direction - COMEDI I/O directions
- * @COMEDI_INPUT: Input.
- * @COMEDI_OUTPUT: Output.
- * @COMEDI_OPENDRAIN: Open-drain (or open-collector) output.
- *
- * These are used by the %INSN_CONFIG_DIO_QUERY configuration instruction to
- * report a direction. They may also be used in other places where a direction
- * needs to be specified.
- */
-enum comedi_io_direction {
- COMEDI_INPUT = 0,
- COMEDI_OUTPUT = 1,
- COMEDI_OPENDRAIN = 2
-};
-
-/**
- * enum configuration_ids - COMEDI configuration instruction codes
- * @INSN_CONFIG_DIO_INPUT: Configure digital I/O as input.
- * @INSN_CONFIG_DIO_OUTPUT: Configure digital I/O as output.
- * @INSN_CONFIG_DIO_OPENDRAIN: Configure digital I/O as open-drain (or open
- * collector) output.
- * @INSN_CONFIG_ANALOG_TRIG: Configure analog trigger.
- * @INSN_CONFIG_ALT_SOURCE: Configure alternate input source.
- * @INSN_CONFIG_DIGITAL_TRIG: Configure digital trigger.
- * @INSN_CONFIG_BLOCK_SIZE: Configure block size for DMA transfers.
- * @INSN_CONFIG_TIMER_1: Configure divisor for external clock.
- * @INSN_CONFIG_FILTER: Configure a filter.
- * @INSN_CONFIG_CHANGE_NOTIFY: Configure change notification for digital
- * inputs. (New drivers should use
- * %INSN_CONFIG_DIGITAL_TRIG instead.)
- * @INSN_CONFIG_SERIAL_CLOCK: Configure clock for serial I/O.
- * @INSN_CONFIG_BIDIRECTIONAL_DATA: Send and receive byte over serial I/O.
- * @INSN_CONFIG_DIO_QUERY: Query direction of digital I/O channel.
- * @INSN_CONFIG_PWM_OUTPUT: Configure pulse-width modulator output.
- * @INSN_CONFIG_GET_PWM_OUTPUT: Get pulse-width modulator output configuration.
- * @INSN_CONFIG_ARM: Arm a subdevice or channel.
- * @INSN_CONFIG_DISARM: Disarm a subdevice or channel.
- * @INSN_CONFIG_GET_COUNTER_STATUS: Get counter status.
- * @INSN_CONFIG_RESET: Reset a subdevice or channel.
- * @INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR: Configure counter/timer as
- * single pulse generator.
- * @INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR: Configure counter/timer as
- * pulse train generator.
- * @INSN_CONFIG_GPCT_QUADRATURE_ENCODER: Configure counter as a quadrature
- * encoder.
- * @INSN_CONFIG_SET_GATE_SRC: Set counter/timer gate source.
- * @INSN_CONFIG_GET_GATE_SRC: Get counter/timer gate source.
- * @INSN_CONFIG_SET_CLOCK_SRC: Set counter/timer master clock source.
- * @INSN_CONFIG_GET_CLOCK_SRC: Get counter/timer master clock source.
- * @INSN_CONFIG_SET_OTHER_SRC: Set counter/timer "other" source.
- * @INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE: Get size (in bytes) of subdevice's
- * on-board FIFOs used during streaming
- * input/output.
- * @INSN_CONFIG_SET_COUNTER_MODE: Set counter/timer mode.
- * @INSN_CONFIG_8254_SET_MODE: (Deprecated) Same as
- * %INSN_CONFIG_SET_COUNTER_MODE.
- * @INSN_CONFIG_8254_READ_STATUS: Read status of 8254 counter channel.
- * @INSN_CONFIG_SET_ROUTING: Set routing for a channel.
- * @INSN_CONFIG_GET_ROUTING: Get routing for a channel.
- * @INSN_CONFIG_PWM_SET_PERIOD: Set PWM period in nanoseconds.
- * @INSN_CONFIG_PWM_GET_PERIOD: Get PWM period in nanoseconds.
- * @INSN_CONFIG_GET_PWM_STATUS: Get PWM status.
- * @INSN_CONFIG_PWM_SET_H_BRIDGE: Set PWM H bridge duty cycle and polarity for
- * a relay simultaneously.
- * @INSN_CONFIG_PWM_GET_H_BRIDGE: Get PWM H bridge duty cycle and polarity.
- * @INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS: Get the hardware timing restraints,
- * regardless of trigger sources.
- */
-enum configuration_ids {
- INSN_CONFIG_DIO_INPUT = COMEDI_INPUT,
- INSN_CONFIG_DIO_OUTPUT = COMEDI_OUTPUT,
- INSN_CONFIG_DIO_OPENDRAIN = COMEDI_OPENDRAIN,
- INSN_CONFIG_ANALOG_TRIG = 16,
-/* INSN_CONFIG_WAVEFORM = 17, */
-/* INSN_CONFIG_TRIG = 18, */
-/* INSN_CONFIG_COUNTER = 19, */
- INSN_CONFIG_ALT_SOURCE = 20,
- INSN_CONFIG_DIGITAL_TRIG = 21,
- INSN_CONFIG_BLOCK_SIZE = 22,
- INSN_CONFIG_TIMER_1 = 23,
- INSN_CONFIG_FILTER = 24,
- INSN_CONFIG_CHANGE_NOTIFY = 25,
-
- INSN_CONFIG_SERIAL_CLOCK = 26, /*ALPHA*/
- INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
- INSN_CONFIG_DIO_QUERY = 28,
- INSN_CONFIG_PWM_OUTPUT = 29,
- INSN_CONFIG_GET_PWM_OUTPUT = 30,
- INSN_CONFIG_ARM = 31,
- INSN_CONFIG_DISARM = 32,
- INSN_CONFIG_GET_COUNTER_STATUS = 33,
- INSN_CONFIG_RESET = 34,
- INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,
- INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,
- INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,
- INSN_CONFIG_SET_GATE_SRC = 2001,
- INSN_CONFIG_GET_GATE_SRC = 2002,
- INSN_CONFIG_SET_CLOCK_SRC = 2003,
- INSN_CONFIG_GET_CLOCK_SRC = 2004,
- INSN_CONFIG_SET_OTHER_SRC = 2005,
- INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,
- INSN_CONFIG_SET_COUNTER_MODE = 4097,
- INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,
- INSN_CONFIG_8254_READ_STATUS = 4098,
- INSN_CONFIG_SET_ROUTING = 4099,
- INSN_CONFIG_GET_ROUTING = 4109,
- INSN_CONFIG_PWM_SET_PERIOD = 5000,
- INSN_CONFIG_PWM_GET_PERIOD = 5001,
- INSN_CONFIG_GET_PWM_STATUS = 5002,
- INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,
- INSN_CONFIG_PWM_GET_H_BRIDGE = 5004,
- INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS = 5005,
-};
-
-/**
- * enum device_configuration_ids - COMEDI configuration instruction codes global
- * to an entire device.
- * @INSN_DEVICE_CONFIG_TEST_ROUTE: Validate the possibility of a
- * globally-named route
- * @INSN_DEVICE_CONFIG_CONNECT_ROUTE: Connect a globally-named route
- * @INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:Disconnect a globally-named route
- * @INSN_DEVICE_CONFIG_GET_ROUTES: Get a list of all globally-named routes
- * that are valid for a particular device.
- */
-enum device_config_route_ids {
- INSN_DEVICE_CONFIG_TEST_ROUTE = 0,
- INSN_DEVICE_CONFIG_CONNECT_ROUTE = 1,
- INSN_DEVICE_CONFIG_DISCONNECT_ROUTE = 2,
- INSN_DEVICE_CONFIG_GET_ROUTES = 3,
-};
-
-/**
- * enum comedi_digital_trig_op - operations for configuring a digital trigger
- * @COMEDI_DIGITAL_TRIG_DISABLE: Return digital trigger to its default,
- * inactive, unconfigured state.
- * @COMEDI_DIGITAL_TRIG_ENABLE_EDGES: Set rising and/or falling edge inputs
- * that each can fire the trigger.
- * @COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: Set a combination of high and/or low
- * level inputs that can fire the trigger.
- *
- * These are used with the %INSN_CONFIG_DIGITAL_TRIG configuration instruction.
- * The data for the configuration instruction is as follows...
- *
- * data[%0] = %INSN_CONFIG_DIGITAL_TRIG
- *
- * data[%1] = trigger ID
- *
- * data[%2] = configuration operation
- *
- * data[%3] = configuration parameter 1
- *
- * data[%4] = configuration parameter 2
- *
- * data[%5] = configuration parameter 3
- *
- * The trigger ID (data[%1]) is used to differentiate multiple digital triggers
- * belonging to the same subdevice. The configuration operation (data[%2]) is
- * one of the enum comedi_digital_trig_op values. The configuration
- * parameters (data[%3], data[%4], and data[%5]) depend on the operation; they
- * are not used with %COMEDI_DIGITAL_TRIG_DISABLE.
- *
- * For %COMEDI_DIGITAL_TRIG_ENABLE_EDGES and %COMEDI_DIGITAL_TRIG_ENABLE_LEVELS,
- * configuration parameter 1 (data[%3]) contains a "left-shift" value that
- * specifies the input corresponding to bit 0 of configuration parameters 2
- * and 3. This is useful if the trigger has more than 32 inputs.
- *
- * For %COMEDI_DIGITAL_TRIG_ENABLE_EDGES, configuration parameter 2 (data[%4])
- * specifies which of up to 32 inputs have rising-edge sensitivity, and
- * configuration parameter 3 (data[%5]) specifies which of up to 32 inputs
- * have falling-edge sensitivity that can fire the trigger.
- *
- * For %COMEDI_DIGITAL_TRIG_ENABLE_LEVELS, configuration parameter 2 (data[%4])
- * specifies which of up to 32 inputs must be at a high level, and
- * configuration parameter 3 (data[%5]) specifies which of up to 32 inputs
- * must be at a low level for the trigger to fire.
- *
- * Some sequences of %INSN_CONFIG_DIGITAL_TRIG instructions may have a (partly)
- * accumulative effect, depending on the low-level driver. This is useful
- * when setting up a trigger that has more than 32 inputs, or has a combination
- * of edge- and level-triggered inputs.
- */
-enum comedi_digital_trig_op {
- COMEDI_DIGITAL_TRIG_DISABLE = 0,
- COMEDI_DIGITAL_TRIG_ENABLE_EDGES = 1,
- COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = 2
-};
-
-/**
- * enum comedi_support_level - support level for a COMEDI feature
- * @COMEDI_UNKNOWN_SUPPORT: Unspecified support for feature.
- * @COMEDI_SUPPORTED: Feature is supported.
- * @COMEDI_UNSUPPORTED: Feature is unsupported.
- */
-enum comedi_support_level {
- COMEDI_UNKNOWN_SUPPORT = 0,
- COMEDI_SUPPORTED,
- COMEDI_UNSUPPORTED
-};
-
-/**
- * enum comedi_counter_status_flags - counter status bits
- * @COMEDI_COUNTER_ARMED: Counter is armed.
- * @COMEDI_COUNTER_COUNTING: Counter is counting.
- * @COMEDI_COUNTER_TERMINAL_COUNT: Counter reached terminal count.
- *
- * These bitwise values are used by the %INSN_CONFIG_GET_COUNTER_STATUS
- * configuration instruction to report the status of a counter.
- */
-enum comedi_counter_status_flags {
- COMEDI_COUNTER_ARMED = 0x1,
- COMEDI_COUNTER_COUNTING = 0x2,
- COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
-};
-
-/* ioctls */
-
-#define CIO 'd'
-#define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig)
-#define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo)
-#define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo)
-#define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo)
-/* _IOWR(CIO, 4, ...) is reserved */
-#define COMEDI_LOCK _IO(CIO, 5)
-#define COMEDI_UNLOCK _IO(CIO, 6)
-#define COMEDI_CANCEL _IO(CIO, 7)
-#define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo)
-#define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd)
-#define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd)
-#define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist)
-#define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn)
-#define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
-#define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
-#define COMEDI_POLL _IO(CIO, 15)
-#define COMEDI_SETRSUBD _IO(CIO, 16)
-#define COMEDI_SETWSUBD _IO(CIO, 17)
-
-/* structures */
-
-/**
- * struct comedi_insn - COMEDI instruction
- * @insn: COMEDI instruction type (%INSN_xxx).
- * @n: Length of @data[].
- * @data: Pointer to data array operated on by the instruction.
- * @subdev: Subdevice index.
- * @chanspec: A packed "chanspec" value consisting of channel number,
- * analog range index, analog reference type, and flags.
- * @unused: Reserved for future use.
- *
- * This is used with the %COMEDI_INSN ioctl, and indirectly with the
- * %COMEDI_INSNLIST ioctl.
- */
-struct comedi_insn {
- unsigned int insn;
- unsigned int n;
- unsigned int __user *data;
- unsigned int subdev;
- unsigned int chanspec;
- unsigned int unused[3];
-};
-
-/**
- * struct comedi_insnlist - list of COMEDI instructions
- * @n_insns: Number of COMEDI instructions.
- * @insns: Pointer to array COMEDI instructions.
- *
- * This is used with the %COMEDI_INSNLIST ioctl.
- */
-struct comedi_insnlist {
- unsigned int n_insns;
- struct comedi_insn __user *insns;
-};
-
-/**
- * struct comedi_cmd - COMEDI asynchronous acquisition command details
- * @subdev: Subdevice index.
- * @flags: Command flags (%CMDF_xxx).
- * @start_src: "Start acquisition" trigger source (%TRIG_xxx).
- * @start_arg: "Start acquisition" trigger argument.
- * @scan_begin_src: "Scan begin" trigger source.
- * @scan_begin_arg: "Scan begin" trigger argument.
- * @convert_src: "Convert" trigger source.
- * @convert_arg: "Convert" trigger argument.
- * @scan_end_src: "Scan end" trigger source.
- * @scan_end_arg: "Scan end" trigger argument.
- * @stop_src: "Stop acquisition" trigger source.
- * @stop_arg: "Stop acquisition" trigger argument.
- * @chanlist: Pointer to array of "chanspec" values, containing a
- * sequence of channel numbers packed with analog range
- * index, etc.
- * @chanlist_len: Number of channels in sequence.
- * @data: Pointer to miscellaneous set-up data (not used).
- * @data_len: Length of miscellaneous set-up data.
- *
- * This is used with the %COMEDI_CMD or %COMEDI_CMDTEST ioctl to set-up
- * or validate an asynchronous acquisition command. The ioctl may modify
- * the &struct comedi_cmd and copy it back to the caller.
- *
- * Optional command @flags values that can be ORed together...
- *
- * %CMDF_BOGUS - makes %COMEDI_CMD ioctl return error %EAGAIN instead of
- * starting the command.
- *
- * %CMDF_PRIORITY - requests "hard real-time" processing (which is not
- * supported in this version of COMEDI).
- *
- * %CMDF_WAKE_EOS - requests the command makes data available for reading
- * after every "scan" period.
- *
- * %CMDF_WRITE - marks the command as being in the "write" (to device)
- * direction. This does not need to be specified by the caller unless the
- * subdevice supports commands in either direction.
- *
- * %CMDF_RAWDATA - prevents the command from "munging" the data between the
- * COMEDI sample format and the raw hardware sample format.
- *
- * %CMDF_ROUND_NEAREST - requests timing periods to be rounded to nearest
- * supported values.
- *
- * %CMDF_ROUND_DOWN - requests timing periods to be rounded down to supported
- * values (frequencies rounded up).
- *
- * %CMDF_ROUND_UP - requests timing periods to be rounded up to supported
- * values (frequencies rounded down).
- *
- * Trigger source values for @start_src, @scan_begin_src, @convert_src,
- * @scan_end_src, and @stop_src...
- *
- * %TRIG_ANY - "all ones" value used to test which trigger sources are
- * supported.
- *
- * %TRIG_INVALID - "all zeroes" value used to indicate that all requested
- * trigger sources are invalid.
- *
- * %TRIG_NONE - never trigger (often used as a @stop_src value).
- *
- * %TRIG_NOW - trigger after '_arg' nanoseconds.
- *
- * %TRIG_FOLLOW - trigger follows another event.
- *
- * %TRIG_TIMER - trigger every '_arg' nanoseconds.
- *
- * %TRIG_COUNT - trigger when count '_arg' is reached.
- *
- * %TRIG_EXT - trigger on external signal specified by '_arg'.
- *
- * %TRIG_INT - trigger on internal, software trigger specified by '_arg'.
- *
- * %TRIG_OTHER - trigger on other, driver-defined signal specified by '_arg'.
- */
-struct comedi_cmd {
- unsigned int subdev;
- unsigned int flags;
-
- unsigned int start_src;
- unsigned int start_arg;
-
- unsigned int scan_begin_src;
- unsigned int scan_begin_arg;
-
- unsigned int convert_src;
- unsigned int convert_arg;
-
- unsigned int scan_end_src;
- unsigned int scan_end_arg;
-
- unsigned int stop_src;
- unsigned int stop_arg;
-
- unsigned int *chanlist;
- unsigned int chanlist_len;
-
- short __user *data;
- unsigned int data_len;
-};
-
-/**
- * struct comedi_chaninfo - used to retrieve per-channel information
- * @subdev: Subdevice index.
- * @maxdata_list: Optional pointer to per-channel maximum data values.
- * @flaglist: Optional pointer to per-channel flags.
- * @rangelist: Optional pointer to per-channel range types.
- * @unused: Reserved for future use.
- *
- * This is used with the %COMEDI_CHANINFO ioctl to get per-channel information
- * for the subdevice. Use of this requires knowledge of the number of channels
- * and subdevice flags obtained using the %COMEDI_SUBDINFO ioctl.
- *
- * The @maxdata_list member must be %NULL unless the %SDF_MAXDATA subdevice
- * flag is set. The @flaglist member must be %NULL unless the %SDF_FLAGS
- * subdevice flag is set. The @rangelist member must be %NULL unless the
- * %SDF_RANGETYPE subdevice flag is set. Otherwise, the arrays they point to
- * must be at least as long as the number of channels.
- */
-struct comedi_chaninfo {
- unsigned int subdev;
- unsigned int __user *maxdata_list;
- unsigned int __user *flaglist;
- unsigned int __user *rangelist;
- unsigned int unused[4];
-};
-
-/**
- * struct comedi_rangeinfo - used to retrieve the range table for a channel
- * @range_type: Encodes subdevice index (bits 27:24), channel index
- * (bits 23:16) and range table length (bits 15:0).
- * @range_ptr: Pointer to array of @struct comedi_krange to be filled
- * in with the range table for the channel or subdevice.
- *
- * This is used with the %COMEDI_RANGEINFO ioctl to retrieve the range table
- * for a specific channel (if the subdevice has the %SDF_RANGETYPE flag set to
- * indicate that the range table depends on the channel), or for the subdevice
- * as a whole (if the %SDF_RANGETYPE flag is clear, indicating the range table
- * is shared by all channels).
- *
- * The @range_type value is an input to the ioctl and comes from a previous
- * use of the %COMEDI_SUBDINFO ioctl (if the %SDF_RANGETYPE flag is clear),
- * or the %COMEDI_CHANINFO ioctl (if the %SDF_RANGETYPE flag is set).
- */
-struct comedi_rangeinfo {
- unsigned int range_type;
- void __user *range_ptr;
-};
-
-/**
- * struct comedi_krange - describes a range in a range table
- * @min: Minimum value in millionths (1e-6) of a unit.
- * @max: Maximum value in millionths (1e-6) of a unit.
- * @flags: Indicates the units (in bits 7:0) OR'ed with optional flags.
- *
- * A range table is associated with a single channel, or with all channels in a
- * subdevice, and a list of one or more ranges. A %struct comedi_krange
- * describes the physical range of units for one of those ranges. Sample
- * values in COMEDI are unsigned from %0 up to some 'maxdata' value. The
- * mapping from sample values to physical units is assumed to be nomimally
- * linear (for the purpose of describing the range), with sample value %0
- * mapping to @min, and the 'maxdata' sample value mapping to @max.
- *
- * The currently defined units are %UNIT_volt (%0), %UNIT_mA (%1), and
- * %UNIT_none (%2). The @min and @max values are the physical range multiplied
- * by 1e6, so a @max value of %1000000 (with %UNIT_volt) represents a maximal
- * value of 1 volt.
- *
- * The only defined flag value is %RF_EXTERNAL (%0x100), indicating that the
- * range needs to be multiplied by an external reference.
- */
-struct comedi_krange {
- int min;
- int max;
- unsigned int flags;
-};
-
-/**
- * struct comedi_subdinfo - used to retrieve information about a subdevice
- * @type: Type of subdevice from &enum comedi_subdevice_type.
- * @n_chan: Number of channels the subdevice supports.
- * @subd_flags: A mixture of static and dynamic flags describing
- * aspects of the subdevice and its current state.
- * @timer_type: Timer type. Always set to %5 ("nanosecond timer").
- * @len_chanlist: Maximum length of a channel list if the subdevice
- * supports asynchronous acquisition commands.
- * @maxdata: Maximum sample value for all channels if the
- * %SDF_MAXDATA subdevice flag is clear.
- * @flags: Channel flags for all channels if the %SDF_FLAGS
- * subdevice flag is clear.
- * @range_type: The range type for all channels if the %SDF_RANGETYPE
- * subdevice flag is clear. Encodes the subdevice index
- * (bits 27:24), a dummy channel index %0 (bits 23:16),
- * and the range table length (bits 15:0).
- * @settling_time_0: Not used.
- * @insn_bits_support: Set to %COMEDI_SUPPORTED if the subdevice supports the
- * %INSN_BITS instruction, or to %COMEDI_UNSUPPORTED if it
- * does not.
- * @unused: Reserved for future use.
- *
- * This is used with the %COMEDI_SUBDINFO ioctl which copies an array of
- * &struct comedi_subdinfo back to user space, with one element per subdevice.
- * Use of this requires knowledge of the number of subdevices obtained from
- * the %COMEDI_DEVINFO ioctl.
- *
- * These are the @subd_flags values that may be ORed together...
- *
- * %SDF_BUSY - the subdevice is busy processing an asynchronous command or a
- * synchronous instruction.
- *
- * %SDF_BUSY_OWNER - the subdevice is busy processing an asynchronous
- * acquisition command started on the current file object (the file object
- * issuing the %COMEDI_SUBDINFO ioctl).
- *
- * %SDF_LOCKED - the subdevice is locked by a %COMEDI_LOCK ioctl.
- *
- * %SDF_LOCK_OWNER - the subdevice is locked by a %COMEDI_LOCK ioctl from the
- * current file object.
- *
- * %SDF_MAXDATA - maximum sample values are channel-specific.
- *
- * %SDF_FLAGS - channel flags are channel-specific.
- *
- * %SDF_RANGETYPE - range types are channel-specific.
- *
- * %SDF_PWM_COUNTER - PWM can switch off automatically.
- *
- * %SDF_PWM_HBRIDGE - or PWM is signed (H-bridge).
- *
- * %SDF_CMD - the subdevice supports asynchronous commands.
- *
- * %SDF_SOFT_CALIBRATED - the subdevice uses software calibration.
- *
- * %SDF_CMD_WRITE - the subdevice supports asynchronous commands in the output
- * ("write") direction.
- *
- * %SDF_CMD_READ - the subdevice supports asynchronous commands in the input
- * ("read") direction.
- *
- * %SDF_READABLE - the subdevice is readable (e.g. analog input).
- *
- * %SDF_WRITABLE (aliased as %SDF_WRITEABLE) - the subdevice is writable (e.g.
- * analog output).
- *
- * %SDF_INTERNAL - the subdevice has no externally visible lines.
- *
- * %SDF_GROUND - the subdevice can use ground as an analog reference.
- *
- * %SDF_COMMON - the subdevice can use a common analog reference.
- *
- * %SDF_DIFF - the subdevice can use differential inputs (or outputs).
- *
- * %SDF_OTHER - the subdevice can use some other analog reference.
- *
- * %SDF_DITHER - the subdevice can do dithering.
- *
- * %SDF_DEGLITCH - the subdevice can do deglitching.
- *
- * %SDF_MMAP - this is never set.
- *
- * %SDF_RUNNING - an asynchronous command is still running.
- *
- * %SDF_LSAMPL - the subdevice uses "long" (32-bit) samples (for asynchronous
- * command data).
- *
- * %SDF_PACKED - the subdevice packs several DIO samples into a single sample
- * (for asynchronous command data).
- *
- * No "channel flags" (@flags) values are currently defined.
- */
-struct comedi_subdinfo {
- unsigned int type;
- unsigned int n_chan;
- unsigned int subd_flags;
- unsigned int timer_type;
- unsigned int len_chanlist;
- unsigned int maxdata;
- unsigned int flags;
- unsigned int range_type;
- unsigned int settling_time_0;
- unsigned int insn_bits_support;
- unsigned int unused[8];
-};
-
-/**
- * struct comedi_devinfo - used to retrieve information about a COMEDI device
- * @version_code: COMEDI version code.
- * @n_subdevs: Number of subdevices the device has.
- * @driver_name: Null-terminated COMEDI driver name.
- * @board_name: Null-terminated COMEDI board name.
- * @read_subdevice: Index of the current "read" subdevice (%-1 if none).
- * @write_subdevice: Index of the current "write" subdevice (%-1 if none).
- * @unused: Reserved for future use.
- *
- * This is used with the %COMEDI_DEVINFO ioctl to get basic information about
- * the device.
- */
-struct comedi_devinfo {
- unsigned int version_code;
- unsigned int n_subdevs;
- char driver_name[COMEDI_NAMELEN];
- char board_name[COMEDI_NAMELEN];
- int read_subdevice;
- int write_subdevice;
- int unused[30];
-};
-
-/**
- * struct comedi_devconfig - used to configure a legacy COMEDI device
- * @board_name: Null-terminated string specifying the type of board
- * to configure.
- * @options: An array of integer configuration options.
- *
- * This is used with the %COMEDI_DEVCONFIG ioctl to configure a "legacy" COMEDI
- * device, such as an ISA card. Not all COMEDI drivers support this. Those
- * that do either expect the specified board name to match one of a list of
- * names registered with the COMEDI core, or expect the specified board name
- * to match the COMEDI driver name itself. The configuration options are
- * handled in a driver-specific manner.
- */
-struct comedi_devconfig {
- char board_name[COMEDI_NAMELEN];
- int options[COMEDI_NDEVCONFOPTS];
-};
-
-/**
- * struct comedi_bufconfig - used to set or get buffer size for a subdevice
- * @subdevice: Subdevice index.
- * @flags: Not used.
- * @maximum_size: Maximum allowed buffer size.
- * @size: Buffer size.
- * @unused: Reserved for future use.
- *
- * This is used with the %COMEDI_BUFCONFIG ioctl to get or configure the
- * maximum buffer size and current buffer size for a COMEDI subdevice that
- * supports asynchronous commands. If the subdevice does not support
- * asynchronous commands, @maximum_size and @size are ignored and set to 0.
- *
- * On ioctl input, non-zero values of @maximum_size and @size specify a
- * new maximum size and new current size (in bytes), respectively. These
- * will by rounded up to a multiple of %PAGE_SIZE. Specifying a new maximum
- * size requires admin capabilities.
- *
- * On ioctl output, @maximum_size and @size and set to the current maximum
- * buffer size and current buffer size, respectively.
- */
-struct comedi_bufconfig {
- unsigned int subdevice;
- unsigned int flags;
-
- unsigned int maximum_size;
- unsigned int size;
-
- unsigned int unused[4];
-};
-
-/**
- * struct comedi_bufinfo - used to manipulate buffer position for a subdevice
- * @subdevice: Subdevice index.
- * @bytes_read: Specify amount to advance read position for an
- * asynchronous command in the input ("read") direction.
- * @buf_write_ptr: Current write position (index) within the buffer.
- * @buf_read_ptr: Current read position (index) within the buffer.
- * @buf_write_count: Total amount written, modulo 2^32.
- * @buf_read_count: Total amount read, modulo 2^32.
- * @bytes_written: Specify amount to advance write position for an
- * asynchronous command in the output ("write") direction.
- * @unused: Reserved for future use.
- *
- * This is used with the %COMEDI_BUFINFO ioctl to optionally advance the
- * current read or write position in an asynchronous acquisition data buffer,
- * and to get the current read and write positions in the buffer.
- */
-struct comedi_bufinfo {
- unsigned int subdevice;
- unsigned int bytes_read;
-
- unsigned int buf_write_ptr;
- unsigned int buf_read_ptr;
- unsigned int buf_write_count;
- unsigned int buf_read_count;
-
- unsigned int bytes_written;
-
- unsigned int unused[4];
-};
-
-/* range stuff */
-
-#define __RANGE(a, b) ((((a) & 0xffff) << 16) | ((b) & 0xffff))
-
-#define RANGE_OFFSET(a) (((a) >> 16) & 0xffff)
-#define RANGE_LENGTH(b) ((b) & 0xffff)
-
-#define RF_UNIT(flags) ((flags) & 0xff)
-#define RF_EXTERNAL 0x100
-
-#define UNIT_volt 0
-#define UNIT_mA 1
-#define UNIT_none 2
-
-#define COMEDI_MIN_SPEED 0xffffffffu
-
-/**********************************************************/
-/* everything after this line is ALPHA */
-/**********************************************************/
-
-/*
- * 8254 specific configuration.
- *
- * It supports two config commands:
- *
- * 0 ID: INSN_CONFIG_SET_COUNTER_MODE
- * 1 8254 Mode
- * I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
- * OR'ed with:
- * I8254_BCD, I8254_BINARY
- *
- * 0 ID: INSN_CONFIG_8254_READ_STATUS
- * 1 <-- Status byte returned here.
- * B7 = Output
- * B6 = NULL Count
- * B5 - B0 Current mode.
- */
-
-enum i8254_mode {
- I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */
- I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */
- I8254_MODE2 = (2 << 1), /* Rate generator */
- I8254_MODE3 = (3 << 1), /* Square wave mode */
- I8254_MODE4 = (4 << 1), /* Software triggered strobe */
- /* Hardware triggered strobe (retriggerable) */
- I8254_MODE5 = (5 << 1),
- /* Use binary-coded decimal instead of binary (pretty useless) */
- I8254_BCD = 1,
- I8254_BINARY = 0
-};
-
-/* *** BEGIN GLOBALLY-NAMED NI TERMINALS/SIGNALS *** */
-
-/*
- * Common National Instruments Terminal/Signal names.
- * Some of these have no NI_ prefix as they are useful for non-NI hardware, such
- * as those that utilize the PXI/RTSI trigger lines.
- *
- * NOTE ABOUT THE CHOICE OF NAMES HERE AND THE CAMELSCRIPT:
- * The choice to use CamelScript and the exact names below is for
- * maintainability, clarity, similarity to manufacturer's documentation,
- * _and_ a mitigation for confusion that has plagued the use of these drivers
- * for years!
- *
- * More detail:
- * There have been significant confusions over the past many years for users
- * when trying to understand how to connect to/from signals and terminals on
- * NI hardware using comedi. The major reason for this is that the actual
- * register values were exposed and required to be used by users. Several
- * major reasons exist why this caused major confusion for users:
- * 1) The register values are _NOT_ in user documentation, but rather in
- * arcane locations, such as a few register programming manuals that are
- * increasingly hard to find and the NI MHDDK (comments in example code).
- * There is no one place to find the various valid values of the registers.
- * 2) The register values are _NOT_ completely consistent. There is no way to
- * gain any sense of intuition of which values, or even enums one should use
- * for various registers. There was some attempt in prior use of comedi to
- * name enums such that a user might know which enums should be used for
- * varying purposes, but the end-user had to gain a knowledge of register
- * values to correctly wield this approach.
- * 3) The names for signals and registers found in the various register level
- * programming manuals and vendor-provided documentation are _not_ even
- * close to the same names that are in the end-user documentation.
- *
- * Similar, albeit less, confusion plagued NI's previous version of their own
- * drivers. Earlier than 2003, NI greatly simplified the situation for users
- * by releasing a new API that abstracted the names of signals/terminals to a
- * common and intuitive set of names.
- *
- * The names below mirror the names chosen and well documented by NI. These
- * names are exposed to the user via the comedilib user library. By keeping
- * the names below, in spite of the use of CamelScript, maintenance will be
- * greatly eased and confusion for users _and_ comedi developers will be
- * greatly reduced.
- */
-
-/*
- * Base of abstracted NI names.
- * The first 16 bits of *_arg are reserved for channel selection.
- * Since we only actually need the first 4 or 5 bits for all register values on
- * NI select registers anyways, we'll identify all values >= (1<<15) as being an
- * abstracted NI signal/terminal name.
- * These values are also used/returned by INSN_DEVICE_CONFIG_TEST_ROUTE,
- * INSN_DEVICE_CONFIG_CONNECT_ROUTE, INSN_DEVICE_CONFIG_DISCONNECT_ROUTE,
- * and INSN_DEVICE_CONFIG_GET_ROUTES.
- */
-#define NI_NAMES_BASE 0x8000u
-
-#define _TERM_N(base, n, x) ((base) + ((x) & ((n) - 1)))
-
-/*
- * not necessarily all allowed 64 PFIs are valid--certainly not for all devices
- */
-#define NI_PFI(x) _TERM_N(NI_NAMES_BASE, 64, x)
-/* 8 trigger lines by standard, Some devices cannot talk to all eight. */
-#define TRIGGER_LINE(x) _TERM_N(NI_PFI(-1) + 1, 8, x)
-/* 4 RTSI shared MUXes to route signals to/from TRIGGER_LINES on NI hardware */
-#define NI_RTSI_BRD(x) _TERM_N(TRIGGER_LINE(-1) + 1, 4, x)
-
-/* *** Counter/timer names : 8 counters max *** */
-#define NI_MAX_COUNTERS 8
-#define NI_COUNTER_NAMES_BASE (NI_RTSI_BRD(-1) + 1)
-#define NI_CtrSource(x) _TERM_N(NI_COUNTER_NAMES_BASE, NI_MAX_COUNTERS, x)
-/* Gate, Aux, A,B,Z are all treated, at times as gates */
-#define NI_GATES_NAMES_BASE (NI_CtrSource(-1) + 1)
-#define NI_CtrGate(x) _TERM_N(NI_GATES_NAMES_BASE, NI_MAX_COUNTERS, x)
-#define NI_CtrAux(x) _TERM_N(NI_CtrGate(-1) + 1, NI_MAX_COUNTERS, x)
-#define NI_CtrA(x) _TERM_N(NI_CtrAux(-1) + 1, NI_MAX_COUNTERS, x)
-#define NI_CtrB(x) _TERM_N(NI_CtrA(-1) + 1, NI_MAX_COUNTERS, x)
-#define NI_CtrZ(x) _TERM_N(NI_CtrB(-1) + 1, NI_MAX_COUNTERS, x)
-#define NI_GATES_NAMES_MAX NI_CtrZ(-1)
-#define NI_CtrArmStartTrigger(x) _TERM_N(NI_CtrZ(-1) + 1, NI_MAX_COUNTERS, x)
-#define NI_CtrInternalOutput(x) \
- _TERM_N(NI_CtrArmStartTrigger(-1) + 1, NI_MAX_COUNTERS, x)
-/** external pin(s) labeled conveniently as Ctr<i>Out. */
-#define NI_CtrOut(x) _TERM_N(NI_CtrInternalOutput(-1) + 1, NI_MAX_COUNTERS, x)
-/** For Buffered sampling of ctr -- x series capability. */
-#define NI_CtrSampleClock(x) _TERM_N(NI_CtrOut(-1) + 1, NI_MAX_COUNTERS, x)
-#define NI_COUNTER_NAMES_MAX NI_CtrSampleClock(-1)
-
-enum ni_common_signal_names {
- /* PXI_Star: this is a non-NI-specific signal */
- PXI_Star = NI_COUNTER_NAMES_MAX + 1,
- PXI_Clk10,
- PXIe_Clk100,
- NI_AI_SampleClock,
- NI_AI_SampleClockTimebase,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_ConvertClockTimebase,
- NI_AI_PauseTrigger,
- NI_AI_HoldCompleteEvent,
- NI_AI_HoldComplete,
- NI_AI_ExternalMUXClock,
- NI_AI_STOP, /* pulse signal that occurs when a update is finished(?) */
- NI_AO_SampleClock,
- NI_AO_SampleClockTimebase,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_SampleClockTimebase,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_SampleClock,
- NI_DO_SampleClockTimebase,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100MHzTimebase,
- NI_200MHzTimebase,
- NI_100kHzTimebase,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- NI_WatchdogExpiredEvent,
- NI_WatchdogExpirationTrigger,
- NI_SCXI_Trig1,
- NI_LogicLow,
- NI_LogicHigh,
- NI_ExternalStrobe,
- NI_PFI_DO,
- NI_CaseGround,
- /* special internal signal used as variable source for RTSI bus: */
- NI_RGOUT0,
-
- /* just a name to make the next more convenient, regardless of above */
- _NI_NAMES_MAX_PLUS_1,
- NI_NUM_NAMES = _NI_NAMES_MAX_PLUS_1 - NI_NAMES_BASE,
-};
-
-/* *** END GLOBALLY-NAMED NI TERMINALS/SIGNALS *** */
-
-#define NI_USUAL_PFI_SELECT(x) (((x) < 10) ? (0x1 + (x)) : (0xb + (x)))
-#define NI_USUAL_RTSI_SELECT(x) (((x) < 7) ? (0xb + (x)) : 0x1b)
-
-/*
- * mode bits for NI general-purpose counters, set with
- * INSN_CONFIG_SET_COUNTER_MODE
- */
-#define NI_GPCT_COUNTING_MODE_SHIFT 16
-#define NI_GPCT_INDEX_PHASE_BITSHIFT 20
-#define NI_GPCT_COUNTING_DIRECTION_SHIFT 24
-enum ni_gpct_mode_bits {
- NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
- NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
- NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
- NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
- NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
- NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
- NI_GPCT_STOP_MODE_MASK = 0x60,
- NI_GPCT_STOP_ON_GATE_BITS = 0x00,
- NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
- NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
- NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
- NI_GPCT_OUTPUT_MODE_MASK = 0x300,
- NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
- NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
- NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
- NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
- NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
- NI_GPCT_DISARM_AT_TC_BITS = 0x400,
- NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
- NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
- NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
- NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
- NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
- NI_GPCT_COUNTING_MODE_NORMAL_BITS =
- 0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
- NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =
- 0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
- NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =
- 0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
- NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =
- 0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
- NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =
- 0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
- NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =
- 0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
- NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
- NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =
- 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
- NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =
- 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
- NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =
- 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
- NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =
- 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
- NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
- NI_GPCT_COUNTING_DIRECTION_MASK =
- 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
- NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =
- 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
- NI_GPCT_COUNTING_DIRECTION_UP_BITS =
- 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
- NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =
- 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
- NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =
- 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
- NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
- NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
- NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
- NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
- NI_GPCT_OR_GATE_BIT = 0x10000000,
- NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
-};
-
-/*
- * Bits for setting a clock source with
- * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters.
- */
-enum ni_gpct_clock_source_bits {
- NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
- NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
- NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
- NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
- NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
- NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
- NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
- /* NI 660x-specific */
- NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,
- NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
- NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
- NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
- NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
- NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
- /* divide source by 2 */
- NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000,
- /* divide source by 8 */
- NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,
- NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
-};
-
-/* NI 660x-specific */
-#define NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(x) (0x10 + (x))
-
-#define NI_GPCT_RTSI_CLOCK_SRC_BITS(x) (0x18 + (x))
-
-/* no pfi on NI 660x */
-#define NI_GPCT_PFI_CLOCK_SRC_BITS(x) (0x20 + (x))
-
-/*
- * Possibilities for setting a gate source with
- * INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
- * May be bitwise-or'd with CR_EDGE or CR_INVERT.
- */
-enum ni_gpct_gate_select {
- /* m-series gates */
- NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
- NI_GPCT_AI_START2_GATE_SELECT = 0x12,
- NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
- NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
- NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
- NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
- NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
- NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
- /* more gates for 660x */
- NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
- NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
- /* more gates for 660x "second gate" */
- NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
- NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
- /*
- * m-series "second gate" sources are unknown,
- * we should add them here with an offset of 0x300 when
- * known.
- */
- NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
-};
-
-#define NI_GPCT_GATE_PIN_GATE_SELECT(x) (0x102 + (x))
-#define NI_GPCT_RTSI_GATE_SELECT(x) NI_USUAL_RTSI_SELECT(x)
-#define NI_GPCT_PFI_GATE_SELECT(x) NI_USUAL_PFI_SELECT(x)
-#define NI_GPCT_UP_DOWN_PIN_GATE_SELECT(x) (0x202 + (x))
-
-/*
- * Possibilities for setting a source with
- * INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters.
- */
-enum ni_gpct_other_index {
- NI_GPCT_SOURCE_ENCODER_A,
- NI_GPCT_SOURCE_ENCODER_B,
- NI_GPCT_SOURCE_ENCODER_Z
-};
-
-enum ni_gpct_other_select {
- /* m-series gates */
- /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
- NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
-};
-
-#define NI_GPCT_PFI_OTHER_SELECT(x) NI_USUAL_PFI_SELECT(x)
-
-/*
- * start sources for ni general-purpose counters for use with
- * INSN_CONFIG_ARM
- */
-enum ni_gpct_arm_source {
- NI_GPCT_ARM_IMMEDIATE = 0x0,
- /*
- * Start both the counter and the adjacent paired counter simultaneously
- */
- NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1,
- /*
- * If the NI_GPCT_HW_ARM bit is set, we will pass the least significant
- * bits (3 bits for 660x or 5 bits for m-series) through to the
- * hardware. To select a hardware trigger, pass the appropriate select
- * bit, e.g.,
- * NI_GPCT_HW_ARM | NI_GPCT_AI_START1_GATE_SELECT or
- * NI_GPCT_HW_ARM | NI_GPCT_PFI_GATE_SELECT(pfi_number)
- */
- NI_GPCT_HW_ARM = 0x1000,
- NI_GPCT_ARM_UNKNOWN = NI_GPCT_HW_ARM, /* for backward compatibility */
-};
-
-/* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */
-enum ni_gpct_filter_select {
- NI_GPCT_FILTER_OFF = 0x0,
- NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
- NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
- NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
- NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
- NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
- NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
-};
-
-/*
- * PFI digital filtering options for ni m-series for use with
- * INSN_CONFIG_FILTER.
- */
-enum ni_pfi_filter_select {
- NI_PFI_FILTER_OFF = 0x0,
- NI_PFI_FILTER_125ns = 0x1,
- NI_PFI_FILTER_6425ns = 0x2,
- NI_PFI_FILTER_2550us = 0x3
-};
-
-/* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */
-enum ni_mio_clock_source {
- NI_MIO_INTERNAL_CLOCK = 0,
- /*
- * Doesn't work for m-series, use NI_MIO_PLL_RTSI_CLOCK()
- * the NI_MIO_PLL_* sources are m-series only
- */
- NI_MIO_RTSI_CLOCK = 1,
- NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
- NI_MIO_PLL_PXI10_CLOCK = 3,
- NI_MIO_PLL_RTSI0_CLOCK = 4
-};
-
-#define NI_MIO_PLL_RTSI_CLOCK(x) (NI_MIO_PLL_RTSI0_CLOCK + (x))
-
-/*
- * Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
- * The numbers assigned are not arbitrary, they correspond to the bits required
- * to program the board.
- */
-enum ni_rtsi_routing {
- NI_RTSI_OUTPUT_ADR_START1 = 0,
- NI_RTSI_OUTPUT_ADR_START2 = 1,
- NI_RTSI_OUTPUT_SCLKG = 2,
- NI_RTSI_OUTPUT_DACUPDN = 3,
- NI_RTSI_OUTPUT_DA_START1 = 4,
- NI_RTSI_OUTPUT_G_SRC0 = 5,
- NI_RTSI_OUTPUT_G_GATE0 = 6,
- NI_RTSI_OUTPUT_RGOUT0 = 7,
- NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
- /* Pre-m-series always have RTSI clock on line 7 */
- NI_RTSI_OUTPUT_RTSI_OSC = 12
-};
-
-#define NI_RTSI_OUTPUT_RTSI_BRD(x) (NI_RTSI_OUTPUT_RTSI_BRD_0 + (x))
-
-/*
- * Signals which can be routed to an NI PFI pin on an m-series board with
- * INSN_CONFIG_SET_ROUTING. These numbers are also returned by
- * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing
- * cannot be changed. The numbers assigned are not arbitrary, they correspond
- * to the bits required to program the board.
- */
-enum ni_pfi_routing {
- NI_PFI_OUTPUT_PFI_DEFAULT = 0,
- NI_PFI_OUTPUT_AI_START1 = 1,
- NI_PFI_OUTPUT_AI_START2 = 2,
- NI_PFI_OUTPUT_AI_CONVERT = 3,
- NI_PFI_OUTPUT_G_SRC1 = 4,
- NI_PFI_OUTPUT_G_GATE1 = 5,
- NI_PFI_OUTPUT_AO_UPDATE_N = 6,
- NI_PFI_OUTPUT_AO_START1 = 7,
- NI_PFI_OUTPUT_AI_START_PULSE = 8,
- NI_PFI_OUTPUT_G_SRC0 = 9,
- NI_PFI_OUTPUT_G_GATE0 = 10,
- NI_PFI_OUTPUT_EXT_STROBE = 11,
- NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
- NI_PFI_OUTPUT_GOUT0 = 13,
- NI_PFI_OUTPUT_GOUT1 = 14,
- NI_PFI_OUTPUT_FREQ_OUT = 15,
- NI_PFI_OUTPUT_PFI_DO = 16,
- NI_PFI_OUTPUT_I_ATRIG = 17,
- NI_PFI_OUTPUT_RTSI0 = 18,
- NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
- NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
- NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
- NI_PFI_OUTPUT_CDI_SAMPLE = 29,
- NI_PFI_OUTPUT_CDO_UPDATE = 30
-};
-
-#define NI_PFI_OUTPUT_RTSI(x) (NI_PFI_OUTPUT_RTSI0 + (x))
-
-/*
- * Signals which can be routed to output on a NI PFI pin on a 660x board
- * with INSN_CONFIG_SET_ROUTING. The numbers assigned are
- * not arbitrary, they correspond to the bits required
- * to program the board. Lines 0 to 7 can only be set to
- * NI_660X_PFI_OUTPUT_DIO. Lines 32 to 39 can only be set to
- * NI_660X_PFI_OUTPUT_COUNTER.
- */
-enum ni_660x_pfi_routing {
- NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */
- NI_660X_PFI_OUTPUT_DIO = 2, /* static digital output */
-};
-
-/*
- * NI External Trigger lines. These values are not arbitrary, but are related
- * to the bits required to program the board (offset by 1 for historical
- * reasons).
- */
-#define NI_EXT_PFI(x) (NI_USUAL_PFI_SELECT(x) - 1)
-#define NI_EXT_RTSI(x) (NI_USUAL_RTSI_SELECT(x) - 1)
-
-/*
- * Clock sources for CDIO subdevice on NI m-series boards. Used as the
- * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd
- * with CR_INVERT to change polarity.
- */
-enum ni_m_series_cdio_scan_begin_src {
- NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
- NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
- NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
- NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
- NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
- NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
- NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
- NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
- NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
- NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
-};
-
-#define NI_CDIO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x)
-#define NI_CDIO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x)
-
-/*
- * scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
- * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to
- * change polarity.
- */
-#define NI_AO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x)
-#define NI_AO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x)
-
-/*
- * Bits for setting a clock source with
- * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice.
- */
-enum ni_freq_out_clock_source_bits {
- NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */
- NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC /* 100 KHz */
-};
-
-/*
- * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
- * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver).
- */
-enum amplc_dio_clock_source {
- /*
- * Per channel external clock
- * input/output pin (pin is only an
- * input when clock source set to this value,
- * otherwise it is an output)
- */
- AMPLC_DIO_CLK_CLKN,
- AMPLC_DIO_CLK_10MHZ, /* 10 MHz internal clock */
- AMPLC_DIO_CLK_1MHZ, /* 1 MHz internal clock */
- AMPLC_DIO_CLK_100KHZ, /* 100 kHz internal clock */
- AMPLC_DIO_CLK_10KHZ, /* 10 kHz internal clock */
- AMPLC_DIO_CLK_1KHZ, /* 1 kHz internal clock */
- /*
- * Output of preceding counter channel
- * (for channel 0, preceding counter
- * channel is channel 2 on preceding
- * counter subdevice, for first counter
- * subdevice, preceding counter
- * subdevice is the last counter
- * subdevice)
- */
- AMPLC_DIO_CLK_OUTNM1,
- AMPLC_DIO_CLK_EXT, /* per chip external input pin */
- /* the following are "enhanced" clock sources for PCIe models */
- AMPLC_DIO_CLK_VCC, /* clock input HIGH */
- AMPLC_DIO_CLK_GND, /* clock input LOW */
- AMPLC_DIO_CLK_PAT_PRESENT, /* "pattern present" signal */
- AMPLC_DIO_CLK_20MHZ /* 20 MHz internal clock */
-};
-
-/*
- * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
- * timer subdevice on some Amplicon DIO PCIe boards (amplc_dio200 driver).
- */
-enum amplc_dio_ts_clock_src {
- AMPLC_DIO_TS_CLK_1GHZ, /* 1 ns period with 20 ns granularity */
- AMPLC_DIO_TS_CLK_1MHZ, /* 1 us period */
- AMPLC_DIO_TS_CLK_1KHZ /* 1 ms period */
-};
-
-/*
- * Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for
- * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver).
- */
-enum amplc_dio_gate_source {
- AMPLC_DIO_GAT_VCC, /* internal high logic level */
- AMPLC_DIO_GAT_GND, /* internal low logic level */
- AMPLC_DIO_GAT_GATN, /* per channel external gate input */
- /*
- * negated output of counter channel minus 2
- * (for channels 0 or 1, channel minus 2 is channel 1 or 2 on
- * the preceding counter subdevice, for the first counter subdevice
- * the preceding counter subdevice is the last counter subdevice)
- */
- AMPLC_DIO_GAT_NOUTNM2,
- AMPLC_DIO_GAT_RESERVED4,
- AMPLC_DIO_GAT_RESERVED5,
- AMPLC_DIO_GAT_RESERVED6,
- AMPLC_DIO_GAT_RESERVED7,
- /* the following are "enhanced" gate sources for PCIe models */
- AMPLC_DIO_GAT_NGATN = 6, /* negated per channel gate input */
- /* non-negated output of counter channel minus 2 */
- AMPLC_DIO_GAT_OUTNM2,
- AMPLC_DIO_GAT_PAT_PRESENT, /* "pattern present" signal */
- AMPLC_DIO_GAT_PAT_OCCURRED, /* "pattern occurred" latched */
- AMPLC_DIO_GAT_PAT_GONE, /* "pattern gone away" latched */
- AMPLC_DIO_GAT_NPAT_PRESENT, /* negated "pattern present" */
- AMPLC_DIO_GAT_NPAT_OCCURRED, /* negated "pattern occurred" */
- AMPLC_DIO_GAT_NPAT_GONE /* negated "pattern gone away" */
-};
-
-/*
- * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
- * the counter subdevice on the Kolter Electronic PCI-Counter board
- * (ke_counter driver).
- */
-enum ke_counter_clock_source {
- KE_CLK_20MHZ, /* internal 20MHz (default) */
- KE_CLK_4MHZ, /* internal 4MHz (option) */
- KE_CLK_EXT /* external clock on pin 21 of D-Sub */
-};
-
-#endif /* _COMEDI_H */
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c
deleted file mode 100644
index 06bfc859ab31..000000000000
--- a/drivers/staging/comedi/comedi_buf.c
+++ /dev/null
@@ -1,692 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_buf.c
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-
-#include "comedidev.h"
-#include "comedi_internal.h"
-
-#ifdef PAGE_KERNEL_NOCACHE
-#define COMEDI_PAGE_PROTECTION PAGE_KERNEL_NOCACHE
-#else
-#define COMEDI_PAGE_PROTECTION PAGE_KERNEL
-#endif
-
-static void comedi_buf_map_kref_release(struct kref *kref)
-{
- struct comedi_buf_map *bm =
- container_of(kref, struct comedi_buf_map, refcount);
- struct comedi_buf_page *buf;
- unsigned int i;
-
- if (bm->page_list) {
- if (bm->dma_dir != DMA_NONE) {
- /*
- * DMA buffer was allocated as a single block.
- * Address is in page_list[0].
- */
- buf = &bm->page_list[0];
- dma_free_coherent(bm->dma_hw_dev,
- PAGE_SIZE * bm->n_pages,
- buf->virt_addr, buf->dma_addr);
- } else {
- for (i = 0; i < bm->n_pages; i++) {
- buf = &bm->page_list[i];
- ClearPageReserved(virt_to_page(buf->virt_addr));
- free_page((unsigned long)buf->virt_addr);
- }
- }
- vfree(bm->page_list);
- }
- if (bm->dma_dir != DMA_NONE)
- put_device(bm->dma_hw_dev);
- kfree(bm);
-}
-
-static void __comedi_buf_free(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- struct comedi_buf_map *bm;
- unsigned long flags;
-
- if (async->prealloc_buf) {
- if (s->async_dma_dir == DMA_NONE)
- vunmap(async->prealloc_buf);
- async->prealloc_buf = NULL;
- async->prealloc_bufsz = 0;
- }
-
- spin_lock_irqsave(&s->spin_lock, flags);
- bm = async->buf_map;
- async->buf_map = NULL;
- spin_unlock_irqrestore(&s->spin_lock, flags);
- comedi_buf_map_put(bm);
-}
-
-static struct comedi_buf_map *
-comedi_buf_map_alloc(struct comedi_device *dev, enum dma_data_direction dma_dir,
- unsigned int n_pages)
-{
- struct comedi_buf_map *bm;
- struct comedi_buf_page *buf;
- unsigned int i;
-
- bm = kzalloc(sizeof(*bm), GFP_KERNEL);
- if (!bm)
- return NULL;
-
- kref_init(&bm->refcount);
- bm->dma_dir = dma_dir;
- if (bm->dma_dir != DMA_NONE) {
- /* Need ref to hardware device to free buffer later. */
- bm->dma_hw_dev = get_device(dev->hw_dev);
- }
-
- bm->page_list = vzalloc(sizeof(*buf) * n_pages);
- if (!bm->page_list)
- goto err;
-
- if (bm->dma_dir != DMA_NONE) {
- void *virt_addr;
- dma_addr_t dma_addr;
-
- /*
- * Currently, the DMA buffer needs to be allocated as a
- * single block so that it can be mmap()'ed.
- */
- virt_addr = dma_alloc_coherent(bm->dma_hw_dev,
- PAGE_SIZE * n_pages, &dma_addr,
- GFP_KERNEL);
- if (!virt_addr)
- goto err;
-
- for (i = 0; i < n_pages; i++) {
- buf = &bm->page_list[i];
- buf->virt_addr = virt_addr + (i << PAGE_SHIFT);
- buf->dma_addr = dma_addr + (i << PAGE_SHIFT);
- }
-
- bm->n_pages = i;
- } else {
- for (i = 0; i < n_pages; i++) {
- buf = &bm->page_list[i];
- buf->virt_addr = (void *)get_zeroed_page(GFP_KERNEL);
- if (!buf->virt_addr)
- break;
-
- SetPageReserved(virt_to_page(buf->virt_addr));
- }
-
- bm->n_pages = i;
- if (i < n_pages)
- goto err;
- }
-
- return bm;
-
-err:
- comedi_buf_map_put(bm);
- return NULL;
-}
-
-static void __comedi_buf_alloc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int n_pages)
-{
- struct comedi_async *async = s->async;
- struct page **pages = NULL;
- struct comedi_buf_map *bm;
- struct comedi_buf_page *buf;
- unsigned long flags;
- unsigned int i;
-
- if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
- dev_err(dev->class_dev,
- "dma buffer allocation not supported\n");
- return;
- }
-
- bm = comedi_buf_map_alloc(dev, s->async_dma_dir, n_pages);
- if (!bm)
- return;
-
- spin_lock_irqsave(&s->spin_lock, flags);
- async->buf_map = bm;
- spin_unlock_irqrestore(&s->spin_lock, flags);
-
- if (bm->dma_dir != DMA_NONE) {
- /*
- * DMA buffer was allocated as a single block.
- * Address is in page_list[0].
- */
- buf = &bm->page_list[0];
- async->prealloc_buf = buf->virt_addr;
- } else {
- pages = vmalloc(sizeof(struct page *) * n_pages);
- if (!pages)
- return;
-
- for (i = 0; i < n_pages; i++) {
- buf = &bm->page_list[i];
- pages[i] = virt_to_page(buf->virt_addr);
- }
-
- /* vmap the pages to prealloc_buf */
- async->prealloc_buf = vmap(pages, n_pages, VM_MAP,
- COMEDI_PAGE_PROTECTION);
-
- vfree(pages);
- }
-}
-
-void comedi_buf_map_get(struct comedi_buf_map *bm)
-{
- if (bm)
- kref_get(&bm->refcount);
-}
-
-int comedi_buf_map_put(struct comedi_buf_map *bm)
-{
- if (bm)
- return kref_put(&bm->refcount, comedi_buf_map_kref_release);
- return 1;
-}
-
-/* helper for "access" vm operation */
-int comedi_buf_map_access(struct comedi_buf_map *bm, unsigned long offset,
- void *buf, int len, int write)
-{
- unsigned int pgoff = offset_in_page(offset);
- unsigned long pg = offset >> PAGE_SHIFT;
- int done = 0;
-
- while (done < len && pg < bm->n_pages) {
- int l = min_t(int, len - done, PAGE_SIZE - pgoff);
- void *b = bm->page_list[pg].virt_addr + pgoff;
-
- if (write)
- memcpy(b, buf, l);
- else
- memcpy(buf, b, l);
- buf += l;
- done += l;
- pg++;
- pgoff = 0;
- }
- return done;
-}
-
-/* returns s->async->buf_map and increments its kref refcount */
-struct comedi_buf_map *
-comedi_buf_map_from_subdev_get(struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- struct comedi_buf_map *bm = NULL;
- unsigned long flags;
-
- if (!async)
- return NULL;
-
- spin_lock_irqsave(&s->spin_lock, flags);
- bm = async->buf_map;
- /* only want it if buffer pages allocated */
- if (bm && bm->n_pages)
- comedi_buf_map_get(bm);
- else
- bm = NULL;
- spin_unlock_irqrestore(&s->spin_lock, flags);
-
- return bm;
-}
-
-bool comedi_buf_is_mmapped(struct comedi_subdevice *s)
-{
- struct comedi_buf_map *bm = s->async->buf_map;
-
- return bm && (kref_read(&bm->refcount) > 1);
-}
-
-int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned long new_size)
-{
- struct comedi_async *async = s->async;
-
- lockdep_assert_held(&dev->mutex);
-
- /* Round up new_size to multiple of PAGE_SIZE */
- new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
-
- /* if no change is required, do nothing */
- if (async->prealloc_buf && async->prealloc_bufsz == new_size)
- return 0;
-
- /* deallocate old buffer */
- __comedi_buf_free(dev, s);
-
- /* allocate new buffer */
- if (new_size) {
- unsigned int n_pages = new_size >> PAGE_SHIFT;
-
- __comedi_buf_alloc(dev, s, n_pages);
-
- if (!async->prealloc_buf) {
- /* allocation failed */
- __comedi_buf_free(dev, s);
- return -ENOMEM;
- }
- }
- async->prealloc_bufsz = new_size;
-
- return 0;
-}
-
-void comedi_buf_reset(struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
-
- async->buf_write_alloc_count = 0;
- async->buf_write_count = 0;
- async->buf_read_alloc_count = 0;
- async->buf_read_count = 0;
-
- async->buf_write_ptr = 0;
- async->buf_read_ptr = 0;
-
- async->cur_chan = 0;
- async->scans_done = 0;
- async->scan_progress = 0;
- async->munge_chan = 0;
- async->munge_count = 0;
- async->munge_ptr = 0;
-
- async->events = 0;
-}
-
-static unsigned int comedi_buf_write_n_unalloc(struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
-
- return free_end - async->buf_write_alloc_count;
-}
-
-unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
-
- return free_end - async->buf_write_count;
-}
-
-/**
- * comedi_buf_write_alloc() - Reserve buffer space for writing
- * @s: COMEDI subdevice.
- * @nbytes: Maximum space to reserve in bytes.
- *
- * Reserve up to @nbytes bytes of space to be written in the COMEDI acquisition
- * data buffer associated with the subdevice. The amount reserved is limited
- * by the space available.
- *
- * Return: The amount of space reserved in bytes.
- */
-unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s,
- unsigned int nbytes)
-{
- struct comedi_async *async = s->async;
- unsigned int unalloc = comedi_buf_write_n_unalloc(s);
-
- if (nbytes > unalloc)
- nbytes = unalloc;
-
- async->buf_write_alloc_count += nbytes;
-
- /*
- * ensure the async buffer 'counts' are read and updated
- * before we write data to the write-alloc'ed buffer space
- */
- smp_mb();
-
- return nbytes;
-}
-EXPORT_SYMBOL_GPL(comedi_buf_write_alloc);
-
-/*
- * munging is applied to data by core as it passes between user
- * and kernel space
- */
-static unsigned int comedi_buf_munge(struct comedi_subdevice *s,
- unsigned int num_bytes)
-{
- struct comedi_async *async = s->async;
- unsigned int count = 0;
- const unsigned int num_sample_bytes = comedi_bytes_per_sample(s);
-
- if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) {
- async->munge_count += num_bytes;
- return num_bytes;
- }
-
- /* don't munge partial samples */
- num_bytes -= num_bytes % num_sample_bytes;
- while (count < num_bytes) {
- int block_size = num_bytes - count;
- unsigned int buf_end;
-
- buf_end = async->prealloc_bufsz - async->munge_ptr;
- if (block_size > buf_end)
- block_size = buf_end;
-
- s->munge(s->device, s,
- async->prealloc_buf + async->munge_ptr,
- block_size, async->munge_chan);
-
- /*
- * ensure data is munged in buffer before the
- * async buffer munge_count is incremented
- */
- smp_wmb();
-
- async->munge_chan += block_size / num_sample_bytes;
- async->munge_chan %= async->cmd.chanlist_len;
- async->munge_count += block_size;
- async->munge_ptr += block_size;
- async->munge_ptr %= async->prealloc_bufsz;
- count += block_size;
- }
-
- return count;
-}
-
-unsigned int comedi_buf_write_n_allocated(struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
-
- return async->buf_write_alloc_count - async->buf_write_count;
-}
-
-/**
- * comedi_buf_write_free() - Free buffer space after it is written
- * @s: COMEDI subdevice.
- * @nbytes: Maximum space to free in bytes.
- *
- * Free up to @nbytes bytes of space previously reserved for writing in the
- * COMEDI acquisition data buffer associated with the subdevice. The amount of
- * space freed is limited to the amount that was reserved. The freed space is
- * assumed to have been filled with sample data by the writer.
- *
- * If the samples in the freed space need to be "munged", do so here. The
- * freed space becomes available for allocation by the reader.
- *
- * Return: The amount of space freed in bytes.
- */
-unsigned int comedi_buf_write_free(struct comedi_subdevice *s,
- unsigned int nbytes)
-{
- struct comedi_async *async = s->async;
- unsigned int allocated = comedi_buf_write_n_allocated(s);
-
- if (nbytes > allocated)
- nbytes = allocated;
-
- async->buf_write_count += nbytes;
- async->buf_write_ptr += nbytes;
- comedi_buf_munge(s, async->buf_write_count - async->munge_count);
- if (async->buf_write_ptr >= async->prealloc_bufsz)
- async->buf_write_ptr %= async->prealloc_bufsz;
-
- return nbytes;
-}
-EXPORT_SYMBOL_GPL(comedi_buf_write_free);
-
-/**
- * comedi_buf_read_n_available() - Determine amount of readable buffer space
- * @s: COMEDI subdevice.
- *
- * Determine the amount of readable buffer space in the COMEDI acquisition data
- * buffer associated with the subdevice. The readable buffer space is that
- * which has been freed by the writer and "munged" to the sample data format
- * expected by COMEDI if necessary.
- *
- * Return: The amount of readable buffer space.
- */
-unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- unsigned int num_bytes;
-
- if (!async)
- return 0;
-
- num_bytes = async->munge_count - async->buf_read_count;
-
- /*
- * ensure the async buffer 'counts' are read before we
- * attempt to read data from the buffer
- */
- smp_rmb();
-
- return num_bytes;
-}
-EXPORT_SYMBOL_GPL(comedi_buf_read_n_available);
-
-/**
- * comedi_buf_read_alloc() - Reserve buffer space for reading
- * @s: COMEDI subdevice.
- * @nbytes: Maximum space to reserve in bytes.
- *
- * Reserve up to @nbytes bytes of previously written and "munged" buffer space
- * for reading in the COMEDI acquisition data buffer associated with the
- * subdevice. The amount reserved is limited to the space available. The
- * reader can read from the reserved space and then free it. A reader is also
- * allowed to read from the space before reserving it as long as it determines
- * the amount of readable data available, but the space needs to be marked as
- * reserved before it can be freed.
- *
- * Return: The amount of space reserved in bytes.
- */
-unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s,
- unsigned int nbytes)
-{
- struct comedi_async *async = s->async;
- unsigned int available;
-
- available = async->munge_count - async->buf_read_alloc_count;
- if (nbytes > available)
- nbytes = available;
-
- async->buf_read_alloc_count += nbytes;
-
- /*
- * ensure the async buffer 'counts' are read before we
- * attempt to read data from the read-alloc'ed buffer space
- */
- smp_rmb();
-
- return nbytes;
-}
-EXPORT_SYMBOL_GPL(comedi_buf_read_alloc);
-
-static unsigned int comedi_buf_read_n_allocated(struct comedi_async *async)
-{
- return async->buf_read_alloc_count - async->buf_read_count;
-}
-
-/**
- * comedi_buf_read_free() - Free buffer space after it has been read
- * @s: COMEDI subdevice.
- * @nbytes: Maximum space to free in bytes.
- *
- * Free up to @nbytes bytes of buffer space previously reserved for reading in
- * the COMEDI acquisition data buffer associated with the subdevice. The
- * amount of space freed is limited to the amount that was reserved.
- *
- * The freed space becomes available for allocation by the writer.
- *
- * Return: The amount of space freed in bytes.
- */
-unsigned int comedi_buf_read_free(struct comedi_subdevice *s,
- unsigned int nbytes)
-{
- struct comedi_async *async = s->async;
- unsigned int allocated;
-
- /*
- * ensure data has been read out of buffer before
- * the async read count is incremented
- */
- smp_mb();
-
- allocated = comedi_buf_read_n_allocated(async);
- if (nbytes > allocated)
- nbytes = allocated;
-
- async->buf_read_count += nbytes;
- async->buf_read_ptr += nbytes;
- async->buf_read_ptr %= async->prealloc_bufsz;
- return nbytes;
-}
-EXPORT_SYMBOL_GPL(comedi_buf_read_free);
-
-static void comedi_buf_memcpy_to(struct comedi_subdevice *s,
- const void *data, unsigned int num_bytes)
-{
- struct comedi_async *async = s->async;
- unsigned int write_ptr = async->buf_write_ptr;
-
- while (num_bytes) {
- unsigned int block_size;
-
- if (write_ptr + num_bytes > async->prealloc_bufsz)
- block_size = async->prealloc_bufsz - write_ptr;
- else
- block_size = num_bytes;
-
- memcpy(async->prealloc_buf + write_ptr, data, block_size);
-
- data += block_size;
- num_bytes -= block_size;
-
- write_ptr = 0;
- }
-}
-
-static void comedi_buf_memcpy_from(struct comedi_subdevice *s,
- void *dest, unsigned int nbytes)
-{
- void *src;
- struct comedi_async *async = s->async;
- unsigned int read_ptr = async->buf_read_ptr;
-
- while (nbytes) {
- unsigned int block_size;
-
- src = async->prealloc_buf + read_ptr;
-
- if (nbytes >= async->prealloc_bufsz - read_ptr)
- block_size = async->prealloc_bufsz - read_ptr;
- else
- block_size = nbytes;
-
- memcpy(dest, src, block_size);
- nbytes -= block_size;
- dest += block_size;
- read_ptr = 0;
- }
-}
-
-/**
- * comedi_buf_write_samples() - Write sample data to COMEDI buffer
- * @s: COMEDI subdevice.
- * @data: Pointer to source samples.
- * @nsamples: Number of samples to write.
- *
- * Write up to @nsamples samples to the COMEDI acquisition data buffer
- * associated with the subdevice, mark it as written and update the
- * acquisition scan progress. If there is not enough room for the specified
- * number of samples, the number of samples written is limited to the number
- * that will fit and the %COMEDI_CB_OVERFLOW event flag is set to cause the
- * acquisition to terminate with an overrun error. Set the %COMEDI_CB_BLOCK
- * event flag if any samples are written to cause waiting tasks to be woken
- * when the event flags are processed.
- *
- * Return: The amount of data written in bytes.
- */
-unsigned int comedi_buf_write_samples(struct comedi_subdevice *s,
- const void *data, unsigned int nsamples)
-{
- unsigned int max_samples;
- unsigned int nbytes;
-
- /*
- * Make sure there is enough room in the buffer for all the samples.
- * If not, clamp the nsamples to the number that will fit, flag the
- * buffer overrun and add the samples that fit.
- */
- max_samples = comedi_bytes_to_samples(s, comedi_buf_write_n_unalloc(s));
- if (nsamples > max_samples) {
- dev_warn(s->device->class_dev, "buffer overrun\n");
- s->async->events |= COMEDI_CB_OVERFLOW;
- nsamples = max_samples;
- }
-
- if (nsamples == 0)
- return 0;
-
- nbytes = comedi_buf_write_alloc(s,
- comedi_samples_to_bytes(s, nsamples));
- comedi_buf_memcpy_to(s, data, nbytes);
- comedi_buf_write_free(s, nbytes);
- comedi_inc_scan_progress(s, nbytes);
- s->async->events |= COMEDI_CB_BLOCK;
-
- return nbytes;
-}
-EXPORT_SYMBOL_GPL(comedi_buf_write_samples);
-
-/**
- * comedi_buf_read_samples() - Read sample data from COMEDI buffer
- * @s: COMEDI subdevice.
- * @data: Pointer to destination.
- * @nsamples: Maximum number of samples to read.
- *
- * Read up to @nsamples samples from the COMEDI acquisition data buffer
- * associated with the subdevice, mark it as read and update the acquisition
- * scan progress. Limit the number of samples read to the number available.
- * Set the %COMEDI_CB_BLOCK event flag if any samples are read to cause waiting
- * tasks to be woken when the event flags are processed.
- *
- * Return: The amount of data read in bytes.
- */
-unsigned int comedi_buf_read_samples(struct comedi_subdevice *s,
- void *data, unsigned int nsamples)
-{
- unsigned int max_samples;
- unsigned int nbytes;
-
- /* clamp nsamples to the number of full samples available */
- max_samples = comedi_bytes_to_samples(s,
- comedi_buf_read_n_available(s));
- if (nsamples > max_samples)
- nsamples = max_samples;
-
- if (nsamples == 0)
- return 0;
-
- nbytes = comedi_buf_read_alloc(s,
- comedi_samples_to_bytes(s, nsamples));
- comedi_buf_memcpy_from(s, data, nbytes);
- comedi_buf_read_free(s, nbytes);
- comedi_inc_scan_progress(s, nbytes);
- s->async->events |= COMEDI_CB_BLOCK;
-
- return nbytes;
-}
-EXPORT_SYMBOL_GPL(comedi_buf_read_samples);
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
deleted file mode 100644
index df77b6bf5c64..000000000000
--- a/drivers/staging/comedi/comedi_fops.c
+++ /dev/null
@@ -1,3436 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/comedi_fops.c
- * comedi kernel module
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
- * compat ioctls:
- * Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
- * Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/fcntl.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include "comedidev.h"
-#include <linux/cdev.h>
-
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/compat.h>
-
-#include "comedi_internal.h"
-
-/*
- * comedi_subdevice "runflags"
- * COMEDI_SRF_RT: DEPRECATED: command is running real-time
- * COMEDI_SRF_ERROR: indicates an COMEDI_CB_ERROR event has occurred
- * since the last command was started
- * COMEDI_SRF_RUNNING: command is running
- * COMEDI_SRF_FREE_SPRIV: free s->private on detach
- *
- * COMEDI_SRF_BUSY_MASK: runflags that indicate the subdevice is "busy"
- */
-#define COMEDI_SRF_RT BIT(1)
-#define COMEDI_SRF_ERROR BIT(2)
-#define COMEDI_SRF_RUNNING BIT(27)
-#define COMEDI_SRF_FREE_SPRIV BIT(31)
-
-#define COMEDI_SRF_BUSY_MASK (COMEDI_SRF_ERROR | COMEDI_SRF_RUNNING)
-
-/**
- * struct comedi_file - Per-file private data for COMEDI device
- * @dev: COMEDI device.
- * @read_subdev: Current "read" subdevice.
- * @write_subdev: Current "write" subdevice.
- * @last_detach_count: Last known detach count.
- * @last_attached: Last known attached/detached state.
- */
-struct comedi_file {
- struct comedi_device *dev;
- struct comedi_subdevice *read_subdev;
- struct comedi_subdevice *write_subdev;
- unsigned int last_detach_count;
- unsigned int last_attached:1;
-};
-
-#define COMEDI_NUM_MINORS 0x100
-#define COMEDI_NUM_SUBDEVICE_MINORS \
- (COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS)
-
-static unsigned short comedi_num_legacy_minors;
-module_param(comedi_num_legacy_minors, ushort, 0444);
-MODULE_PARM_DESC(comedi_num_legacy_minors,
- "number of comedi minor devices to reserve for non-auto-configured devices (default 0)"
- );
-
-unsigned int comedi_default_buf_size_kb = CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB;
-module_param(comedi_default_buf_size_kb, uint, 0644);
-MODULE_PARM_DESC(comedi_default_buf_size_kb,
- "default asynchronous buffer size in KiB (default "
- __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB) ")");
-
-unsigned int comedi_default_buf_maxsize_kb =
- CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB;
-module_param(comedi_default_buf_maxsize_kb, uint, 0644);
-MODULE_PARM_DESC(comedi_default_buf_maxsize_kb,
- "default maximum size of asynchronous buffer in KiB (default "
- __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB) ")");
-
-static DEFINE_MUTEX(comedi_board_minor_table_lock);
-static struct comedi_device
-*comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS];
-
-static DEFINE_MUTEX(comedi_subdevice_minor_table_lock);
-/* Note: indexed by minor - COMEDI_NUM_BOARD_MINORS. */
-static struct comedi_subdevice
-*comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS];
-
-static struct class *comedi_class;
-static struct cdev comedi_cdev;
-
-static void comedi_device_init(struct comedi_device *dev)
-{
- kref_init(&dev->refcount);
- spin_lock_init(&dev->spinlock);
- mutex_init(&dev->mutex);
- init_rwsem(&dev->attach_lock);
- dev->minor = -1;
-}
-
-static void comedi_dev_kref_release(struct kref *kref)
-{
- struct comedi_device *dev =
- container_of(kref, struct comedi_device, refcount);
-
- mutex_destroy(&dev->mutex);
- put_device(dev->class_dev);
- kfree(dev);
-}
-
-/**
- * comedi_dev_put() - Release a use of a COMEDI device
- * @dev: COMEDI device.
- *
- * Must be called when a user of a COMEDI device is finished with it.
- * When the last user of the COMEDI device calls this function, the
- * COMEDI device is destroyed.
- *
- * Return: 1 if the COMEDI device is destroyed by this call or @dev is
- * NULL, otherwise return 0. Callers must not assume the COMEDI
- * device is still valid if this function returns 0.
- */
-int comedi_dev_put(struct comedi_device *dev)
-{
- if (dev)
- return kref_put(&dev->refcount, comedi_dev_kref_release);
- return 1;
-}
-EXPORT_SYMBOL_GPL(comedi_dev_put);
-
-static struct comedi_device *comedi_dev_get(struct comedi_device *dev)
-{
- if (dev)
- kref_get(&dev->refcount);
- return dev;
-}
-
-static void comedi_device_cleanup(struct comedi_device *dev)
-{
- struct module *driver_module = NULL;
-
- if (!dev)
- return;
- mutex_lock(&dev->mutex);
- if (dev->attached)
- driver_module = dev->driver->module;
- comedi_device_detach(dev);
- if (driver_module && dev->use_count)
- module_put(driver_module);
- mutex_unlock(&dev->mutex);
-}
-
-static bool comedi_clear_board_dev(struct comedi_device *dev)
-{
- unsigned int i = dev->minor;
- bool cleared = false;
-
- lockdep_assert_held(&dev->mutex);
- mutex_lock(&comedi_board_minor_table_lock);
- if (dev == comedi_board_minor_table[i]) {
- comedi_board_minor_table[i] = NULL;
- cleared = true;
- }
- mutex_unlock(&comedi_board_minor_table_lock);
- return cleared;
-}
-
-static struct comedi_device *comedi_clear_board_minor(unsigned int minor)
-{
- struct comedi_device *dev;
-
- mutex_lock(&comedi_board_minor_table_lock);
- dev = comedi_board_minor_table[minor];
- comedi_board_minor_table[minor] = NULL;
- mutex_unlock(&comedi_board_minor_table_lock);
- return dev;
-}
-
-static void comedi_free_board_dev(struct comedi_device *dev)
-{
- if (dev) {
- comedi_device_cleanup(dev);
- if (dev->class_dev) {
- device_destroy(comedi_class,
- MKDEV(COMEDI_MAJOR, dev->minor));
- }
- comedi_dev_put(dev);
- }
-}
-
-static struct comedi_subdevice *
-comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned int minor)
-{
- struct comedi_subdevice *s;
- unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
-
- mutex_lock(&comedi_subdevice_minor_table_lock);
- s = comedi_subdevice_minor_table[i];
- if (s && s->device != dev)
- s = NULL;
- mutex_unlock(&comedi_subdevice_minor_table_lock);
- return s;
-}
-
-static struct comedi_device *comedi_dev_get_from_board_minor(unsigned int minor)
-{
- struct comedi_device *dev;
-
- mutex_lock(&comedi_board_minor_table_lock);
- dev = comedi_dev_get(comedi_board_minor_table[minor]);
- mutex_unlock(&comedi_board_minor_table_lock);
- return dev;
-}
-
-static struct comedi_device *
-comedi_dev_get_from_subdevice_minor(unsigned int minor)
-{
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
-
- mutex_lock(&comedi_subdevice_minor_table_lock);
- s = comedi_subdevice_minor_table[i];
- dev = comedi_dev_get(s ? s->device : NULL);
- mutex_unlock(&comedi_subdevice_minor_table_lock);
- return dev;
-}
-
-/**
- * comedi_dev_get_from_minor() - Get COMEDI device by minor device number
- * @minor: Minor device number.
- *
- * Finds the COMEDI device associated with the minor device number, if any,
- * and increments its reference count. The COMEDI device is prevented from
- * being freed until a matching call is made to comedi_dev_put().
- *
- * Return: A pointer to the COMEDI device if it exists, with its usage
- * reference incremented. Return NULL if no COMEDI device exists with the
- * specified minor device number.
- */
-struct comedi_device *comedi_dev_get_from_minor(unsigned int minor)
-{
- if (minor < COMEDI_NUM_BOARD_MINORS)
- return comedi_dev_get_from_board_minor(minor);
-
- return comedi_dev_get_from_subdevice_minor(minor);
-}
-EXPORT_SYMBOL_GPL(comedi_dev_get_from_minor);
-
-static struct comedi_subdevice *
-comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
-{
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- if (minor >= COMEDI_NUM_BOARD_MINORS) {
- s = comedi_subdevice_from_minor(dev, minor);
- if (!s || (s->subdev_flags & SDF_CMD_READ))
- return s;
- }
- return dev->read_subdev;
-}
-
-static struct comedi_subdevice *
-comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor)
-{
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- if (minor >= COMEDI_NUM_BOARD_MINORS) {
- s = comedi_subdevice_from_minor(dev, minor);
- if (!s || (s->subdev_flags & SDF_CMD_WRITE))
- return s;
- }
- return dev->write_subdev;
-}
-
-static void comedi_file_reset(struct file *file)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi_subdevice *s, *read_s, *write_s;
- unsigned int minor = iminor(file_inode(file));
-
- read_s = dev->read_subdev;
- write_s = dev->write_subdev;
- if (minor >= COMEDI_NUM_BOARD_MINORS) {
- s = comedi_subdevice_from_minor(dev, minor);
- if (!s || s->subdev_flags & SDF_CMD_READ)
- read_s = s;
- if (!s || s->subdev_flags & SDF_CMD_WRITE)
- write_s = s;
- }
- cfp->last_attached = dev->attached;
- cfp->last_detach_count = dev->detach_count;
- WRITE_ONCE(cfp->read_subdev, read_s);
- WRITE_ONCE(cfp->write_subdev, write_s);
-}
-
-static void comedi_file_check(struct file *file)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
-
- if (cfp->last_attached != dev->attached ||
- cfp->last_detach_count != dev->detach_count)
- comedi_file_reset(file);
-}
-
-static struct comedi_subdevice *comedi_file_read_subdevice(struct file *file)
-{
- struct comedi_file *cfp = file->private_data;
-
- comedi_file_check(file);
- return READ_ONCE(cfp->read_subdev);
-}
-
-static struct comedi_subdevice *comedi_file_write_subdevice(struct file *file)
-{
- struct comedi_file *cfp = file->private_data;
-
- comedi_file_check(file);
- return READ_ONCE(cfp->write_subdev);
-}
-
-static int resize_async_buffer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int new_size)
-{
- struct comedi_async *async = s->async;
- int retval;
-
- lockdep_assert_held(&dev->mutex);
-
- if (new_size > async->max_bufsize)
- return -EPERM;
-
- if (s->busy) {
- dev_dbg(dev->class_dev,
- "subdevice is busy, cannot resize buffer\n");
- return -EBUSY;
- }
- if (comedi_buf_is_mmapped(s)) {
- dev_dbg(dev->class_dev,
- "subdevice is mmapped, cannot resize buffer\n");
- return -EBUSY;
- }
-
- /* make sure buffer is an integral number of pages (we round up) */
- new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
-
- retval = comedi_buf_alloc(dev, s, new_size);
- if (retval < 0)
- return retval;
-
- if (s->buf_change) {
- retval = s->buf_change(dev, s);
- if (retval < 0)
- return retval;
- }
-
- dev_dbg(dev->class_dev, "subd %d buffer resized to %i bytes\n",
- s->index, async->prealloc_bufsz);
- return 0;
-}
-
-/* sysfs attribute files */
-
-static ssize_t max_read_buffer_kb_show(struct device *csdev,
- struct device_attribute *attr, char *buf)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size = 0;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_read_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
- size = s->async->max_bufsize / 1024;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return snprintf(buf, PAGE_SIZE, "%u\n", size);
-}
-
-static ssize_t max_read_buffer_kb_store(struct device *csdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size;
- int err;
-
- err = kstrtouint(buf, 10, &size);
- if (err)
- return err;
- if (size > (UINT_MAX / 1024))
- return -EINVAL;
- size *= 1024;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_read_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
- s->async->max_bufsize = size;
- else
- err = -EINVAL;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return err ? err : count;
-}
-static DEVICE_ATTR_RW(max_read_buffer_kb);
-
-static ssize_t read_buffer_kb_show(struct device *csdev,
- struct device_attribute *attr, char *buf)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size = 0;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_read_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
- size = s->async->prealloc_bufsz / 1024;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return snprintf(buf, PAGE_SIZE, "%u\n", size);
-}
-
-static ssize_t read_buffer_kb_store(struct device *csdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size;
- int err;
-
- err = kstrtouint(buf, 10, &size);
- if (err)
- return err;
- if (size > (UINT_MAX / 1024))
- return -EINVAL;
- size *= 1024;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_read_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
- err = resize_async_buffer(dev, s, size);
- else
- err = -EINVAL;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return err ? err : count;
-}
-static DEVICE_ATTR_RW(read_buffer_kb);
-
-static ssize_t max_write_buffer_kb_show(struct device *csdev,
- struct device_attribute *attr,
- char *buf)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size = 0;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_write_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
- size = s->async->max_bufsize / 1024;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return snprintf(buf, PAGE_SIZE, "%u\n", size);
-}
-
-static ssize_t max_write_buffer_kb_store(struct device *csdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size;
- int err;
-
- err = kstrtouint(buf, 10, &size);
- if (err)
- return err;
- if (size > (UINT_MAX / 1024))
- return -EINVAL;
- size *= 1024;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_write_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
- s->async->max_bufsize = size;
- else
- err = -EINVAL;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return err ? err : count;
-}
-static DEVICE_ATTR_RW(max_write_buffer_kb);
-
-static ssize_t write_buffer_kb_show(struct device *csdev,
- struct device_attribute *attr, char *buf)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size = 0;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_write_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
- size = s->async->prealloc_bufsz / 1024;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return snprintf(buf, PAGE_SIZE, "%u\n", size);
-}
-
-static ssize_t write_buffer_kb_store(struct device *csdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned int minor = MINOR(csdev->devt);
- struct comedi_device *dev;
- struct comedi_subdevice *s;
- unsigned int size;
- int err;
-
- err = kstrtouint(buf, 10, &size);
- if (err)
- return err;
- if (size > (UINT_MAX / 1024))
- return -EINVAL;
- size *= 1024;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return -ENODEV;
-
- mutex_lock(&dev->mutex);
- s = comedi_write_subdevice(dev, minor);
- if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
- err = resize_async_buffer(dev, s, size);
- else
- err = -EINVAL;
- mutex_unlock(&dev->mutex);
-
- comedi_dev_put(dev);
- return err ? err : count;
-}
-static DEVICE_ATTR_RW(write_buffer_kb);
-
-static struct attribute *comedi_dev_attrs[] = {
- &dev_attr_max_read_buffer_kb.attr,
- &dev_attr_read_buffer_kb.attr,
- &dev_attr_max_write_buffer_kb.attr,
- &dev_attr_write_buffer_kb.attr,
- NULL,
-};
-ATTRIBUTE_GROUPS(comedi_dev);
-
-static void __comedi_clear_subdevice_runflags(struct comedi_subdevice *s,
- unsigned int bits)
-{
- s->runflags &= ~bits;
-}
-
-static void __comedi_set_subdevice_runflags(struct comedi_subdevice *s,
- unsigned int bits)
-{
- s->runflags |= bits;
-}
-
-static void comedi_update_subdevice_runflags(struct comedi_subdevice *s,
- unsigned int mask,
- unsigned int bits)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&s->spin_lock, flags);
- __comedi_clear_subdevice_runflags(s, mask);
- __comedi_set_subdevice_runflags(s, bits & mask);
- spin_unlock_irqrestore(&s->spin_lock, flags);
-}
-
-static unsigned int __comedi_get_subdevice_runflags(struct comedi_subdevice *s)
-{
- return s->runflags;
-}
-
-static unsigned int comedi_get_subdevice_runflags(struct comedi_subdevice *s)
-{
- unsigned long flags;
- unsigned int runflags;
-
- spin_lock_irqsave(&s->spin_lock, flags);
- runflags = __comedi_get_subdevice_runflags(s);
- spin_unlock_irqrestore(&s->spin_lock, flags);
- return runflags;
-}
-
-static bool comedi_is_runflags_running(unsigned int runflags)
-{
- return runflags & COMEDI_SRF_RUNNING;
-}
-
-static bool comedi_is_runflags_in_error(unsigned int runflags)
-{
- return runflags & COMEDI_SRF_ERROR;
-}
-
-/**
- * comedi_is_subdevice_running() - Check if async command running on subdevice
- * @s: COMEDI subdevice.
- *
- * Return: %true if an asynchronous COMEDI command is active on the
- * subdevice, else %false.
- */
-bool comedi_is_subdevice_running(struct comedi_subdevice *s)
-{
- unsigned int runflags = comedi_get_subdevice_runflags(s);
-
- return comedi_is_runflags_running(runflags);
-}
-EXPORT_SYMBOL_GPL(comedi_is_subdevice_running);
-
-static bool __comedi_is_subdevice_running(struct comedi_subdevice *s)
-{
- unsigned int runflags = __comedi_get_subdevice_runflags(s);
-
- return comedi_is_runflags_running(runflags);
-}
-
-bool comedi_can_auto_free_spriv(struct comedi_subdevice *s)
-{
- unsigned int runflags = __comedi_get_subdevice_runflags(s);
-
- return runflags & COMEDI_SRF_FREE_SPRIV;
-}
-
-/**
- * comedi_set_spriv_auto_free() - Mark subdevice private data as freeable
- * @s: COMEDI subdevice.
- *
- * Mark the subdevice as having a pointer to private data that can be
- * automatically freed when the COMEDI device is detached from the low-level
- * driver.
- */
-void comedi_set_spriv_auto_free(struct comedi_subdevice *s)
-{
- __comedi_set_subdevice_runflags(s, COMEDI_SRF_FREE_SPRIV);
-}
-EXPORT_SYMBOL_GPL(comedi_set_spriv_auto_free);
-
-/**
- * comedi_alloc_spriv - Allocate memory for the subdevice private data
- * @s: COMEDI subdevice.
- * @size: Size of the memory to allocate.
- *
- * Allocate memory for the subdevice private data and point @s->private
- * to it. The memory will be freed automatically when the COMEDI device
- * is detached from the low-level driver.
- *
- * Return: A pointer to the allocated memory @s->private on success.
- * Return NULL on failure.
- */
-void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
-{
- s->private = kzalloc(size, GFP_KERNEL);
- if (s->private)
- comedi_set_spriv_auto_free(s);
- return s->private;
-}
-EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
-
-/*
- * This function restores a subdevice to an idle state.
- */
-static void do_become_nonbusy(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
-
- lockdep_assert_held(&dev->mutex);
- comedi_update_subdevice_runflags(s, COMEDI_SRF_RUNNING, 0);
- if (async) {
- comedi_buf_reset(s);
- async->inttrig = NULL;
- kfree(async->cmd.chanlist);
- async->cmd.chanlist = NULL;
- s->busy = NULL;
- wake_up_interruptible_all(&async->wait_head);
- } else {
- dev_err(dev->class_dev,
- "BUG: (?) %s called with async=NULL\n", __func__);
- s->busy = NULL;
- }
-}
-
-static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- int ret = 0;
-
- lockdep_assert_held(&dev->mutex);
- if (comedi_is_subdevice_running(s) && s->cancel)
- ret = s->cancel(dev, s);
-
- do_become_nonbusy(dev, s);
-
- return ret;
-}
-
-void comedi_device_cancel_all(struct comedi_device *dev)
-{
- struct comedi_subdevice *s;
- int i;
-
- lockdep_assert_held(&dev->mutex);
- if (!dev->attached)
- return;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- if (s->async)
- do_cancel(dev, s);
- }
-}
-
-static int is_device_busy(struct comedi_device *dev)
-{
- struct comedi_subdevice *s;
- int i;
-
- lockdep_assert_held(&dev->mutex);
- if (!dev->attached)
- return 0;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- if (s->busy)
- return 1;
- if (s->async && comedi_buf_is_mmapped(s))
- return 1;
- }
-
- return 0;
-}
-
-/*
- * COMEDI_DEVCONFIG ioctl
- * attaches (and configures) or detaches a legacy device
- *
- * arg:
- * pointer to comedi_devconfig structure (NULL if detaching)
- *
- * reads:
- * comedi_devconfig structure (if attaching)
- *
- * writes:
- * nothing
- */
-static int do_devconfig_ioctl(struct comedi_device *dev,
- struct comedi_devconfig __user *arg)
-{
- struct comedi_devconfig it;
-
- lockdep_assert_held(&dev->mutex);
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (!arg) {
- if (is_device_busy(dev))
- return -EBUSY;
- if (dev->attached) {
- struct module *driver_module = dev->driver->module;
-
- comedi_device_detach(dev);
- module_put(driver_module);
- }
- return 0;
- }
-
- if (copy_from_user(&it, arg, sizeof(it)))
- return -EFAULT;
-
- it.board_name[COMEDI_NAMELEN - 1] = 0;
-
- if (it.options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
- dev_warn(dev->class_dev,
- "comedi_config --init_data is deprecated\n");
- return -EINVAL;
- }
-
- if (dev->minor >= comedi_num_legacy_minors)
- /* don't re-use dynamically allocated comedi devices */
- return -EBUSY;
-
- /* This increments the driver module count on success. */
- return comedi_device_attach(dev, &it);
-}
-
-/*
- * COMEDI_BUFCONFIG ioctl
- * buffer configuration
- *
- * arg:
- * pointer to comedi_bufconfig structure
- *
- * reads:
- * comedi_bufconfig structure
- *
- * writes:
- * modified comedi_bufconfig structure
- */
-static int do_bufconfig_ioctl(struct comedi_device *dev,
- struct comedi_bufconfig __user *arg)
-{
- struct comedi_bufconfig bc;
- struct comedi_async *async;
- struct comedi_subdevice *s;
- int retval = 0;
-
- lockdep_assert_held(&dev->mutex);
- if (copy_from_user(&bc, arg, sizeof(bc)))
- return -EFAULT;
-
- if (bc.subdevice >= dev->n_subdevices)
- return -EINVAL;
-
- s = &dev->subdevices[bc.subdevice];
- async = s->async;
-
- if (!async) {
- dev_dbg(dev->class_dev,
- "subdevice does not have async capability\n");
- bc.size = 0;
- bc.maximum_size = 0;
- goto copyback;
- }
-
- if (bc.maximum_size) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- async->max_bufsize = bc.maximum_size;
- }
-
- if (bc.size) {
- retval = resize_async_buffer(dev, s, bc.size);
- if (retval < 0)
- return retval;
- }
-
- bc.size = async->prealloc_bufsz;
- bc.maximum_size = async->max_bufsize;
-
-copyback:
- if (copy_to_user(arg, &bc, sizeof(bc)))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * COMEDI_DEVINFO ioctl
- * device info
- *
- * arg:
- * pointer to comedi_devinfo structure
- *
- * reads:
- * nothing
- *
- * writes:
- * comedi_devinfo structure
- */
-static int do_devinfo_ioctl(struct comedi_device *dev,
- struct comedi_devinfo __user *arg,
- struct file *file)
-{
- struct comedi_subdevice *s;
- struct comedi_devinfo devinfo;
-
- lockdep_assert_held(&dev->mutex);
- memset(&devinfo, 0, sizeof(devinfo));
-
- /* fill devinfo structure */
- devinfo.version_code = COMEDI_VERSION_CODE;
- devinfo.n_subdevs = dev->n_subdevices;
- strscpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
- strscpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
-
- s = comedi_file_read_subdevice(file);
- if (s)
- devinfo.read_subdevice = s->index;
- else
- devinfo.read_subdevice = -1;
-
- s = comedi_file_write_subdevice(file);
- if (s)
- devinfo.write_subdevice = s->index;
- else
- devinfo.write_subdevice = -1;
-
- if (copy_to_user(arg, &devinfo, sizeof(devinfo)))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * COMEDI_SUBDINFO ioctl
- * subdevices info
- *
- * arg:
- * pointer to array of comedi_subdinfo structures
- *
- * reads:
- * nothing
- *
- * writes:
- * array of comedi_subdinfo structures
- */
-static int do_subdinfo_ioctl(struct comedi_device *dev,
- struct comedi_subdinfo __user *arg, void *file)
-{
- int ret, i;
- struct comedi_subdinfo *tmp, *us;
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- tmp = kcalloc(dev->n_subdevices, sizeof(*tmp), GFP_KERNEL);
- if (!tmp)
- return -ENOMEM;
-
- /* fill subdinfo structs */
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- us = tmp + i;
-
- us->type = s->type;
- us->n_chan = s->n_chan;
- us->subd_flags = s->subdev_flags;
- if (comedi_is_subdevice_running(s))
- us->subd_flags |= SDF_RUNNING;
-#define TIMER_nanosec 5 /* backwards compatibility */
- us->timer_type = TIMER_nanosec;
- us->len_chanlist = s->len_chanlist;
- us->maxdata = s->maxdata;
- if (s->range_table) {
- us->range_type =
- (i << 24) | (0 << 16) | (s->range_table->length);
- } else {
- us->range_type = 0; /* XXX */
- }
-
- if (s->busy)
- us->subd_flags |= SDF_BUSY;
- if (s->busy == file)
- us->subd_flags |= SDF_BUSY_OWNER;
- if (s->lock)
- us->subd_flags |= SDF_LOCKED;
- if (s->lock == file)
- us->subd_flags |= SDF_LOCK_OWNER;
- if (!s->maxdata && s->maxdata_list)
- us->subd_flags |= SDF_MAXDATA;
- if (s->range_table_list)
- us->subd_flags |= SDF_RANGETYPE;
- if (s->do_cmd)
- us->subd_flags |= SDF_CMD;
-
- if (s->insn_bits != &insn_inval)
- us->insn_bits_support = COMEDI_SUPPORTED;
- else
- us->insn_bits_support = COMEDI_UNSUPPORTED;
- }
-
- ret = copy_to_user(arg, tmp, dev->n_subdevices * sizeof(*tmp));
-
- kfree(tmp);
-
- return ret ? -EFAULT : 0;
-}
-
-/*
- * COMEDI_CHANINFO ioctl
- * subdevice channel info
- *
- * arg:
- * pointer to comedi_chaninfo structure
- *
- * reads:
- * comedi_chaninfo structure
- *
- * writes:
- * array of maxdata values to chaninfo->maxdata_list if requested
- * array of range table lengths to chaninfo->range_table_list if requested
- */
-static int do_chaninfo_ioctl(struct comedi_device *dev,
- struct comedi_chaninfo *it)
-{
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
-
- if (it->subdev >= dev->n_subdevices)
- return -EINVAL;
- s = &dev->subdevices[it->subdev];
-
- if (it->maxdata_list) {
- if (s->maxdata || !s->maxdata_list)
- return -EINVAL;
- if (copy_to_user(it->maxdata_list, s->maxdata_list,
- s->n_chan * sizeof(unsigned int)))
- return -EFAULT;
- }
-
- if (it->flaglist)
- return -EINVAL; /* flaglist not supported */
-
- if (it->rangelist) {
- int i;
-
- if (!s->range_table_list)
- return -EINVAL;
- for (i = 0; i < s->n_chan; i++) {
- int x;
-
- x = (dev->minor << 28) | (it->subdev << 24) | (i << 16) |
- (s->range_table_list[i]->length);
- if (put_user(x, it->rangelist + i))
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-/*
- * COMEDI_BUFINFO ioctl
- * buffer information
- *
- * arg:
- * pointer to comedi_bufinfo structure
- *
- * reads:
- * comedi_bufinfo structure
- *
- * writes:
- * modified comedi_bufinfo structure
- */
-static int do_bufinfo_ioctl(struct comedi_device *dev,
- struct comedi_bufinfo __user *arg, void *file)
-{
- struct comedi_bufinfo bi;
- struct comedi_subdevice *s;
- struct comedi_async *async;
- unsigned int runflags;
- int retval = 0;
- bool become_nonbusy = false;
-
- lockdep_assert_held(&dev->mutex);
- if (copy_from_user(&bi, arg, sizeof(bi)))
- return -EFAULT;
-
- if (bi.subdevice >= dev->n_subdevices)
- return -EINVAL;
-
- s = &dev->subdevices[bi.subdevice];
-
- async = s->async;
-
- if (!async || s->busy != file)
- return -EINVAL;
-
- runflags = comedi_get_subdevice_runflags(s);
- if (!(async->cmd.flags & CMDF_WRITE)) {
- /* command was set up in "read" direction */
- if (bi.bytes_read) {
- comedi_buf_read_alloc(s, bi.bytes_read);
- bi.bytes_read = comedi_buf_read_free(s, bi.bytes_read);
- }
- /*
- * If nothing left to read, and command has stopped, and
- * {"read" position not updated or command stopped normally},
- * then become non-busy.
- */
- if (comedi_buf_read_n_available(s) == 0 &&
- !comedi_is_runflags_running(runflags) &&
- (bi.bytes_read == 0 ||
- !comedi_is_runflags_in_error(runflags))) {
- become_nonbusy = true;
- if (comedi_is_runflags_in_error(runflags))
- retval = -EPIPE;
- }
- bi.bytes_written = 0;
- } else {
- /* command was set up in "write" direction */
- if (!comedi_is_runflags_running(runflags)) {
- bi.bytes_written = 0;
- become_nonbusy = true;
- if (comedi_is_runflags_in_error(runflags))
- retval = -EPIPE;
- } else if (bi.bytes_written) {
- comedi_buf_write_alloc(s, bi.bytes_written);
- bi.bytes_written =
- comedi_buf_write_free(s, bi.bytes_written);
- }
- bi.bytes_read = 0;
- }
-
- bi.buf_write_count = async->buf_write_count;
- bi.buf_write_ptr = async->buf_write_ptr;
- bi.buf_read_count = async->buf_read_count;
- bi.buf_read_ptr = async->buf_read_ptr;
-
- if (become_nonbusy)
- do_become_nonbusy(dev, s);
-
- if (retval)
- return retval;
-
- if (copy_to_user(arg, &bi, sizeof(bi)))
- return -EFAULT;
-
- return 0;
-}
-
-static int check_insn_config_length(struct comedi_insn *insn,
- unsigned int *data)
-{
- if (insn->n < 1)
- return -EINVAL;
-
- switch (data[0]) {
- case INSN_CONFIG_DIO_OUTPUT:
- case INSN_CONFIG_DIO_INPUT:
- case INSN_CONFIG_DISARM:
- case INSN_CONFIG_RESET:
- if (insn->n == 1)
- return 0;
- break;
- case INSN_CONFIG_ARM:
- case INSN_CONFIG_DIO_QUERY:
- case INSN_CONFIG_BLOCK_SIZE:
- case INSN_CONFIG_FILTER:
- case INSN_CONFIG_SERIAL_CLOCK:
- case INSN_CONFIG_BIDIRECTIONAL_DATA:
- case INSN_CONFIG_ALT_SOURCE:
- case INSN_CONFIG_SET_COUNTER_MODE:
- case INSN_CONFIG_8254_READ_STATUS:
- case INSN_CONFIG_SET_ROUTING:
- case INSN_CONFIG_GET_ROUTING:
- case INSN_CONFIG_GET_PWM_STATUS:
- case INSN_CONFIG_PWM_SET_PERIOD:
- case INSN_CONFIG_PWM_GET_PERIOD:
- if (insn->n == 2)
- return 0;
- break;
- case INSN_CONFIG_SET_GATE_SRC:
- case INSN_CONFIG_GET_GATE_SRC:
- case INSN_CONFIG_SET_CLOCK_SRC:
- case INSN_CONFIG_GET_CLOCK_SRC:
- case INSN_CONFIG_SET_OTHER_SRC:
- case INSN_CONFIG_GET_COUNTER_STATUS:
- case INSN_CONFIG_PWM_SET_H_BRIDGE:
- case INSN_CONFIG_PWM_GET_H_BRIDGE:
- case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
- if (insn->n == 3)
- return 0;
- break;
- case INSN_CONFIG_PWM_OUTPUT:
- case INSN_CONFIG_ANALOG_TRIG:
- case INSN_CONFIG_TIMER_1:
- if (insn->n == 5)
- return 0;
- break;
- case INSN_CONFIG_DIGITAL_TRIG:
- if (insn->n == 6)
- return 0;
- break;
- case INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS:
- if (insn->n >= 4)
- return 0;
- break;
- /*
- * by default we allow the insn since we don't have checks for
- * all possible cases yet
- */
- default:
- pr_warn("No check for data length of config insn id %i is implemented\n",
- data[0]);
- pr_warn("Add a check to %s in %s\n", __func__, __FILE__);
- pr_warn("Assuming n=%i is correct\n", insn->n);
- return 0;
- }
- return -EINVAL;
-}
-
-static int check_insn_device_config_length(struct comedi_insn *insn,
- unsigned int *data)
-{
- if (insn->n < 1)
- return -EINVAL;
-
- switch (data[0]) {
- case INSN_DEVICE_CONFIG_TEST_ROUTE:
- case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
- case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
- if (insn->n == 3)
- return 0;
- break;
- case INSN_DEVICE_CONFIG_GET_ROUTES:
- /*
- * Big enough for config_id and the length of the userland
- * memory buffer. Additional length should be in factors of 2
- * to communicate any returned route pairs (source,destination).
- */
- if (insn->n >= 2)
- return 0;
- break;
- }
- return -EINVAL;
-}
-
-/**
- * get_valid_routes() - Calls low-level driver get_valid_routes function to
- * either return a count of valid routes to user, or copy
- * of list of all valid device routes to buffer in
- * userspace.
- * @dev: comedi device pointer
- * @data: data from user insn call. The length of the data must be >= 2.
- * data[0] must contain the INSN_DEVICE_CONFIG config_id.
- * data[1](input) contains the number of _pairs_ for which memory is
- * allotted from the user. If the user specifies '0', then only
- * the number of pairs available is returned.
- * data[1](output) returns either the number of pairs available (if none
- * where requested) or the number of _pairs_ that are copied back
- * to the user.
- * data[2::2] returns each (source, destination) pair.
- *
- * Return: -EINVAL if low-level driver does not allocate and return routes as
- * expected. Returns 0 otherwise.
- */
-static int get_valid_routes(struct comedi_device *dev, unsigned int *data)
-{
- lockdep_assert_held(&dev->mutex);
- data[1] = dev->get_valid_routes(dev, data[1], data + 2);
- return 0;
-}
-
-static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
- unsigned int *data, void *file)
-{
- struct comedi_subdevice *s;
- int ret = 0;
- int i;
-
- lockdep_assert_held(&dev->mutex);
- if (insn->insn & INSN_MASK_SPECIAL) {
- /* a non-subdevice instruction */
-
- switch (insn->insn) {
- case INSN_GTOD:
- {
- struct timespec64 tv;
-
- if (insn->n != 2) {
- ret = -EINVAL;
- break;
- }
-
- ktime_get_real_ts64(&tv);
- /* unsigned data safe until 2106 */
- data[0] = (unsigned int)tv.tv_sec;
- data[1] = tv.tv_nsec / NSEC_PER_USEC;
- ret = 2;
-
- break;
- }
- case INSN_WAIT:
- if (insn->n != 1 || data[0] >= 100000) {
- ret = -EINVAL;
- break;
- }
- udelay(data[0] / 1000);
- ret = 1;
- break;
- case INSN_INTTRIG:
- if (insn->n != 1) {
- ret = -EINVAL;
- break;
- }
- if (insn->subdev >= dev->n_subdevices) {
- dev_dbg(dev->class_dev,
- "%d not usable subdevice\n",
- insn->subdev);
- ret = -EINVAL;
- break;
- }
- s = &dev->subdevices[insn->subdev];
- if (!s->async) {
- dev_dbg(dev->class_dev, "no async\n");
- ret = -EINVAL;
- break;
- }
- if (!s->async->inttrig) {
- dev_dbg(dev->class_dev, "no inttrig\n");
- ret = -EAGAIN;
- break;
- }
- ret = s->async->inttrig(dev, s, data[0]);
- if (ret >= 0)
- ret = 1;
- break;
- case INSN_DEVICE_CONFIG:
- ret = check_insn_device_config_length(insn, data);
- if (ret)
- break;
-
- if (data[0] == INSN_DEVICE_CONFIG_GET_ROUTES) {
- /*
- * data[1] should be the number of _pairs_ that
- * the memory can hold.
- */
- data[1] = (insn->n - 2) / 2;
- ret = get_valid_routes(dev, data);
- break;
- }
-
- /* other global device config instructions. */
- ret = dev->insn_device_config(dev, insn, data);
- break;
- default:
- dev_dbg(dev->class_dev, "invalid insn\n");
- ret = -EINVAL;
- break;
- }
- } else {
- /* a subdevice instruction */
- unsigned int maxdata;
-
- if (insn->subdev >= dev->n_subdevices) {
- dev_dbg(dev->class_dev, "subdevice %d out of range\n",
- insn->subdev);
- ret = -EINVAL;
- goto out;
- }
- s = &dev->subdevices[insn->subdev];
-
- if (s->type == COMEDI_SUBD_UNUSED) {
- dev_dbg(dev->class_dev, "%d not usable subdevice\n",
- insn->subdev);
- ret = -EIO;
- goto out;
- }
-
- /* are we locked? (ioctl lock) */
- if (s->lock && s->lock != file) {
- dev_dbg(dev->class_dev, "device locked\n");
- ret = -EACCES;
- goto out;
- }
-
- ret = comedi_check_chanlist(s, 1, &insn->chanspec);
- if (ret < 0) {
- ret = -EINVAL;
- dev_dbg(dev->class_dev, "bad chanspec\n");
- goto out;
- }
-
- if (s->busy) {
- ret = -EBUSY;
- goto out;
- }
- /* This looks arbitrary. It is. */
- s->busy = parse_insn;
- switch (insn->insn) {
- case INSN_READ:
- ret = s->insn_read(dev, s, insn, data);
- if (ret == -ETIMEDOUT) {
- dev_dbg(dev->class_dev,
- "subdevice %d read instruction timed out\n",
- s->index);
- }
- break;
- case INSN_WRITE:
- maxdata = s->maxdata_list
- ? s->maxdata_list[CR_CHAN(insn->chanspec)]
- : s->maxdata;
- for (i = 0; i < insn->n; ++i) {
- if (data[i] > maxdata) {
- ret = -EINVAL;
- dev_dbg(dev->class_dev,
- "bad data value(s)\n");
- break;
- }
- }
- if (ret == 0) {
- ret = s->insn_write(dev, s, insn, data);
- if (ret == -ETIMEDOUT) {
- dev_dbg(dev->class_dev,
- "subdevice %d write instruction timed out\n",
- s->index);
- }
- }
- break;
- case INSN_BITS:
- if (insn->n != 2) {
- ret = -EINVAL;
- } else {
- /*
- * Most drivers ignore the base channel in
- * insn->chanspec. Fix this here if
- * the subdevice has <= 32 channels.
- */
- unsigned int orig_mask = data[0];
- unsigned int shift = 0;
-
- if (s->n_chan <= 32) {
- shift = CR_CHAN(insn->chanspec);
- if (shift > 0) {
- insn->chanspec = 0;
- data[0] <<= shift;
- data[1] <<= shift;
- }
- }
- ret = s->insn_bits(dev, s, insn, data);
- data[0] = orig_mask;
- if (shift > 0)
- data[1] >>= shift;
- }
- break;
- case INSN_CONFIG:
- ret = check_insn_config_length(insn, data);
- if (ret)
- break;
- ret = s->insn_config(dev, s, insn, data);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- s->busy = NULL;
- }
-
-out:
- return ret;
-}
-
-/*
- * COMEDI_INSNLIST ioctl
- * synchronous instruction list
- *
- * arg:
- * pointer to comedi_insnlist structure
- *
- * reads:
- * comedi_insnlist structure
- * array of comedi_insn structures from insnlist->insns pointer
- * data (for writes) from insns[].data pointers
- *
- * writes:
- * data (for reads) to insns[].data pointers
- */
-/* arbitrary limits */
-#define MIN_SAMPLES 16
-#define MAX_SAMPLES 65536
-static int do_insnlist_ioctl(struct comedi_device *dev,
- struct comedi_insn *insns,
- unsigned int n_insns,
- void *file)
-{
- unsigned int *data = NULL;
- unsigned int max_n_data_required = MIN_SAMPLES;
- int i = 0;
- int ret = 0;
-
- lockdep_assert_held(&dev->mutex);
-
- /* Determine maximum memory needed for all instructions. */
- for (i = 0; i < n_insns; ++i) {
- if (insns[i].n > MAX_SAMPLES) {
- dev_dbg(dev->class_dev,
- "number of samples too large\n");
- ret = -EINVAL;
- goto error;
- }
- max_n_data_required = max(max_n_data_required, insns[i].n);
- }
-
- /* Allocate scratch space for all instruction data. */
- data = kmalloc_array(max_n_data_required, sizeof(unsigned int),
- GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto error;
- }
-
- for (i = 0; i < n_insns; ++i) {
- if (insns[i].insn & INSN_MASK_WRITE) {
- if (copy_from_user(data, insns[i].data,
- insns[i].n * sizeof(unsigned int))) {
- dev_dbg(dev->class_dev,
- "copy_from_user failed\n");
- ret = -EFAULT;
- goto error;
- }
- }
- ret = parse_insn(dev, insns + i, data, file);
- if (ret < 0)
- goto error;
- if (insns[i].insn & INSN_MASK_READ) {
- if (copy_to_user(insns[i].data, data,
- insns[i].n * sizeof(unsigned int))) {
- dev_dbg(dev->class_dev,
- "copy_to_user failed\n");
- ret = -EFAULT;
- goto error;
- }
- }
- if (need_resched())
- schedule();
- }
-
-error:
- kfree(data);
-
- if (ret < 0)
- return ret;
- return i;
-}
-
-/*
- * COMEDI_INSN ioctl
- * synchronous instruction
- *
- * arg:
- * pointer to comedi_insn structure
- *
- * reads:
- * comedi_insn structure
- * data (for writes) from insn->data pointer
- *
- * writes:
- * data (for reads) to insn->data pointer
- */
-static int do_insn_ioctl(struct comedi_device *dev,
- struct comedi_insn *insn, void *file)
-{
- unsigned int *data = NULL;
- unsigned int n_data = MIN_SAMPLES;
- int ret = 0;
-
- lockdep_assert_held(&dev->mutex);
-
- n_data = max(n_data, insn->n);
-
- /* This is where the behavior of insn and insnlist deviate. */
- if (insn->n > MAX_SAMPLES) {
- insn->n = MAX_SAMPLES;
- n_data = MAX_SAMPLES;
- }
-
- data = kmalloc_array(n_data, sizeof(unsigned int), GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto error;
- }
-
- if (insn->insn & INSN_MASK_WRITE) {
- if (copy_from_user(data,
- insn->data,
- insn->n * sizeof(unsigned int))) {
- ret = -EFAULT;
- goto error;
- }
- }
- ret = parse_insn(dev, insn, data, file);
- if (ret < 0)
- goto error;
- if (insn->insn & INSN_MASK_READ) {
- if (copy_to_user(insn->data,
- data,
- insn->n * sizeof(unsigned int))) {
- ret = -EFAULT;
- goto error;
- }
- }
- ret = insn->n;
-
-error:
- kfree(data);
-
- return ret;
-}
-
-static int __comedi_get_user_cmd(struct comedi_device *dev,
- struct comedi_cmd *cmd)
-{
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- if (cmd->subdev >= dev->n_subdevices) {
- dev_dbg(dev->class_dev, "%d no such subdevice\n", cmd->subdev);
- return -ENODEV;
- }
-
- s = &dev->subdevices[cmd->subdev];
-
- if (s->type == COMEDI_SUBD_UNUSED) {
- dev_dbg(dev->class_dev, "%d not valid subdevice\n",
- cmd->subdev);
- return -EIO;
- }
-
- if (!s->do_cmd || !s->do_cmdtest || !s->async) {
- dev_dbg(dev->class_dev,
- "subdevice %d does not support commands\n",
- cmd->subdev);
- return -EIO;
- }
-
- /* make sure channel/gain list isn't too long */
- if (cmd->chanlist_len > s->len_chanlist) {
- dev_dbg(dev->class_dev, "channel/gain list too long %d > %d\n",
- cmd->chanlist_len, s->len_chanlist);
- return -EINVAL;
- }
-
- /*
- * Set the CMDF_WRITE flag to the correct state if the subdevice
- * supports only "read" commands or only "write" commands.
- */
- switch (s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) {
- case SDF_CMD_READ:
- cmd->flags &= ~CMDF_WRITE;
- break;
- case SDF_CMD_WRITE:
- cmd->flags |= CMDF_WRITE;
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int __comedi_get_user_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int __user *user_chanlist,
- struct comedi_cmd *cmd)
-{
- unsigned int *chanlist;
- int ret;
-
- lockdep_assert_held(&dev->mutex);
- cmd->chanlist = NULL;
- chanlist = memdup_user(user_chanlist,
- cmd->chanlist_len * sizeof(unsigned int));
- if (IS_ERR(chanlist))
- return PTR_ERR(chanlist);
-
- /* make sure each element in channel/gain list is valid */
- ret = comedi_check_chanlist(s, cmd->chanlist_len, chanlist);
- if (ret < 0) {
- kfree(chanlist);
- return ret;
- }
-
- cmd->chanlist = chanlist;
-
- return 0;
-}
-
-/*
- * COMEDI_CMD ioctl
- * asynchronous acquisition command set-up
- *
- * arg:
- * pointer to comedi_cmd structure
- *
- * reads:
- * comedi_cmd structure
- * channel/range list from cmd->chanlist pointer
- *
- * writes:
- * possibly modified comedi_cmd structure (when -EAGAIN returned)
- */
-static int do_cmd_ioctl(struct comedi_device *dev,
- struct comedi_cmd *cmd, bool *copy, void *file)
-{
- struct comedi_subdevice *s;
- struct comedi_async *async;
- unsigned int __user *user_chanlist;
- int ret;
-
- lockdep_assert_held(&dev->mutex);
-
- /* do some simple cmd validation */
- ret = __comedi_get_user_cmd(dev, cmd);
- if (ret)
- return ret;
-
- /* save user's chanlist pointer so it can be restored later */
- user_chanlist = (unsigned int __user *)cmd->chanlist;
-
- s = &dev->subdevices[cmd->subdev];
- async = s->async;
-
- /* are we locked? (ioctl lock) */
- if (s->lock && s->lock != file) {
- dev_dbg(dev->class_dev, "subdevice locked\n");
- return -EACCES;
- }
-
- /* are we busy? */
- if (s->busy) {
- dev_dbg(dev->class_dev, "subdevice busy\n");
- return -EBUSY;
- }
-
- /* make sure channel/gain list isn't too short */
- if (cmd->chanlist_len < 1) {
- dev_dbg(dev->class_dev, "channel/gain list too short %u < 1\n",
- cmd->chanlist_len);
- return -EINVAL;
- }
-
- async->cmd = *cmd;
- async->cmd.data = NULL;
-
- /* load channel/gain list */
- ret = __comedi_get_user_chanlist(dev, s, user_chanlist, &async->cmd);
- if (ret)
- goto cleanup;
-
- ret = s->do_cmdtest(dev, s, &async->cmd);
-
- if (async->cmd.flags & CMDF_BOGUS || ret) {
- dev_dbg(dev->class_dev, "test returned %d\n", ret);
- *cmd = async->cmd;
- /* restore chanlist pointer before copying back */
- cmd->chanlist = (unsigned int __force *)user_chanlist;
- cmd->data = NULL;
- *copy = true;
- ret = -EAGAIN;
- goto cleanup;
- }
-
- if (!async->prealloc_bufsz) {
- ret = -ENOMEM;
- dev_dbg(dev->class_dev, "no buffer (?)\n");
- goto cleanup;
- }
-
- comedi_buf_reset(s);
-
- async->cb_mask = COMEDI_CB_BLOCK | COMEDI_CB_CANCEL_MASK;
- if (async->cmd.flags & CMDF_WAKE_EOS)
- async->cb_mask |= COMEDI_CB_EOS;
-
- comedi_update_subdevice_runflags(s, COMEDI_SRF_BUSY_MASK,
- COMEDI_SRF_RUNNING);
-
- /*
- * Set s->busy _after_ setting COMEDI_SRF_RUNNING flag to avoid
- * race with comedi_read() or comedi_write().
- */
- s->busy = file;
- ret = s->do_cmd(dev, s);
- if (ret == 0)
- return 0;
-
-cleanup:
- do_become_nonbusy(dev, s);
-
- return ret;
-}
-
-/*
- * COMEDI_CMDTEST ioctl
- * asynchronous acquisition command testing
- *
- * arg:
- * pointer to comedi_cmd structure
- *
- * reads:
- * comedi_cmd structure
- * channel/range list from cmd->chanlist pointer
- *
- * writes:
- * possibly modified comedi_cmd structure
- */
-static int do_cmdtest_ioctl(struct comedi_device *dev,
- struct comedi_cmd *cmd, bool *copy, void *file)
-{
- struct comedi_subdevice *s;
- unsigned int __user *user_chanlist;
- int ret;
-
- lockdep_assert_held(&dev->mutex);
-
- /* do some simple cmd validation */
- ret = __comedi_get_user_cmd(dev, cmd);
- if (ret)
- return ret;
-
- /* save user's chanlist pointer so it can be restored later */
- user_chanlist = (unsigned int __user *)cmd->chanlist;
-
- s = &dev->subdevices[cmd->subdev];
-
- /* user_chanlist can be NULL for COMEDI_CMDTEST ioctl */
- if (user_chanlist) {
- /* load channel/gain list */
- ret = __comedi_get_user_chanlist(dev, s, user_chanlist, cmd);
- if (ret)
- return ret;
- }
-
- ret = s->do_cmdtest(dev, s, cmd);
-
- kfree(cmd->chanlist); /* free kernel copy of user chanlist */
-
- /* restore chanlist pointer before copying back */
- cmd->chanlist = (unsigned int __force *)user_chanlist;
- *copy = true;
-
- return ret;
-}
-
-/*
- * COMEDI_LOCK ioctl
- * lock subdevice
- *
- * arg:
- * subdevice number
- *
- * reads:
- * nothing
- *
- * writes:
- * nothing
- */
-static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg,
- void *file)
-{
- int ret = 0;
- unsigned long flags;
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- if (arg >= dev->n_subdevices)
- return -EINVAL;
- s = &dev->subdevices[arg];
-
- spin_lock_irqsave(&s->spin_lock, flags);
- if (s->busy || s->lock)
- ret = -EBUSY;
- else
- s->lock = file;
- spin_unlock_irqrestore(&s->spin_lock, flags);
-
- return ret;
-}
-
-/*
- * COMEDI_UNLOCK ioctl
- * unlock subdevice
- *
- * arg:
- * subdevice number
- *
- * reads:
- * nothing
- *
- * writes:
- * nothing
- */
-static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg,
- void *file)
-{
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- if (arg >= dev->n_subdevices)
- return -EINVAL;
- s = &dev->subdevices[arg];
-
- if (s->busy)
- return -EBUSY;
-
- if (s->lock && s->lock != file)
- return -EACCES;
-
- if (s->lock == file)
- s->lock = NULL;
-
- return 0;
-}
-
-/*
- * COMEDI_CANCEL ioctl
- * cancel asynchronous acquisition
- *
- * arg:
- * subdevice number
- *
- * reads:
- * nothing
- *
- * writes:
- * nothing
- */
-static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg,
- void *file)
-{
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- if (arg >= dev->n_subdevices)
- return -EINVAL;
- s = &dev->subdevices[arg];
- if (!s->async)
- return -EINVAL;
-
- if (!s->busy)
- return 0;
-
- if (s->busy != file)
- return -EBUSY;
-
- return do_cancel(dev, s);
-}
-
-/*
- * COMEDI_POLL ioctl
- * instructs driver to synchronize buffers
- *
- * arg:
- * subdevice number
- *
- * reads:
- * nothing
- *
- * writes:
- * nothing
- */
-static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg,
- void *file)
-{
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->mutex);
- if (arg >= dev->n_subdevices)
- return -EINVAL;
- s = &dev->subdevices[arg];
-
- if (!s->busy)
- return 0;
-
- if (s->busy != file)
- return -EBUSY;
-
- if (s->poll)
- return s->poll(dev, s);
-
- return -EINVAL;
-}
-
-/*
- * COMEDI_SETRSUBD ioctl
- * sets the current "read" subdevice on a per-file basis
- *
- * arg:
- * subdevice number
- *
- * reads:
- * nothing
- *
- * writes:
- * nothing
- */
-static int do_setrsubd_ioctl(struct comedi_device *dev, unsigned long arg,
- struct file *file)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_subdevice *s_old, *s_new;
-
- lockdep_assert_held(&dev->mutex);
- if (arg >= dev->n_subdevices)
- return -EINVAL;
-
- s_new = &dev->subdevices[arg];
- s_old = comedi_file_read_subdevice(file);
- if (s_old == s_new)
- return 0; /* no change */
-
- if (!(s_new->subdev_flags & SDF_CMD_READ))
- return -EINVAL;
-
- /*
- * Check the file isn't still busy handling a "read" command on the
- * old subdevice (if any).
- */
- if (s_old && s_old->busy == file && s_old->async &&
- !(s_old->async->cmd.flags & CMDF_WRITE))
- return -EBUSY;
-
- WRITE_ONCE(cfp->read_subdev, s_new);
- return 0;
-}
-
-/*
- * COMEDI_SETWSUBD ioctl
- * sets the current "write" subdevice on a per-file basis
- *
- * arg:
- * subdevice number
- *
- * reads:
- * nothing
- *
- * writes:
- * nothing
- */
-static int do_setwsubd_ioctl(struct comedi_device *dev, unsigned long arg,
- struct file *file)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_subdevice *s_old, *s_new;
-
- lockdep_assert_held(&dev->mutex);
- if (arg >= dev->n_subdevices)
- return -EINVAL;
-
- s_new = &dev->subdevices[arg];
- s_old = comedi_file_write_subdevice(file);
- if (s_old == s_new)
- return 0; /* no change */
-
- if (!(s_new->subdev_flags & SDF_CMD_WRITE))
- return -EINVAL;
-
- /*
- * Check the file isn't still busy handling a "write" command on the
- * old subdevice (if any).
- */
- if (s_old && s_old->busy == file && s_old->async &&
- (s_old->async->cmd.flags & CMDF_WRITE))
- return -EBUSY;
-
- WRITE_ONCE(cfp->write_subdev, s_new);
- return 0;
-}
-
-static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- unsigned int minor = iminor(file_inode(file));
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- int rc;
-
- mutex_lock(&dev->mutex);
-
- /*
- * Device config is special, because it must work on
- * an unconfigured device.
- */
- if (cmd == COMEDI_DEVCONFIG) {
- if (minor >= COMEDI_NUM_BOARD_MINORS) {
- /* Device config not appropriate on non-board minors. */
- rc = -ENOTTY;
- goto done;
- }
- rc = do_devconfig_ioctl(dev,
- (struct comedi_devconfig __user *)arg);
- if (rc == 0) {
- if (arg == 0 &&
- dev->minor >= comedi_num_legacy_minors) {
- /*
- * Successfully unconfigured a dynamically
- * allocated device. Try and remove it.
- */
- if (comedi_clear_board_dev(dev)) {
- mutex_unlock(&dev->mutex);
- comedi_free_board_dev(dev);
- return rc;
- }
- }
- }
- goto done;
- }
-
- if (!dev->attached) {
- dev_dbg(dev->class_dev, "no driver attached\n");
- rc = -ENODEV;
- goto done;
- }
-
- switch (cmd) {
- case COMEDI_BUFCONFIG:
- rc = do_bufconfig_ioctl(dev,
- (struct comedi_bufconfig __user *)arg);
- break;
- case COMEDI_DEVINFO:
- rc = do_devinfo_ioctl(dev, (struct comedi_devinfo __user *)arg,
- file);
- break;
- case COMEDI_SUBDINFO:
- rc = do_subdinfo_ioctl(dev,
- (struct comedi_subdinfo __user *)arg,
- file);
- break;
- case COMEDI_CHANINFO: {
- struct comedi_chaninfo it;
-
- if (copy_from_user(&it, (void __user *)arg, sizeof(it)))
- rc = -EFAULT;
- else
- rc = do_chaninfo_ioctl(dev, &it);
- break;
- }
- case COMEDI_RANGEINFO: {
- struct comedi_rangeinfo it;
-
- if (copy_from_user(&it, (void __user *)arg, sizeof(it)))
- rc = -EFAULT;
- else
- rc = do_rangeinfo_ioctl(dev, &it);
- break;
- }
- case COMEDI_BUFINFO:
- rc = do_bufinfo_ioctl(dev,
- (struct comedi_bufinfo __user *)arg,
- file);
- break;
- case COMEDI_LOCK:
- rc = do_lock_ioctl(dev, arg, file);
- break;
- case COMEDI_UNLOCK:
- rc = do_unlock_ioctl(dev, arg, file);
- break;
- case COMEDI_CANCEL:
- rc = do_cancel_ioctl(dev, arg, file);
- break;
- case COMEDI_CMD: {
- struct comedi_cmd cmd;
- bool copy = false;
-
- if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd))) {
- rc = -EFAULT;
- break;
- }
- rc = do_cmd_ioctl(dev, &cmd, &copy, file);
- if (copy && copy_to_user((void __user *)arg, &cmd, sizeof(cmd)))
- rc = -EFAULT;
- break;
- }
- case COMEDI_CMDTEST: {
- struct comedi_cmd cmd;
- bool copy = false;
-
- if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd))) {
- rc = -EFAULT;
- break;
- }
- rc = do_cmdtest_ioctl(dev, &cmd, &copy, file);
- if (copy && copy_to_user((void __user *)arg, &cmd, sizeof(cmd)))
- rc = -EFAULT;
- break;
- }
- case COMEDI_INSNLIST: {
- struct comedi_insnlist insnlist;
- struct comedi_insn *insns = NULL;
-
- if (copy_from_user(&insnlist, (void __user *)arg,
- sizeof(insnlist))) {
- rc = -EFAULT;
- break;
- }
- insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL);
- if (!insns) {
- rc = -ENOMEM;
- break;
- }
- if (copy_from_user(insns, insnlist.insns,
- sizeof(*insns) * insnlist.n_insns)) {
- rc = -EFAULT;
- kfree(insns);
- break;
- }
- rc = do_insnlist_ioctl(dev, insns, insnlist.n_insns, file);
- kfree(insns);
- break;
- }
- case COMEDI_INSN: {
- struct comedi_insn insn;
-
- if (copy_from_user(&insn, (void __user *)arg, sizeof(insn)))
- rc = -EFAULT;
- else
- rc = do_insn_ioctl(dev, &insn, file);
- break;
- }
- case COMEDI_POLL:
- rc = do_poll_ioctl(dev, arg, file);
- break;
- case COMEDI_SETRSUBD:
- rc = do_setrsubd_ioctl(dev, arg, file);
- break;
- case COMEDI_SETWSUBD:
- rc = do_setwsubd_ioctl(dev, arg, file);
- break;
- default:
- rc = -ENOTTY;
- break;
- }
-
-done:
- mutex_unlock(&dev->mutex);
- return rc;
-}
-
-static void comedi_vm_open(struct vm_area_struct *area)
-{
- struct comedi_buf_map *bm;
-
- bm = area->vm_private_data;
- comedi_buf_map_get(bm);
-}
-
-static void comedi_vm_close(struct vm_area_struct *area)
-{
- struct comedi_buf_map *bm;
-
- bm = area->vm_private_data;
- comedi_buf_map_put(bm);
-}
-
-static int comedi_vm_access(struct vm_area_struct *vma, unsigned long addr,
- void *buf, int len, int write)
-{
- struct comedi_buf_map *bm = vma->vm_private_data;
- unsigned long offset =
- addr - vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT);
-
- if (len < 0)
- return -EINVAL;
- if (len > vma->vm_end - addr)
- len = vma->vm_end - addr;
- return comedi_buf_map_access(bm, offset, buf, len, write);
-}
-
-static const struct vm_operations_struct comedi_vm_ops = {
- .open = comedi_vm_open,
- .close = comedi_vm_close,
- .access = comedi_vm_access,
-};
-
-static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi_subdevice *s;
- struct comedi_async *async;
- struct comedi_buf_map *bm = NULL;
- struct comedi_buf_page *buf;
- unsigned long start = vma->vm_start;
- unsigned long size;
- int n_pages;
- int i;
- int retval = 0;
-
- /*
- * 'trylock' avoids circular dependency with current->mm->mmap_lock
- * and down-reading &dev->attach_lock should normally succeed without
- * contention unless the device is in the process of being attached
- * or detached.
- */
- if (!down_read_trylock(&dev->attach_lock))
- return -EAGAIN;
-
- if (!dev->attached) {
- dev_dbg(dev->class_dev, "no driver attached\n");
- retval = -ENODEV;
- goto done;
- }
-
- if (vma->vm_flags & VM_WRITE)
- s = comedi_file_write_subdevice(file);
- else
- s = comedi_file_read_subdevice(file);
- if (!s) {
- retval = -EINVAL;
- goto done;
- }
-
- async = s->async;
- if (!async) {
- retval = -EINVAL;
- goto done;
- }
-
- if (vma->vm_pgoff != 0) {
- dev_dbg(dev->class_dev, "mmap() offset must be 0.\n");
- retval = -EINVAL;
- goto done;
- }
-
- size = vma->vm_end - vma->vm_start;
- if (size > async->prealloc_bufsz) {
- retval = -EFAULT;
- goto done;
- }
- if (offset_in_page(size)) {
- retval = -EFAULT;
- goto done;
- }
-
- n_pages = vma_pages(vma);
-
- /* get reference to current buf map (if any) */
- bm = comedi_buf_map_from_subdev_get(s);
- if (!bm || n_pages > bm->n_pages) {
- retval = -EINVAL;
- goto done;
- }
- if (bm->dma_dir != DMA_NONE) {
- /*
- * DMA buffer was allocated as a single block.
- * Address is in page_list[0].
- */
- buf = &bm->page_list[0];
- retval = dma_mmap_coherent(bm->dma_hw_dev, vma, buf->virt_addr,
- buf->dma_addr, n_pages * PAGE_SIZE);
- } else {
- for (i = 0; i < n_pages; ++i) {
- unsigned long pfn;
-
- buf = &bm->page_list[i];
- pfn = page_to_pfn(virt_to_page(buf->virt_addr));
- retval = remap_pfn_range(vma, start, pfn, PAGE_SIZE,
- PAGE_SHARED);
- if (retval)
- break;
-
- start += PAGE_SIZE;
- }
- }
-
- if (retval == 0) {
- vma->vm_ops = &comedi_vm_ops;
- vma->vm_private_data = bm;
-
- vma->vm_ops->open(vma);
- }
-
-done:
- up_read(&dev->attach_lock);
- comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */
- return retval;
-}
-
-static __poll_t comedi_poll(struct file *file, poll_table *wait)
-{
- __poll_t mask = 0;
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi_subdevice *s, *s_read;
-
- down_read(&dev->attach_lock);
-
- if (!dev->attached) {
- dev_dbg(dev->class_dev, "no driver attached\n");
- goto done;
- }
-
- s = comedi_file_read_subdevice(file);
- s_read = s;
- if (s && s->async) {
- poll_wait(file, &s->async->wait_head, wait);
- if (s->busy != file || !comedi_is_subdevice_running(s) ||
- (s->async->cmd.flags & CMDF_WRITE) ||
- comedi_buf_read_n_available(s) > 0)
- mask |= EPOLLIN | EPOLLRDNORM;
- }
-
- s = comedi_file_write_subdevice(file);
- if (s && s->async) {
- unsigned int bps = comedi_bytes_per_sample(s);
-
- if (s != s_read)
- poll_wait(file, &s->async->wait_head, wait);
- if (s->busy != file || !comedi_is_subdevice_running(s) ||
- !(s->async->cmd.flags & CMDF_WRITE) ||
- comedi_buf_write_n_available(s) >= bps)
- mask |= EPOLLOUT | EPOLLWRNORM;
- }
-
-done:
- up_read(&dev->attach_lock);
- return mask;
-}
-
-static ssize_t comedi_write(struct file *file, const char __user *buf,
- size_t nbytes, loff_t *offset)
-{
- struct comedi_subdevice *s;
- struct comedi_async *async;
- unsigned int n, m;
- ssize_t count = 0;
- int retval = 0;
- DECLARE_WAITQUEUE(wait, current);
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- bool become_nonbusy = false;
- bool attach_locked;
- unsigned int old_detach_count;
-
- /* Protect against device detachment during operation. */
- down_read(&dev->attach_lock);
- attach_locked = true;
- old_detach_count = dev->detach_count;
-
- if (!dev->attached) {
- dev_dbg(dev->class_dev, "no driver attached\n");
- retval = -ENODEV;
- goto out;
- }
-
- s = comedi_file_write_subdevice(file);
- if (!s || !s->async) {
- retval = -EIO;
- goto out;
- }
-
- async = s->async;
- if (s->busy != file || !(async->cmd.flags & CMDF_WRITE)) {
- retval = -EINVAL;
- goto out;
- }
-
- add_wait_queue(&async->wait_head, &wait);
- while (count == 0 && !retval) {
- unsigned int runflags;
- unsigned int wp, n1, n2;
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- runflags = comedi_get_subdevice_runflags(s);
- if (!comedi_is_runflags_running(runflags)) {
- if (comedi_is_runflags_in_error(runflags))
- retval = -EPIPE;
- if (retval || nbytes)
- become_nonbusy = true;
- break;
- }
- if (nbytes == 0)
- break;
-
- /* Allocate all free buffer space. */
- comedi_buf_write_alloc(s, async->prealloc_bufsz);
- m = comedi_buf_write_n_allocated(s);
- n = min_t(size_t, m, nbytes);
-
- if (n == 0) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- break;
- }
- schedule();
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- if (s->busy != file ||
- !(async->cmd.flags & CMDF_WRITE)) {
- retval = -EINVAL;
- break;
- }
- continue;
- }
-
- set_current_state(TASK_RUNNING);
- wp = async->buf_write_ptr;
- n1 = min(n, async->prealloc_bufsz - wp);
- n2 = n - n1;
- m = copy_from_user(async->prealloc_buf + wp, buf, n1);
- if (m)
- m += n2;
- else if (n2)
- m = copy_from_user(async->prealloc_buf, buf + n1, n2);
- if (m) {
- n -= m;
- retval = -EFAULT;
- }
- comedi_buf_write_free(s, n);
-
- count += n;
- nbytes -= n;
-
- buf += n;
- }
- remove_wait_queue(&async->wait_head, &wait);
- set_current_state(TASK_RUNNING);
- if (become_nonbusy && count == 0) {
- struct comedi_subdevice *new_s;
-
- /*
- * To avoid deadlock, cannot acquire dev->mutex
- * while dev->attach_lock is held.
- */
- up_read(&dev->attach_lock);
- attach_locked = false;
- mutex_lock(&dev->mutex);
- /*
- * Check device hasn't become detached behind our back.
- * Checking dev->detach_count is unchanged ought to be
- * sufficient (unless there have been 2**32 detaches in the
- * meantime!), but check the subdevice pointer as well just in
- * case.
- *
- * Also check the subdevice is still in a suitable state to
- * become non-busy in case it changed behind our back.
- */
- new_s = comedi_file_write_subdevice(file);
- if (dev->attached && old_detach_count == dev->detach_count &&
- s == new_s && new_s->async == async && s->busy == file &&
- (async->cmd.flags & CMDF_WRITE) &&
- !comedi_is_subdevice_running(s))
- do_become_nonbusy(dev, s);
- mutex_unlock(&dev->mutex);
- }
-out:
- if (attach_locked)
- up_read(&dev->attach_lock);
-
- return count ? count : retval;
-}
-
-static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
- loff_t *offset)
-{
- struct comedi_subdevice *s;
- struct comedi_async *async;
- unsigned int n, m;
- ssize_t count = 0;
- int retval = 0;
- DECLARE_WAITQUEUE(wait, current);
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- unsigned int old_detach_count;
- bool become_nonbusy = false;
- bool attach_locked;
-
- /* Protect against device detachment during operation. */
- down_read(&dev->attach_lock);
- attach_locked = true;
- old_detach_count = dev->detach_count;
-
- if (!dev->attached) {
- dev_dbg(dev->class_dev, "no driver attached\n");
- retval = -ENODEV;
- goto out;
- }
-
- s = comedi_file_read_subdevice(file);
- if (!s || !s->async) {
- retval = -EIO;
- goto out;
- }
-
- async = s->async;
- if (s->busy != file || (async->cmd.flags & CMDF_WRITE)) {
- retval = -EINVAL;
- goto out;
- }
-
- add_wait_queue(&async->wait_head, &wait);
- while (count == 0 && !retval) {
- unsigned int rp, n1, n2;
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- m = comedi_buf_read_n_available(s);
- n = min_t(size_t, m, nbytes);
-
- if (n == 0) {
- unsigned int runflags =
- comedi_get_subdevice_runflags(s);
-
- if (!comedi_is_runflags_running(runflags)) {
- if (comedi_is_runflags_in_error(runflags))
- retval = -EPIPE;
- if (retval || nbytes)
- become_nonbusy = true;
- break;
- }
- if (nbytes == 0)
- break;
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- break;
- }
- schedule();
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- if (s->busy != file ||
- (async->cmd.flags & CMDF_WRITE)) {
- retval = -EINVAL;
- break;
- }
- continue;
- }
-
- set_current_state(TASK_RUNNING);
- rp = async->buf_read_ptr;
- n1 = min(n, async->prealloc_bufsz - rp);
- n2 = n - n1;
- m = copy_to_user(buf, async->prealloc_buf + rp, n1);
- if (m)
- m += n2;
- else if (n2)
- m = copy_to_user(buf + n1, async->prealloc_buf, n2);
- if (m) {
- n -= m;
- retval = -EFAULT;
- }
-
- comedi_buf_read_alloc(s, n);
- comedi_buf_read_free(s, n);
-
- count += n;
- nbytes -= n;
-
- buf += n;
- }
- remove_wait_queue(&async->wait_head, &wait);
- set_current_state(TASK_RUNNING);
- if (become_nonbusy && count == 0) {
- struct comedi_subdevice *new_s;
-
- /*
- * To avoid deadlock, cannot acquire dev->mutex
- * while dev->attach_lock is held.
- */
- up_read(&dev->attach_lock);
- attach_locked = false;
- mutex_lock(&dev->mutex);
- /*
- * Check device hasn't become detached behind our back.
- * Checking dev->detach_count is unchanged ought to be
- * sufficient (unless there have been 2**32 detaches in the
- * meantime!), but check the subdevice pointer as well just in
- * case.
- *
- * Also check the subdevice is still in a suitable state to
- * become non-busy in case it changed behind our back.
- */
- new_s = comedi_file_read_subdevice(file);
- if (dev->attached && old_detach_count == dev->detach_count &&
- s == new_s && new_s->async == async && s->busy == file &&
- !(async->cmd.flags & CMDF_WRITE) &&
- !comedi_is_subdevice_running(s) &&
- comedi_buf_read_n_available(s) == 0)
- do_become_nonbusy(dev, s);
- mutex_unlock(&dev->mutex);
- }
-out:
- if (attach_locked)
- up_read(&dev->attach_lock);
-
- return count ? count : retval;
-}
-
-static int comedi_open(struct inode *inode, struct file *file)
-{
- const unsigned int minor = iminor(inode);
- struct comedi_file *cfp;
- struct comedi_device *dev = comedi_dev_get_from_minor(minor);
- int rc;
-
- if (!dev) {
- pr_debug("invalid minor number\n");
- return -ENODEV;
- }
-
- cfp = kzalloc(sizeof(*cfp), GFP_KERNEL);
- if (!cfp) {
- comedi_dev_put(dev);
- return -ENOMEM;
- }
-
- cfp->dev = dev;
-
- mutex_lock(&dev->mutex);
- if (!dev->attached && !capable(CAP_SYS_ADMIN)) {
- dev_dbg(dev->class_dev, "not attached and not CAP_SYS_ADMIN\n");
- rc = -ENODEV;
- goto out;
- }
- if (dev->attached && dev->use_count == 0) {
- if (!try_module_get(dev->driver->module)) {
- rc = -ENXIO;
- goto out;
- }
- if (dev->open) {
- rc = dev->open(dev);
- if (rc < 0) {
- module_put(dev->driver->module);
- goto out;
- }
- }
- }
-
- dev->use_count++;
- file->private_data = cfp;
- comedi_file_reset(file);
- rc = 0;
-
-out:
- mutex_unlock(&dev->mutex);
- if (rc) {
- comedi_dev_put(dev);
- kfree(cfp);
- }
- return rc;
-}
-
-static int comedi_fasync(int fd, struct file *file, int on)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
-
- return fasync_helper(fd, file, on, &dev->async_queue);
-}
-
-static int comedi_close(struct inode *inode, struct file *file)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi_subdevice *s = NULL;
- int i;
-
- mutex_lock(&dev->mutex);
-
- if (dev->subdevices) {
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
-
- if (s->busy == file)
- do_cancel(dev, s);
- if (s->lock == file)
- s->lock = NULL;
- }
- }
- if (dev->attached && dev->use_count == 1) {
- if (dev->close)
- dev->close(dev);
- module_put(dev->driver->module);
- }
-
- dev->use_count--;
-
- mutex_unlock(&dev->mutex);
- comedi_dev_put(dev);
- kfree(cfp);
-
- return 0;
-}
-
-#ifdef CONFIG_COMPAT
-
-#define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
-#define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
-/*
- * N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
- * It's too late to change it now, but it only affects the command number.
- */
-#define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
-/*
- * N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
- * It's too late to change it now, but it only affects the command number.
- */
-#define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
-#define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
-#define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
-
-struct comedi32_chaninfo_struct {
- unsigned int subdev;
- compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */
- compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
- compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */
- unsigned int unused[4];
-};
-
-struct comedi32_rangeinfo_struct {
- unsigned int range_type;
- compat_uptr_t range_ptr; /* 32-bit 'void *' */
-};
-
-struct comedi32_cmd_struct {
- unsigned int subdev;
- unsigned int flags;
- unsigned int start_src;
- unsigned int start_arg;
- unsigned int scan_begin_src;
- unsigned int scan_begin_arg;
- unsigned int convert_src;
- unsigned int convert_arg;
- unsigned int scan_end_src;
- unsigned int scan_end_arg;
- unsigned int stop_src;
- unsigned int stop_arg;
- compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
- unsigned int chanlist_len;
- compat_uptr_t data; /* 32-bit 'short *' */
- unsigned int data_len;
-};
-
-struct comedi32_insn_struct {
- unsigned int insn;
- unsigned int n;
- compat_uptr_t data; /* 32-bit 'unsigned int *' */
- unsigned int subdev;
- unsigned int chanspec;
- unsigned int unused[3];
-};
-
-struct comedi32_insnlist_struct {
- unsigned int n_insns;
- compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */
-};
-
-/* Handle 32-bit COMEDI_CHANINFO ioctl. */
-static int compat_chaninfo(struct file *file, unsigned long arg)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi32_chaninfo_struct chaninfo32;
- struct comedi_chaninfo chaninfo;
- int err;
-
- if (copy_from_user(&chaninfo32, compat_ptr(arg), sizeof(chaninfo32)))
- return -EFAULT;
-
- memset(&chaninfo, 0, sizeof(chaninfo));
- chaninfo.subdev = chaninfo32.subdev;
- chaninfo.maxdata_list = compat_ptr(chaninfo32.maxdata_list);
- chaninfo.flaglist = compat_ptr(chaninfo32.flaglist);
- chaninfo.rangelist = compat_ptr(chaninfo32.rangelist);
-
- mutex_lock(&dev->mutex);
- err = do_chaninfo_ioctl(dev, &chaninfo);
- mutex_unlock(&dev->mutex);
- return err;
-}
-
-/* Handle 32-bit COMEDI_RANGEINFO ioctl. */
-static int compat_rangeinfo(struct file *file, unsigned long arg)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi32_rangeinfo_struct rangeinfo32;
- struct comedi_rangeinfo rangeinfo;
- int err;
-
- if (copy_from_user(&rangeinfo32, compat_ptr(arg), sizeof(rangeinfo32)))
- return -EFAULT;
- memset(&rangeinfo, 0, sizeof(rangeinfo));
- rangeinfo.range_type = rangeinfo32.range_type;
- rangeinfo.range_ptr = compat_ptr(rangeinfo32.range_ptr);
-
- mutex_lock(&dev->mutex);
- err = do_rangeinfo_ioctl(dev, &rangeinfo);
- mutex_unlock(&dev->mutex);
- return err;
-}
-
-/* Copy 32-bit cmd structure to native cmd structure. */
-static int get_compat_cmd(struct comedi_cmd *cmd,
- struct comedi32_cmd_struct __user *cmd32)
-{
- struct comedi32_cmd_struct v32;
-
- if (copy_from_user(&v32, cmd32, sizeof(v32)))
- return -EFAULT;
-
- cmd->subdev = v32.subdev;
- cmd->flags = v32.flags;
- cmd->start_src = v32.start_src;
- cmd->start_arg = v32.start_arg;
- cmd->scan_begin_src = v32.scan_begin_src;
- cmd->scan_begin_arg = v32.scan_begin_arg;
- cmd->convert_src = v32.convert_src;
- cmd->convert_arg = v32.convert_arg;
- cmd->scan_end_src = v32.scan_end_src;
- cmd->scan_end_arg = v32.scan_end_arg;
- cmd->stop_src = v32.stop_src;
- cmd->stop_arg = v32.stop_arg;
- cmd->chanlist = (unsigned int __force *)compat_ptr(v32.chanlist);
- cmd->chanlist_len = v32.chanlist_len;
- cmd->data = compat_ptr(v32.data);
- cmd->data_len = v32.data_len;
- return 0;
-}
-
-/* Copy native cmd structure to 32-bit cmd structure. */
-static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32,
- struct comedi_cmd *cmd)
-{
- struct comedi32_cmd_struct v32;
-
- memset(&v32, 0, sizeof(v32));
- v32.subdev = cmd->subdev;
- v32.flags = cmd->flags;
- v32.start_src = cmd->start_src;
- v32.start_arg = cmd->start_arg;
- v32.scan_begin_src = cmd->scan_begin_src;
- v32.scan_begin_arg = cmd->scan_begin_arg;
- v32.convert_src = cmd->convert_src;
- v32.convert_arg = cmd->convert_arg;
- v32.scan_end_src = cmd->scan_end_src;
- v32.scan_end_arg = cmd->scan_end_arg;
- v32.stop_src = cmd->stop_src;
- v32.stop_arg = cmd->stop_arg;
- /* Assume chanlist pointer is unchanged. */
- v32.chanlist = ptr_to_compat((unsigned int __user *)cmd->chanlist);
- v32.chanlist_len = cmd->chanlist_len;
- v32.data = ptr_to_compat(cmd->data);
- v32.data_len = cmd->data_len;
- if (copy_to_user(cmd32, &v32, sizeof(v32)))
- return -EFAULT;
- return 0;
-}
-
-/* Handle 32-bit COMEDI_CMD ioctl. */
-static int compat_cmd(struct file *file, unsigned long arg)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi_cmd cmd;
- bool copy = false;
- int rc, err;
-
- rc = get_compat_cmd(&cmd, compat_ptr(arg));
- if (rc)
- return rc;
-
- mutex_lock(&dev->mutex);
- rc = do_cmd_ioctl(dev, &cmd, &copy, file);
- mutex_unlock(&dev->mutex);
- if (copy) {
- /* Special case: copy cmd back to user. */
- err = put_compat_cmd(compat_ptr(arg), &cmd);
- if (err)
- rc = err;
- }
- return rc;
-}
-
-/* Handle 32-bit COMEDI_CMDTEST ioctl. */
-static int compat_cmdtest(struct file *file, unsigned long arg)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi_cmd cmd;
- bool copy = false;
- int rc, err;
-
- rc = get_compat_cmd(&cmd, compat_ptr(arg));
- if (rc)
- return rc;
-
- mutex_lock(&dev->mutex);
- rc = do_cmdtest_ioctl(dev, &cmd, &copy, file);
- mutex_unlock(&dev->mutex);
- if (copy) {
- err = put_compat_cmd(compat_ptr(arg), &cmd);
- if (err)
- rc = err;
- }
- return rc;
-}
-
-/* Copy 32-bit insn structure to native insn structure. */
-static int get_compat_insn(struct comedi_insn *insn,
- struct comedi32_insn_struct __user *insn32)
-{
- struct comedi32_insn_struct v32;
-
- /* Copy insn structure. Ignore the unused members. */
- if (copy_from_user(&v32, insn32, sizeof(v32)))
- return -EFAULT;
- memset(insn, 0, sizeof(*insn));
- insn->insn = v32.insn;
- insn->n = v32.n;
- insn->data = compat_ptr(v32.data);
- insn->subdev = v32.subdev;
- insn->chanspec = v32.chanspec;
- return 0;
-}
-
-/* Handle 32-bit COMEDI_INSNLIST ioctl. */
-static int compat_insnlist(struct file *file, unsigned long arg)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi32_insnlist_struct insnlist32;
- struct comedi32_insn_struct __user *insn32;
- struct comedi_insn *insns;
- unsigned int n;
- int rc;
-
- if (copy_from_user(&insnlist32, compat_ptr(arg), sizeof(insnlist32)))
- return -EFAULT;
-
- insns = kcalloc(insnlist32.n_insns, sizeof(*insns), GFP_KERNEL);
- if (!insns)
- return -ENOMEM;
-
- /* Copy insn structures. */
- insn32 = compat_ptr(insnlist32.insns);
- for (n = 0; n < insnlist32.n_insns; n++) {
- rc = get_compat_insn(insns + n, insn32 + n);
- if (rc) {
- kfree(insns);
- return rc;
- }
- }
-
- mutex_lock(&dev->mutex);
- rc = do_insnlist_ioctl(dev, insns, insnlist32.n_insns, file);
- mutex_unlock(&dev->mutex);
- return rc;
-}
-
-/* Handle 32-bit COMEDI_INSN ioctl. */
-static int compat_insn(struct file *file, unsigned long arg)
-{
- struct comedi_file *cfp = file->private_data;
- struct comedi_device *dev = cfp->dev;
- struct comedi_insn insn;
- int rc;
-
- rc = get_compat_insn(&insn, (void __user *)arg);
- if (rc)
- return rc;
-
- mutex_lock(&dev->mutex);
- rc = do_insn_ioctl(dev, &insn, file);
- mutex_unlock(&dev->mutex);
- return rc;
-}
-
-/*
- * compat_ioctl file operation.
- *
- * Returns -ENOIOCTLCMD for unrecognised ioctl codes.
- */
-static long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int rc;
-
- switch (cmd) {
- case COMEDI_DEVCONFIG:
- case COMEDI_DEVINFO:
- case COMEDI_SUBDINFO:
- case COMEDI_BUFCONFIG:
- case COMEDI_BUFINFO:
- /* Just need to translate the pointer argument. */
- arg = (unsigned long)compat_ptr(arg);
- rc = comedi_unlocked_ioctl(file, cmd, arg);
- break;
- case COMEDI_LOCK:
- case COMEDI_UNLOCK:
- case COMEDI_CANCEL:
- case COMEDI_POLL:
- case COMEDI_SETRSUBD:
- case COMEDI_SETWSUBD:
- /* No translation needed. */
- rc = comedi_unlocked_ioctl(file, cmd, arg);
- break;
- case COMEDI32_CHANINFO:
- rc = compat_chaninfo(file, arg);
- break;
- case COMEDI32_RANGEINFO:
- rc = compat_rangeinfo(file, arg);
- break;
- case COMEDI32_CMD:
- rc = compat_cmd(file, arg);
- break;
- case COMEDI32_CMDTEST:
- rc = compat_cmdtest(file, arg);
- break;
- case COMEDI32_INSNLIST:
- rc = compat_insnlist(file, arg);
- break;
- case COMEDI32_INSN:
- rc = compat_insn(file, arg);
- break;
- default:
- rc = -ENOIOCTLCMD;
- break;
- }
- return rc;
-}
-#else
-#define comedi_compat_ioctl NULL
-#endif
-
-static const struct file_operations comedi_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = comedi_unlocked_ioctl,
- .compat_ioctl = comedi_compat_ioctl,
- .open = comedi_open,
- .release = comedi_close,
- .read = comedi_read,
- .write = comedi_write,
- .mmap = comedi_mmap,
- .poll = comedi_poll,
- .fasync = comedi_fasync,
- .llseek = noop_llseek,
-};
-
-/**
- * comedi_event() - Handle events for asynchronous COMEDI command
- * @dev: COMEDI device.
- * @s: COMEDI subdevice.
- * Context: in_interrupt() (usually), @s->spin_lock spin-lock not held.
- *
- * If an asynchronous COMEDI command is active on the subdevice, process
- * any %COMEDI_CB_... event flags that have been set, usually by an
- * interrupt handler. These may change the run state of the asynchronous
- * command, wake a task, and/or send a %SIGIO signal.
- */
-void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- unsigned int events;
- int si_code = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&s->spin_lock, flags);
-
- events = async->events;
- async->events = 0;
- if (!__comedi_is_subdevice_running(s)) {
- spin_unlock_irqrestore(&s->spin_lock, flags);
- return;
- }
-
- if (events & COMEDI_CB_CANCEL_MASK)
- __comedi_clear_subdevice_runflags(s, COMEDI_SRF_RUNNING);
-
- /*
- * Remember if an error event has occurred, so an error can be
- * returned the next time the user does a read() or write().
- */
- if (events & COMEDI_CB_ERROR_MASK)
- __comedi_set_subdevice_runflags(s, COMEDI_SRF_ERROR);
-
- if (async->cb_mask & events) {
- wake_up_interruptible(&async->wait_head);
- si_code = async->cmd.flags & CMDF_WRITE ? POLL_OUT : POLL_IN;
- }
-
- spin_unlock_irqrestore(&s->spin_lock, flags);
-
- if (si_code)
- kill_fasync(&dev->async_queue, SIGIO, si_code);
-}
-EXPORT_SYMBOL_GPL(comedi_event);
-
-/* Note: the ->mutex is pre-locked on successful return */
-struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
-{
- struct comedi_device *dev;
- struct device *csdev;
- unsigned int i;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return ERR_PTR(-ENOMEM);
- comedi_device_init(dev);
- comedi_set_hw_dev(dev, hardware_device);
- mutex_lock(&dev->mutex);
- mutex_lock(&comedi_board_minor_table_lock);
- for (i = hardware_device ? comedi_num_legacy_minors : 0;
- i < COMEDI_NUM_BOARD_MINORS; ++i) {
- if (!comedi_board_minor_table[i]) {
- comedi_board_minor_table[i] = dev;
- break;
- }
- }
- mutex_unlock(&comedi_board_minor_table_lock);
- if (i == COMEDI_NUM_BOARD_MINORS) {
- mutex_unlock(&dev->mutex);
- comedi_device_cleanup(dev);
- comedi_dev_put(dev);
- dev_err(hardware_device,
- "ran out of minor numbers for board device files\n");
- return ERR_PTR(-EBUSY);
- }
- dev->minor = i;
- csdev = device_create(comedi_class, hardware_device,
- MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i);
- if (!IS_ERR(csdev))
- dev->class_dev = get_device(csdev);
-
- /* Note: dev->mutex needs to be unlocked by the caller. */
- return dev;
-}
-
-void comedi_release_hardware_device(struct device *hardware_device)
-{
- int minor;
- struct comedi_device *dev;
-
- for (minor = comedi_num_legacy_minors; minor < COMEDI_NUM_BOARD_MINORS;
- minor++) {
- mutex_lock(&comedi_board_minor_table_lock);
- dev = comedi_board_minor_table[minor];
- if (dev && dev->hw_dev == hardware_device) {
- comedi_board_minor_table[minor] = NULL;
- mutex_unlock(&comedi_board_minor_table_lock);
- comedi_free_board_dev(dev);
- break;
- }
- mutex_unlock(&comedi_board_minor_table_lock);
- }
-}
-
-int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
-{
- struct comedi_device *dev = s->device;
- struct device *csdev;
- unsigned int i;
-
- mutex_lock(&comedi_subdevice_minor_table_lock);
- for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) {
- if (!comedi_subdevice_minor_table[i]) {
- comedi_subdevice_minor_table[i] = s;
- break;
- }
- }
- mutex_unlock(&comedi_subdevice_minor_table_lock);
- if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
- dev_err(dev->class_dev,
- "ran out of minor numbers for subdevice files\n");
- return -EBUSY;
- }
- i += COMEDI_NUM_BOARD_MINORS;
- s->minor = i;
- csdev = device_create(comedi_class, dev->class_dev,
- MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i_subd%i",
- dev->minor, s->index);
- if (!IS_ERR(csdev))
- s->class_dev = csdev;
-
- return 0;
-}
-
-void comedi_free_subdevice_minor(struct comedi_subdevice *s)
-{
- unsigned int i;
-
- if (!s)
- return;
- if (s->minor < COMEDI_NUM_BOARD_MINORS ||
- s->minor >= COMEDI_NUM_MINORS)
- return;
-
- i = s->minor - COMEDI_NUM_BOARD_MINORS;
- mutex_lock(&comedi_subdevice_minor_table_lock);
- if (s == comedi_subdevice_minor_table[i])
- comedi_subdevice_minor_table[i] = NULL;
- mutex_unlock(&comedi_subdevice_minor_table_lock);
- if (s->class_dev) {
- device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
- s->class_dev = NULL;
- }
-}
-
-static void comedi_cleanup_board_minors(void)
-{
- struct comedi_device *dev;
- unsigned int i;
-
- for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
- dev = comedi_clear_board_minor(i);
- comedi_free_board_dev(dev);
- }
-}
-
-static int __init comedi_init(void)
-{
- int i;
- int retval;
-
- pr_info("version " COMEDI_RELEASE " - http://www.comedi.org\n");
-
- if (comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
- pr_err("invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n",
- COMEDI_NUM_BOARD_MINORS);
- return -EINVAL;
- }
-
- retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
- COMEDI_NUM_MINORS, "comedi");
- if (retval)
- return retval;
-
- cdev_init(&comedi_cdev, &comedi_fops);
- comedi_cdev.owner = THIS_MODULE;
-
- retval = kobject_set_name(&comedi_cdev.kobj, "comedi");
- if (retval)
- goto out_unregister_chrdev_region;
-
- retval = cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0),
- COMEDI_NUM_MINORS);
- if (retval)
- goto out_unregister_chrdev_region;
-
- comedi_class = class_create(THIS_MODULE, "comedi");
- if (IS_ERR(comedi_class)) {
- retval = PTR_ERR(comedi_class);
- pr_err("failed to create class\n");
- goto out_cdev_del;
- }
-
- comedi_class->dev_groups = comedi_dev_groups;
-
- /* create devices files for legacy/manual use */
- for (i = 0; i < comedi_num_legacy_minors; i++) {
- struct comedi_device *dev;
-
- dev = comedi_alloc_board_minor(NULL);
- if (IS_ERR(dev)) {
- retval = PTR_ERR(dev);
- goto out_cleanup_board_minors;
- }
- /* comedi_alloc_board_minor() locked the mutex */
- lockdep_assert_held(&dev->mutex);
- mutex_unlock(&dev->mutex);
- }
-
- /* XXX requires /proc interface */
- comedi_proc_init();
-
- return 0;
-
-out_cleanup_board_minors:
- comedi_cleanup_board_minors();
- class_destroy(comedi_class);
-out_cdev_del:
- cdev_del(&comedi_cdev);
-out_unregister_chrdev_region:
- unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
- return retval;
-}
-module_init(comedi_init);
-
-static void __exit comedi_cleanup(void)
-{
- comedi_cleanup_board_minors();
- class_destroy(comedi_class);
- cdev_del(&comedi_cdev);
- unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
-
- comedi_proc_cleanup();
-}
-module_exit(comedi_cleanup);
-
-MODULE_AUTHOR("https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi core module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
deleted file mode 100644
index 9b3631a654c8..000000000000
--- a/drivers/staging/comedi/comedi_internal.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _COMEDI_INTERNAL_H
-#define _COMEDI_INTERNAL_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/*
- * various internal comedi stuff
- */
-
-struct comedi_buf_map;
-struct comedi_devconfig;
-struct comedi_device;
-struct comedi_insn;
-struct comedi_rangeinfo;
-struct comedi_subdevice;
-struct device;
-
-int do_rangeinfo_ioctl(struct comedi_device *dev,
- struct comedi_rangeinfo *it);
-struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device);
-void comedi_release_hardware_device(struct device *hardware_device);
-int comedi_alloc_subdevice_minor(struct comedi_subdevice *s);
-void comedi_free_subdevice_minor(struct comedi_subdevice *s);
-
-int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned long new_size);
-void comedi_buf_reset(struct comedi_subdevice *s);
-bool comedi_buf_is_mmapped(struct comedi_subdevice *s);
-void comedi_buf_map_get(struct comedi_buf_map *bm);
-int comedi_buf_map_put(struct comedi_buf_map *bm);
-int comedi_buf_map_access(struct comedi_buf_map *bm, unsigned long offset,
- void *buf, int len, int write);
-struct comedi_buf_map *
-comedi_buf_map_from_subdev_get(struct comedi_subdevice *s);
-unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s);
-unsigned int comedi_buf_write_n_allocated(struct comedi_subdevice *s);
-void comedi_device_cancel_all(struct comedi_device *dev);
-bool comedi_can_auto_free_spriv(struct comedi_subdevice *s);
-
-extern unsigned int comedi_default_buf_size_kb;
-extern unsigned int comedi_default_buf_maxsize_kb;
-
-/* drivers.c */
-
-extern struct comedi_driver *comedi_drivers;
-extern struct mutex comedi_drivers_list_lock;
-
-int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-void comedi_device_detach(struct comedi_device *dev);
-int comedi_device_attach(struct comedi_device *dev,
- struct comedi_devconfig *it);
-
-#ifdef CONFIG_PROC_FS
-
-/* proc.c */
-
-void comedi_proc_init(void);
-void comedi_proc_cleanup(void);
-#else
-static inline void comedi_proc_init(void)
-{
-}
-
-static inline void comedi_proc_cleanup(void)
-{
-}
-#endif
-
-#endif /* _COMEDI_INTERNAL_H */
diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c
deleted file mode 100644
index 54739af7eb71..000000000000
--- a/drivers/staging/comedi/comedi_pci.c
+++ /dev/null
@@ -1,228 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_pci.c
- * Comedi PCI driver specific functions.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "comedi_pci.h"
-
-/**
- * comedi_to_pci_dev() - Return PCI device attached to COMEDI device
- * @dev: COMEDI device.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
- * a &struct device embedded in a &struct pci_dev.
- *
- * Return: Attached PCI device if @dev->hw_dev is non-%NULL.
- * Return %NULL if @dev->hw_dev is %NULL.
- */
-struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev)
-{
- return dev->hw_dev ? to_pci_dev(dev->hw_dev) : NULL;
-}
-EXPORT_SYMBOL_GPL(comedi_to_pci_dev);
-
-/**
- * comedi_pci_enable() - Enable the PCI device and request the regions
- * @dev: COMEDI device.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
- * a &struct device embedded in a &struct pci_dev. Enable the PCI device
- * and request its regions. Set @dev->ioenabled to %true if successful,
- * otherwise undo what was done.
- *
- * Calls to comedi_pci_enable() and comedi_pci_disable() cannot be nested.
- *
- * Return:
- * 0 on success,
- * -%ENODEV if @dev->hw_dev is %NULL,
- * -%EBUSY if regions busy,
- * or some negative error number if failed to enable PCI device.
- *
- */
-int comedi_pci_enable(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- int rc;
-
- if (!pcidev)
- return -ENODEV;
-
- rc = pci_enable_device(pcidev);
- if (rc < 0)
- return rc;
-
- rc = pci_request_regions(pcidev, dev->board_name);
- if (rc < 0)
- pci_disable_device(pcidev);
- else
- dev->ioenabled = true;
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(comedi_pci_enable);
-
-/**
- * comedi_pci_disable() - Release the regions and disable the PCI device
- * @dev: COMEDI device.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
- * a &struct device embedded in a &struct pci_dev. If the earlier call
- * to comedi_pci_enable() was successful, release the PCI device's regions
- * and disable it. Reset @dev->ioenabled back to %false.
- */
-void comedi_pci_disable(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev && dev->ioenabled) {
- pci_release_regions(pcidev);
- pci_disable_device(pcidev);
- }
- dev->ioenabled = false;
-}
-EXPORT_SYMBOL_GPL(comedi_pci_disable);
-
-/**
- * comedi_pci_detach() - A generic "detach" handler for PCI COMEDI drivers
- * @dev: COMEDI device.
- *
- * COMEDI drivers for PCI devices that need no special clean-up of private data
- * and have no ioremapped regions other than that pointed to by @dev->mmio may
- * use this function as its "detach" handler called by the COMEDI core when a
- * COMEDI device is being detached from the low-level driver. It may be also
- * called from a more specific "detach" handler that does additional clean-up.
- *
- * Free the IRQ if @dev->irq is non-zero, iounmap @dev->mmio if it is
- * non-%NULL, and call comedi_pci_disable() to release the PCI device's regions
- * and disable it.
- */
-void comedi_pci_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (!pcidev || !dev->ioenabled)
- return;
-
- if (dev->irq) {
- free_irq(dev->irq, dev);
- dev->irq = 0;
- }
- if (dev->mmio) {
- iounmap(dev->mmio);
- dev->mmio = NULL;
- }
- comedi_pci_disable(dev);
-}
-EXPORT_SYMBOL_GPL(comedi_pci_detach);
-
-/**
- * comedi_pci_auto_config() - Configure/probe a PCI COMEDI device
- * @pcidev: PCI device.
- * @driver: Registered COMEDI driver.
- * @context: Driver specific data, passed to comedi_auto_config().
- *
- * Typically called from the pci_driver (*probe) function. Auto-configure
- * a COMEDI device, using the &struct device embedded in *@pcidev as the
- * hardware device. The @context value gets passed through to @driver's
- * "auto_attach" handler. The "auto_attach" handler may call
- * comedi_to_pci_dev() on the passed in COMEDI device to recover @pcidev.
- *
- * Return: The result of calling comedi_auto_config() (0 on success, or
- * a negative error number on failure).
- */
-int comedi_pci_auto_config(struct pci_dev *pcidev,
- struct comedi_driver *driver,
- unsigned long context)
-{
- return comedi_auto_config(&pcidev->dev, driver, context);
-}
-EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
-
-/**
- * comedi_pci_auto_unconfig() - Unconfigure/remove a PCI COMEDI device
- * @pcidev: PCI device.
- *
- * Typically called from the pci_driver (*remove) function. Auto-unconfigure
- * a COMEDI device attached to this PCI device, using a pointer to the
- * &struct device embedded in *@pcidev as the hardware device. The COMEDI
- * driver's "detach" handler will be called during unconfiguration of the
- * COMEDI device.
- *
- * Note that the COMEDI device may have already been unconfigured using the
- * %COMEDI_DEVCONFIG ioctl, in which case this attempt to unconfigure it
- * again should be ignored.
- */
-void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
-{
- comedi_auto_unconfig(&pcidev->dev);
-}
-EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
-
-/**
- * comedi_pci_driver_register() - Register a PCI COMEDI driver
- * @comedi_driver: COMEDI driver to be registered.
- * @pci_driver: PCI driver to be registered.
- *
- * This function is called from the module_init() of PCI COMEDI driver modules
- * to register the COMEDI driver and the PCI driver. Do not call it directly,
- * use the module_comedi_pci_driver() helper macro instead.
- *
- * Return: 0 on success, or a negative error number on failure.
- */
-int comedi_pci_driver_register(struct comedi_driver *comedi_driver,
- struct pci_driver *pci_driver)
-{
- int ret;
-
- ret = comedi_driver_register(comedi_driver);
- if (ret < 0)
- return ret;
-
- ret = pci_register_driver(pci_driver);
- if (ret < 0) {
- comedi_driver_unregister(comedi_driver);
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_pci_driver_register);
-
-/**
- * comedi_pci_driver_unregister() - Unregister a PCI COMEDI driver
- * @comedi_driver: COMEDI driver to be unregistered.
- * @pci_driver: PCI driver to be unregistered.
- *
- * This function is called from the module_exit() of PCI COMEDI driver modules
- * to unregister the PCI driver and the COMEDI driver. Do not call it
- * directly, use the module_comedi_pci_driver() helper macro instead.
- */
-void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver,
- struct pci_driver *pci_driver)
-{
- pci_unregister_driver(pci_driver);
- comedi_driver_unregister(comedi_driver);
-}
-EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister);
-
-static int __init comedi_pci_init(void)
-{
- return 0;
-}
-module_init(comedi_pci_init);
-
-static void __exit comedi_pci_exit(void)
-{
-}
-module_exit(comedi_pci_exit);
-
-MODULE_AUTHOR("https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi PCI interface module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/comedi_pci.h b/drivers/staging/comedi/comedi_pci.h
deleted file mode 100644
index 4e069440cbdc..000000000000
--- a/drivers/staging/comedi/comedi_pci.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedi_pci.h
- * header file for Comedi PCI drivers
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _COMEDI_PCI_H
-#define _COMEDI_PCI_H
-
-#include <linux/pci.h>
-
-#include "comedidev.h"
-
-/*
- * PCI Vendor IDs not in <linux/pci_ids.h>
- */
-#define PCI_VENDOR_ID_KOLTER 0x1001
-#define PCI_VENDOR_ID_ICP 0x104c
-#define PCI_VENDOR_ID_DT 0x1116
-#define PCI_VENDOR_ID_IOTECH 0x1616
-#define PCI_VENDOR_ID_CONTEC 0x1221
-#define PCI_VENDOR_ID_RTD 0x1435
-#define PCI_VENDOR_ID_HUMUSOFT 0x186c
-
-struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev);
-
-int comedi_pci_enable(struct comedi_device *dev);
-void comedi_pci_disable(struct comedi_device *dev);
-void comedi_pci_detach(struct comedi_device *dev);
-
-int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver,
- unsigned long context);
-void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
-
-int comedi_pci_driver_register(struct comedi_driver *comedi_driver,
- struct pci_driver *pci_driver);
-void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver,
- struct pci_driver *pci_driver);
-
-/**
- * module_comedi_pci_driver() - Helper macro for registering a comedi PCI driver
- * @__comedi_driver: comedi_driver struct
- * @__pci_driver: pci_driver struct
- *
- * Helper macro for comedi PCI drivers which do not do anything special
- * in module init/exit. This eliminates a lot of boilerplate. Each
- * module may only use this macro once, and calling it replaces
- * module_init() and module_exit()
- */
-#define module_comedi_pci_driver(__comedi_driver, __pci_driver) \
- module_driver(__comedi_driver, comedi_pci_driver_register, \
- comedi_pci_driver_unregister, &(__pci_driver))
-
-#endif /* _COMEDI_PCI_H */
diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c
deleted file mode 100644
index bb273bb202e6..000000000000
--- a/drivers/staging/comedi/comedi_pcmcia.c
+++ /dev/null
@@ -1,209 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_pcmcia.c
- * Comedi PCMCIA driver specific functions.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include "comedi_pcmcia.h"
-
-/**
- * comedi_to_pcmcia_dev() - Return PCMCIA device attached to COMEDI device
- * @dev: COMEDI device.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
- * a &struct device embedded in a &struct pcmcia_device.
- *
- * Return: Attached PCMCIA device if @dev->hw_dev is non-%NULL.
- * Return %NULL if @dev->hw_dev is %NULL.
- */
-struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev)
-{
- return dev->hw_dev ? to_pcmcia_dev(dev->hw_dev) : NULL;
-}
-EXPORT_SYMBOL_GPL(comedi_to_pcmcia_dev);
-
-static int comedi_pcmcia_conf_check(struct pcmcia_device *link,
- void *priv_data)
-{
- if (link->config_index == 0)
- return -EINVAL;
-
- return pcmcia_request_io(link);
-}
-
-/**
- * comedi_pcmcia_enable() - Request the regions and enable the PCMCIA device
- * @dev: COMEDI device.
- * @conf_check: Optional callback to check each configuration option of the
- * PCMCIA device and request I/O regions.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a a
- * &struct device embedded in a &struct pcmcia_device. The comedi PCMCIA
- * driver needs to set the 'config_flags' member in the &struct pcmcia_device,
- * as appropriate for that driver, before calling this function in order to
- * allow pcmcia_loop_config() to do its internal autoconfiguration.
- *
- * If @conf_check is %NULL it is set to a default function. If is
- * passed to pcmcia_loop_config() and should return %0 if the configuration
- * is valid and I/O regions requested successfully, otherwise it should return
- * a negative error value. The default function returns -%EINVAL if the
- * 'config_index' member is %0, otherwise it calls pcmcia_request_io() and
- * returns the result.
- *
- * If the above configuration check passes, pcmcia_enable_device() is called
- * to set up and activate the PCMCIA device.
- *
- * If this function returns an error, comedi_pcmcia_disable() should be called
- * to release requested resources.
- *
- * Return:
- * 0 on success,
- * -%ENODEV id @dev->hw_dev is %NULL,
- * a negative error number from pcmcia_loop_config() if it fails,
- * or a negative error number from pcmcia_enable_device() if it fails.
- */
-int comedi_pcmcia_enable(struct comedi_device *dev,
- int (*conf_check)(struct pcmcia_device *p_dev,
- void *priv_data))
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- int ret;
-
- if (!link)
- return -ENODEV;
-
- if (!conf_check)
- conf_check = comedi_pcmcia_conf_check;
-
- ret = pcmcia_loop_config(link, conf_check, NULL);
- if (ret)
- return ret;
-
- return pcmcia_enable_device(link);
-}
-EXPORT_SYMBOL_GPL(comedi_pcmcia_enable);
-
-/**
- * comedi_pcmcia_disable() - Disable the PCMCIA device and release the regions
- * @dev: COMEDI device.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
- * a &struct device embedded in a &struct pcmcia_device. Call
- * pcmcia_disable_device() to disable and clean up the PCMCIA device.
- */
-void comedi_pcmcia_disable(struct comedi_device *dev)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
-
- if (link)
- pcmcia_disable_device(link);
-}
-EXPORT_SYMBOL_GPL(comedi_pcmcia_disable);
-
-/**
- * comedi_pcmcia_auto_config() - Configure/probe a PCMCIA COMEDI device
- * @link: PCMCIA device.
- * @driver: Registered COMEDI driver.
- *
- * Typically called from the pcmcia_driver (*probe) function. Auto-configure
- * a COMEDI device, using a pointer to the &struct device embedded in *@link
- * as the hardware device. The @driver's "auto_attach" handler may call
- * comedi_to_pcmcia_dev() on the passed in COMEDI device to recover @link.
- *
- * Return: The result of calling comedi_auto_config() (0 on success, or a
- * negative error number on failure).
- */
-int comedi_pcmcia_auto_config(struct pcmcia_device *link,
- struct comedi_driver *driver)
-{
- return comedi_auto_config(&link->dev, driver, 0);
-}
-EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_config);
-
-/**
- * comedi_pcmcia_auto_unconfig() - Unconfigure/remove a PCMCIA COMEDI device
- * @link: PCMCIA device.
- *
- * Typically called from the pcmcia_driver (*remove) function.
- * Auto-unconfigure a COMEDI device attached to this PCMCIA device, using a
- * pointer to the &struct device embedded in *@link as the hardware device.
- * The COMEDI driver's "detach" handler will be called during unconfiguration
- * of the COMEDI device.
- *
- * Note that the COMEDI device may have already been unconfigured using the
- * %COMEDI_DEVCONFIG ioctl, in which case this attempt to unconfigure it
- * again should be ignored.
- */
-void comedi_pcmcia_auto_unconfig(struct pcmcia_device *link)
-{
- comedi_auto_unconfig(&link->dev);
-}
-EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_unconfig);
-
-/**
- * comedi_pcmcia_driver_register() - Register a PCMCIA COMEDI driver
- * @comedi_driver: COMEDI driver to be registered.
- * @pcmcia_driver: PCMCIA driver to be registered.
- *
- * This function is used for the module_init() of PCMCIA COMEDI driver modules
- * to register the COMEDI driver and the PCMCIA driver. Do not call it
- * directly, use the module_comedi_pcmcia_driver() helper macro instead.
- *
- * Return: 0 on success, or a negative error number on failure.
- */
-int comedi_pcmcia_driver_register(struct comedi_driver *comedi_driver,
- struct pcmcia_driver *pcmcia_driver)
-{
- int ret;
-
- ret = comedi_driver_register(comedi_driver);
- if (ret < 0)
- return ret;
-
- ret = pcmcia_register_driver(pcmcia_driver);
- if (ret < 0) {
- comedi_driver_unregister(comedi_driver);
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_register);
-
-/**
- * comedi_pcmcia_driver_unregister() - Unregister a PCMCIA COMEDI driver
- * @comedi_driver: COMEDI driver to be registered.
- * @pcmcia_driver: PCMCIA driver to be registered.
- *
- * This function is called from the module_exit() of PCMCIA COMEDI driver
- * modules to unregister the PCMCIA driver and the COMEDI driver. Do not call
- * it directly, use the module_comedi_pcmcia_driver() helper macro instead.
- */
-void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver,
- struct pcmcia_driver *pcmcia_driver)
-{
- pcmcia_unregister_driver(pcmcia_driver);
- comedi_driver_unregister(comedi_driver);
-}
-EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_unregister);
-
-static int __init comedi_pcmcia_init(void)
-{
- return 0;
-}
-module_init(comedi_pcmcia_init);
-
-static void __exit comedi_pcmcia_exit(void)
-{
-}
-module_exit(comedi_pcmcia_exit);
-
-MODULE_AUTHOR("https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi PCMCIA interface module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/comedi_pcmcia.h b/drivers/staging/comedi/comedi_pcmcia.h
deleted file mode 100644
index f2f6e779645b..000000000000
--- a/drivers/staging/comedi/comedi_pcmcia.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedi_pcmcia.h
- * header file for Comedi PCMCIA drivers
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _COMEDI_PCMCIA_H
-#define _COMEDI_PCMCIA_H
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-#include "comedidev.h"
-
-struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev);
-
-int comedi_pcmcia_enable(struct comedi_device *dev,
- int (*conf_check)(struct pcmcia_device *p_dev,
- void *priv_data));
-void comedi_pcmcia_disable(struct comedi_device *dev);
-
-int comedi_pcmcia_auto_config(struct pcmcia_device *link,
- struct comedi_driver *driver);
-void comedi_pcmcia_auto_unconfig(struct pcmcia_device *link);
-
-int comedi_pcmcia_driver_register(struct comedi_driver *comedi_driver,
- struct pcmcia_driver *pcmcia_driver);
-void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver,
- struct pcmcia_driver *pcmcia_driver);
-
-/**
- * module_comedi_pcmcia_driver() - Helper macro for registering a comedi
- * PCMCIA driver
- * @__comedi_driver: comedi_driver struct
- * @__pcmcia_driver: pcmcia_driver struct
- *
- * Helper macro for comedi PCMCIA drivers which do not do anything special
- * in module init/exit. This eliminates a lot of boilerplate. Each
- * module may only use this macro once, and calling it replaces
- * module_init() and module_exit()
- */
-#define module_comedi_pcmcia_driver(__comedi_driver, __pcmcia_driver) \
- module_driver(__comedi_driver, comedi_pcmcia_driver_register, \
- comedi_pcmcia_driver_unregister, &(__pcmcia_driver))
-
-#endif /* _COMEDI_PCMCIA_H */
diff --git a/drivers/staging/comedi/comedi_usb.c b/drivers/staging/comedi/comedi_usb.c
deleted file mode 100644
index eea8ebf32ed0..000000000000
--- a/drivers/staging/comedi/comedi_usb.c
+++ /dev/null
@@ -1,151 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_usb.c
- * Comedi USB driver specific functions.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/module.h>
-
-#include "comedi_usb.h"
-
-/**
- * comedi_to_usb_interface() - Return USB interface attached to COMEDI device
- * @dev: COMEDI device.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
- * a &struct device embedded in a &struct usb_interface.
- *
- * Return: Attached USB interface if @dev->hw_dev is non-%NULL.
- * Return %NULL if @dev->hw_dev is %NULL.
- */
-struct usb_interface *comedi_to_usb_interface(struct comedi_device *dev)
-{
- return dev->hw_dev ? to_usb_interface(dev->hw_dev) : NULL;
-}
-EXPORT_SYMBOL_GPL(comedi_to_usb_interface);
-
-/**
- * comedi_to_usb_dev() - Return USB device attached to COMEDI device
- * @dev: COMEDI device.
- *
- * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
- * a &struct device embedded in a &struct usb_interface.
- *
- * Return: USB device to which the USB interface belongs if @dev->hw_dev is
- * non-%NULL. Return %NULL if @dev->hw_dev is %NULL.
- */
-struct usb_device *comedi_to_usb_dev(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
-
- return intf ? interface_to_usbdev(intf) : NULL;
-}
-EXPORT_SYMBOL_GPL(comedi_to_usb_dev);
-
-/**
- * comedi_usb_auto_config() - Configure/probe a USB COMEDI driver
- * @intf: USB interface.
- * @driver: Registered COMEDI driver.
- * @context: Driver specific data, passed to comedi_auto_config().
- *
- * Typically called from the usb_driver (*probe) function. Auto-configure a
- * COMEDI device, using a pointer to the &struct device embedded in *@intf as
- * the hardware device. The @context value gets passed through to @driver's
- * "auto_attach" handler. The "auto_attach" handler may call
- * comedi_to_usb_interface() on the passed in COMEDI device to recover @intf.
- *
- * Return: The result of calling comedi_auto_config() (%0 on success, or
- * a negative error number on failure).
- */
-int comedi_usb_auto_config(struct usb_interface *intf,
- struct comedi_driver *driver,
- unsigned long context)
-{
- return comedi_auto_config(&intf->dev, driver, context);
-}
-EXPORT_SYMBOL_GPL(comedi_usb_auto_config);
-
-/**
- * comedi_usb_auto_unconfig() - Unconfigure/disconnect a USB COMEDI device
- * @intf: USB interface.
- *
- * Typically called from the usb_driver (*disconnect) function.
- * Auto-unconfigure a COMEDI device attached to this USB interface, using a
- * pointer to the &struct device embedded in *@intf as the hardware device.
- * The COMEDI driver's "detach" handler will be called during unconfiguration
- * of the COMEDI device.
- *
- * Note that the COMEDI device may have already been unconfigured using the
- * %COMEDI_DEVCONFIG ioctl, in which case this attempt to unconfigure it
- * again should be ignored.
- */
-void comedi_usb_auto_unconfig(struct usb_interface *intf)
-{
- comedi_auto_unconfig(&intf->dev);
-}
-EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig);
-
-/**
- * comedi_usb_driver_register() - Register a USB COMEDI driver
- * @comedi_driver: COMEDI driver to be registered.
- * @usb_driver: USB driver to be registered.
- *
- * This function is called from the module_init() of USB COMEDI driver modules
- * to register the COMEDI driver and the USB driver. Do not call it directly,
- * use the module_comedi_usb_driver() helper macro instead.
- *
- * Return: %0 on success, or a negative error number on failure.
- */
-int comedi_usb_driver_register(struct comedi_driver *comedi_driver,
- struct usb_driver *usb_driver)
-{
- int ret;
-
- ret = comedi_driver_register(comedi_driver);
- if (ret < 0)
- return ret;
-
- ret = usb_register(usb_driver);
- if (ret < 0) {
- comedi_driver_unregister(comedi_driver);
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_usb_driver_register);
-
-/**
- * comedi_usb_driver_unregister() - Unregister a USB COMEDI driver
- * @comedi_driver: COMEDI driver to be registered.
- * @usb_driver: USB driver to be registered.
- *
- * This function is called from the module_exit() of USB COMEDI driver modules
- * to unregister the USB driver and the COMEDI driver. Do not call it
- * directly, use the module_comedi_usb_driver() helper macro instead.
- */
-void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver,
- struct usb_driver *usb_driver)
-{
- usb_deregister(usb_driver);
- comedi_driver_unregister(comedi_driver);
-}
-EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister);
-
-static int __init comedi_usb_init(void)
-{
- return 0;
-}
-module_init(comedi_usb_init);
-
-static void __exit comedi_usb_exit(void)
-{
-}
-module_exit(comedi_usb_exit);
-
-MODULE_AUTHOR("https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi USB interface module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/comedi_usb.h b/drivers/staging/comedi/comedi_usb.h
deleted file mode 100644
index 601e29d3891c..000000000000
--- a/drivers/staging/comedi/comedi_usb.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* comedi_usb.h
- * header file for USB Comedi drivers
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _COMEDI_USB_H
-#define _COMEDI_USB_H
-
-#include <linux/usb.h>
-
-#include "comedidev.h"
-
-struct usb_interface *comedi_to_usb_interface(struct comedi_device *dev);
-struct usb_device *comedi_to_usb_dev(struct comedi_device *dev);
-
-int comedi_usb_auto_config(struct usb_interface *intf,
- struct comedi_driver *driver, unsigned long context);
-void comedi_usb_auto_unconfig(struct usb_interface *intf);
-
-int comedi_usb_driver_register(struct comedi_driver *comedi_driver,
- struct usb_driver *usb_driver);
-void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver,
- struct usb_driver *usb_driver);
-
-/**
- * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver
- * @__comedi_driver: comedi_driver struct
- * @__usb_driver: usb_driver struct
- *
- * Helper macro for comedi USB drivers which do not do anything special
- * in module init/exit. This eliminates a lot of boilerplate. Each
- * module may only use this macro once, and calling it replaces
- * module_init() and module_exit()
- */
-#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \
- module_driver(__comedi_driver, comedi_usb_driver_register, \
- comedi_usb_driver_unregister, &(__usb_driver))
-
-#endif /* _COMEDI_USB_H */
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
deleted file mode 100644
index 0e1b95ef9a4d..000000000000
--- a/drivers/staging/comedi/comedidev.h
+++ /dev/null
@@ -1,1054 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedidev.h
- * header file for kernel-only structures, variables, and constants
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _COMEDIDEV_H
-#define _COMEDIDEV_H
-
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-#include <linux/spinlock_types.h>
-#include <linux/rwsem.h>
-#include <linux/kref.h>
-
-#include "comedi.h"
-
-#define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, \
- COMEDI_MINORVERSION, COMEDI_MICROVERSION)
-#define COMEDI_RELEASE VERSION
-
-#define COMEDI_NUM_BOARD_MINORS 0x30
-
-/**
- * struct comedi_subdevice - Working data for a COMEDI subdevice
- * @device: COMEDI device to which this subdevice belongs. (Initialized by
- * comedi_alloc_subdevices().)
- * @index: Index of this subdevice within device's array of subdevices.
- * (Initialized by comedi_alloc_subdevices().)
- * @type: Type of subdevice from &enum comedi_subdevice_type. (Initialized by
- * the low-level driver.)
- * @n_chan: Number of channels the subdevice supports. (Initialized by the
- * low-level driver.)
- * @subdev_flags: Various "SDF" flags indicating aspects of the subdevice to
- * the COMEDI core and user application. (Initialized by the low-level
- * driver.)
- * @len_chanlist: Maximum length of a channel list if the subdevice supports
- * asynchronous acquisition commands. (Optionally initialized by the
- * low-level driver, or changed from 0 to 1 during post-configuration.)
- * @private: Private data pointer which is either set by the low-level driver
- * itself, or by a call to comedi_alloc_spriv() which allocates storage.
- * In the latter case, the storage is automatically freed after the
- * low-level driver's "detach" handler is called for the device.
- * (Initialized by the low-level driver.)
- * @async: Pointer to &struct comedi_async id the subdevice supports
- * asynchronous acquisition commands. (Allocated and initialized during
- * post-configuration if needed.)
- * @lock: Pointer to a file object that performed a %COMEDI_LOCK ioctl on the
- * subdevice. (Initially NULL.)
- * @busy: Pointer to a file object that is performing an asynchronous
- * acquisition command on the subdevice. (Initially NULL.)
- * @runflags: Internal flags for use by COMEDI core, mostly indicating whether
- * an asynchronous acquisition command is running.
- * @spin_lock: Generic spin-lock for use by the COMEDI core and the low-level
- * driver. (Initialized by comedi_alloc_subdevices().)
- * @io_bits: Bit-mask indicating the channel directions for a DIO subdevice
- * with no more than 32 channels. A '1' at a bit position indicates the
- * corresponding channel is configured as an output. (Initialized by the
- * low-level driver for a DIO subdevice. Forced to all-outputs during
- * post-configuration for a digital output subdevice.)
- * @maxdata: If non-zero, this is the maximum raw data value of each channel.
- * If zero, the maximum data value is channel-specific. (Initialized by
- * the low-level driver.)
- * @maxdata_list: If the maximum data value is channel-specific, this points
- * to an array of maximum data values indexed by channel index.
- * (Initialized by the low-level driver.)
- * @range_table: If non-NULL, this points to a COMEDI range table for the
- * subdevice. If NULL, the range table is channel-specific. (Initialized
- * by the low-level driver, will be set to an "invalid" range table during
- * post-configuration if @range_table and @range_table_list are both
- * NULL.)
- * @range_table_list: If the COMEDI range table is channel-specific, this
- * points to an array of pointers to COMEDI range tables indexed by
- * channel number. (Initialized by the low-level driver.)
- * @chanlist: Not used.
- * @insn_read: Optional pointer to a handler for the %INSN_READ instruction.
- * (Initialized by the low-level driver, or set to a default handler
- * during post-configuration.)
- * @insn_write: Optional pointer to a handler for the %INSN_WRITE instruction.
- * (Initialized by the low-level driver, or set to a default handler
- * during post-configuration.)
- * @insn_bits: Optional pointer to a handler for the %INSN_BITS instruction
- * for a digital input, digital output or digital input/output subdevice.
- * (Initialized by the low-level driver, or set to a default handler
- * during post-configuration.)
- * @insn_config: Optional pointer to a handler for the %INSN_CONFIG
- * instruction. (Initialized by the low-level driver, or set to a default
- * handler during post-configuration.)
- * @do_cmd: If the subdevice supports asynchronous acquisition commands, this
- * points to a handler to set it up in hardware. (Initialized by the
- * low-level driver.)
- * @do_cmdtest: If the subdevice supports asynchronous acquisition commands,
- * this points to a handler used to check and possibly tweak a prospective
- * acquisition command without setting it up in hardware. (Initialized by
- * the low-level driver.)
- * @poll: If the subdevice supports asynchronous acquisition commands, this
- * is an optional pointer to a handler for the %COMEDI_POLL ioctl which
- * instructs the low-level driver to synchronize buffers. (Initialized by
- * the low-level driver if needed.)
- * @cancel: If the subdevice supports asynchronous acquisition commands, this
- * points to a handler used to terminate a running command. (Initialized
- * by the low-level driver.)
- * @buf_change: If the subdevice supports asynchronous acquisition commands,
- * this is an optional pointer to a handler that is called when the data
- * buffer for handling asynchronous commands is allocated or reallocated.
- * (Initialized by the low-level driver if needed.)
- * @munge: If the subdevice supports asynchronous acquisition commands and
- * uses DMA to transfer data from the hardware to the acquisition buffer,
- * this points to a function used to "munge" the data values from the
- * hardware into the format expected by COMEDI. (Initialized by the
- * low-level driver if needed.)
- * @async_dma_dir: If the subdevice supports asynchronous acquisition commands
- * and uses DMA to transfer data from the hardware to the acquisition
- * buffer, this sets the DMA direction for the buffer. (initialized to
- * %DMA_NONE by comedi_alloc_subdevices() and changed by the low-level
- * driver if necessary.)
- * @state: Handy bit-mask indicating the output states for a DIO or digital
- * output subdevice with no more than 32 channels. (Initialized by the
- * low-level driver.)
- * @class_dev: If the subdevice supports asynchronous acquisition commands,
- * this points to a sysfs comediX_subdY device where X is the minor device
- * number of the COMEDI device and Y is the subdevice number. The minor
- * device number for the sysfs device is allocated dynamically in the
- * range 48 to 255. This is used to allow the COMEDI device to be opened
- * with a different default read or write subdevice. (Allocated during
- * post-configuration if needed.)
- * @minor: If @class_dev is set, this is its dynamically allocated minor
- * device number. (Set during post-configuration if necessary.)
- * @readback: Optional pointer to memory allocated by
- * comedi_alloc_subdev_readback() used to hold the values written to
- * analog output channels so they can be read back. The storage is
- * automatically freed after the low-level driver's "detach" handler is
- * called for the device. (Initialized by the low-level driver.)
- *
- * This is the main control structure for a COMEDI subdevice. If the subdevice
- * supports asynchronous acquisition commands, additional information is stored
- * in the &struct comedi_async pointed to by @async.
- *
- * Most of the subdevice is initialized by the low-level driver's "attach" or
- * "auto_attach" handlers but parts of it are initialized by
- * comedi_alloc_subdevices(), and other parts are initialized during
- * post-configuration on return from that handler.
- *
- * A low-level driver that sets @insn_bits for a digital input, digital output,
- * or DIO subdevice may leave @insn_read and @insn_write uninitialized, in
- * which case they will be set to a default handler during post-configuration
- * that uses @insn_bits to emulate the %INSN_READ and %INSN_WRITE instructions.
- */
-struct comedi_subdevice {
- struct comedi_device *device;
- int index;
- int type;
- int n_chan;
- int subdev_flags;
- int len_chanlist; /* maximum length of channel/gain list */
-
- void *private;
-
- struct comedi_async *async;
-
- void *lock;
- void *busy;
- unsigned int runflags;
- spinlock_t spin_lock; /* generic spin-lock for COMEDI and drivers */
-
- unsigned int io_bits;
-
- unsigned int maxdata; /* if maxdata==0, use list */
- const unsigned int *maxdata_list; /* list is channel specific */
-
- const struct comedi_lrange *range_table;
- const struct comedi_lrange *const *range_table_list;
-
- unsigned int *chanlist; /* driver-owned chanlist (not used) */
-
- int (*insn_read)(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
- int (*insn_write)(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
- int (*insn_bits)(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
- int (*insn_config)(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
- int (*do_cmd)(struct comedi_device *dev, struct comedi_subdevice *s);
- int (*do_cmdtest)(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
- int (*poll)(struct comedi_device *dev, struct comedi_subdevice *s);
- int (*cancel)(struct comedi_device *dev, struct comedi_subdevice *s);
-
- /* called when the buffer changes */
- int (*buf_change)(struct comedi_device *dev,
- struct comedi_subdevice *s);
-
- void (*munge)(struct comedi_device *dev, struct comedi_subdevice *s,
- void *data, unsigned int num_bytes,
- unsigned int start_chan_index);
- enum dma_data_direction async_dma_dir;
-
- unsigned int state;
-
- struct device *class_dev;
- int minor;
-
- unsigned int *readback;
-};
-
-/**
- * struct comedi_buf_page - Describe a page of a COMEDI buffer
- * @virt_addr: Kernel address of page.
- * @dma_addr: DMA address of page if in DMA coherent memory.
- */
-struct comedi_buf_page {
- void *virt_addr;
- dma_addr_t dma_addr;
-};
-
-/**
- * struct comedi_buf_map - Describe pages in a COMEDI buffer
- * @dma_hw_dev: Low-level hardware &struct device pointer copied from the
- * COMEDI device's hw_dev member.
- * @page_list: Pointer to array of &struct comedi_buf_page, one for each
- * page in the buffer.
- * @n_pages: Number of pages in the buffer.
- * @dma_dir: DMA direction used to allocate pages of DMA coherent memory,
- * or %DMA_NONE if pages allocated from regular memory.
- * @refcount: &struct kref reference counter used to free the buffer.
- *
- * A COMEDI data buffer is allocated as individual pages, either in
- * conventional memory or DMA coherent memory, depending on the attached,
- * low-level hardware device. (The buffer pages also get mapped into the
- * kernel's contiguous virtual address space pointed to by the 'prealloc_buf'
- * member of &struct comedi_async.)
- *
- * The buffer is normally freed when the COMEDI device is detached from the
- * low-level driver (which may happen due to device removal), but if it happens
- * to be mmapped at the time, the pages cannot be freed until the buffer has
- * been munmapped. That is what the reference counter is for. (The virtual
- * address space pointed by 'prealloc_buf' is freed when the COMEDI device is
- * detached.)
- */
-struct comedi_buf_map {
- struct device *dma_hw_dev;
- struct comedi_buf_page *page_list;
- unsigned int n_pages;
- enum dma_data_direction dma_dir;
- struct kref refcount;
-};
-
-/**
- * struct comedi_async - Control data for asynchronous COMEDI commands
- * @prealloc_buf: Kernel virtual address of allocated acquisition buffer.
- * @prealloc_bufsz: Buffer size (in bytes).
- * @buf_map: Map of buffer pages.
- * @max_bufsize: Maximum allowed buffer size (in bytes).
- * @buf_write_count: "Write completed" count (in bytes, modulo 2**32).
- * @buf_write_alloc_count: "Allocated for writing" count (in bytes,
- * modulo 2**32).
- * @buf_read_count: "Read completed" count (in bytes, modulo 2**32).
- * @buf_read_alloc_count: "Allocated for reading" count (in bytes,
- * modulo 2**32).
- * @buf_write_ptr: Buffer position for writer.
- * @buf_read_ptr: Buffer position for reader.
- * @cur_chan: Current position in chanlist for scan (for those drivers that
- * use it).
- * @scans_done: The number of scans completed.
- * @scan_progress: Amount received or sent for current scan (in bytes).
- * @munge_chan: Current position in chanlist for "munging".
- * @munge_count: "Munge" count (in bytes, modulo 2**32).
- * @munge_ptr: Buffer position for "munging".
- * @events: Bit-vector of events that have occurred.
- * @cmd: Details of comedi command in progress.
- * @wait_head: Task wait queue for file reader or writer.
- * @cb_mask: Bit-vector of events that should wake waiting tasks.
- * @inttrig: Software trigger function for command, or NULL.
- *
- * Note about the ..._count and ..._ptr members:
- *
- * Think of the _Count values being integers of unlimited size, indexing
- * into a buffer of infinite length (though only an advancing portion
- * of the buffer of fixed length prealloc_bufsz is accessible at any
- * time). Then:
- *
- * Buf_Read_Count <= Buf_Read_Alloc_Count <= Munge_Count <=
- * Buf_Write_Count <= Buf_Write_Alloc_Count <=
- * (Buf_Read_Count + prealloc_bufsz)
- *
- * (Those aren't the actual members, apart from prealloc_bufsz.) When the
- * buffer is reset, those _Count values start at 0 and only increase in value,
- * maintaining the above inequalities until the next time the buffer is
- * reset. The buffer is divided into the following regions by the inequalities:
- *
- * [0, Buf_Read_Count):
- * old region no longer accessible
- *
- * [Buf_Read_Count, Buf_Read_Alloc_Count):
- * filled and munged region allocated for reading but not yet read
- *
- * [Buf_Read_Alloc_Count, Munge_Count):
- * filled and munged region not yet allocated for reading
- *
- * [Munge_Count, Buf_Write_Count):
- * filled region not yet munged
- *
- * [Buf_Write_Count, Buf_Write_Alloc_Count):
- * unfilled region allocated for writing but not yet written
- *
- * [Buf_Write_Alloc_Count, Buf_Read_Count + prealloc_bufsz):
- * unfilled region not yet allocated for writing
- *
- * [Buf_Read_Count + prealloc_bufsz, infinity):
- * unfilled region not yet accessible
- *
- * Data needs to be written into the buffer before it can be read out,
- * and may need to be converted (or "munged") between the two
- * operations. Extra unfilled buffer space may need to allocated for
- * writing (advancing Buf_Write_Alloc_Count) before new data is written.
- * After writing new data, the newly filled space needs to be released
- * (advancing Buf_Write_Count). This also results in the new data being
- * "munged" (advancing Munge_Count). Before data is read out of the
- * buffer, extra space may need to be allocated for reading (advancing
- * Buf_Read_Alloc_Count). After the data has been read out, the space
- * needs to be released (advancing Buf_Read_Count).
- *
- * The actual members, buf_read_count, buf_read_alloc_count,
- * munge_count, buf_write_count, and buf_write_alloc_count take the
- * value of the corresponding capitalized _Count values modulo 2^32
- * (UINT_MAX+1). Subtracting a "higher" _count value from a "lower"
- * _count value gives the same answer as subtracting a "higher" _Count
- * value from a lower _Count value because prealloc_bufsz < UINT_MAX+1.
- * The modulo operation is done implicitly.
- *
- * The buf_read_ptr, munge_ptr, and buf_write_ptr members take the value
- * of the corresponding capitalized _Count values modulo prealloc_bufsz.
- * These correspond to byte indices in the physical buffer. The modulo
- * operation is done by subtracting prealloc_bufsz when the value
- * exceeds prealloc_bufsz (assuming prealloc_bufsz plus the increment is
- * less than or equal to UINT_MAX).
- */
-struct comedi_async {
- void *prealloc_buf;
- unsigned int prealloc_bufsz;
- struct comedi_buf_map *buf_map;
- unsigned int max_bufsize;
- unsigned int buf_write_count;
- unsigned int buf_write_alloc_count;
- unsigned int buf_read_count;
- unsigned int buf_read_alloc_count;
- unsigned int buf_write_ptr;
- unsigned int buf_read_ptr;
- unsigned int cur_chan;
- unsigned int scans_done;
- unsigned int scan_progress;
- unsigned int munge_chan;
- unsigned int munge_count;
- unsigned int munge_ptr;
- unsigned int events;
- struct comedi_cmd cmd;
- wait_queue_head_t wait_head;
- unsigned int cb_mask;
- int (*inttrig)(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int x);
-};
-
-/**
- * enum comedi_cb - &struct comedi_async callback "events"
- * @COMEDI_CB_EOS: end-of-scan
- * @COMEDI_CB_EOA: end-of-acquisition/output
- * @COMEDI_CB_BLOCK: data has arrived, wakes up read() / write()
- * @COMEDI_CB_EOBUF: DEPRECATED: end of buffer
- * @COMEDI_CB_ERROR: card error during acquisition
- * @COMEDI_CB_OVERFLOW: buffer overflow/underflow
- * @COMEDI_CB_ERROR_MASK: events that indicate an error has occurred
- * @COMEDI_CB_CANCEL_MASK: events that will cancel an async command
- */
-enum comedi_cb {
- COMEDI_CB_EOS = BIT(0),
- COMEDI_CB_EOA = BIT(1),
- COMEDI_CB_BLOCK = BIT(2),
- COMEDI_CB_EOBUF = BIT(3),
- COMEDI_CB_ERROR = BIT(4),
- COMEDI_CB_OVERFLOW = BIT(5),
- /* masks */
- COMEDI_CB_ERROR_MASK = (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW),
- COMEDI_CB_CANCEL_MASK = (COMEDI_CB_EOA | COMEDI_CB_ERROR_MASK)
-};
-
-/**
- * struct comedi_driver - COMEDI driver registration
- * @driver_name: Name of driver.
- * @module: Owning module.
- * @attach: The optional "attach" handler for manually configured COMEDI
- * devices.
- * @detach: The "detach" handler for deconfiguring COMEDI devices.
- * @auto_attach: The optional "auto_attach" handler for automatically
- * configured COMEDI devices.
- * @num_names: Optional number of "board names" supported.
- * @board_name: Optional pointer to a pointer to a board name. The pointer
- * to a board name is embedded in an element of a driver-defined array
- * of static, read-only board type information.
- * @offset: Optional size of each element of the driver-defined array of
- * static, read-only board type information, i.e. the offset between each
- * pointer to a board name.
- *
- * This is used with comedi_driver_register() and comedi_driver_unregister() to
- * register and unregister a low-level COMEDI driver with the COMEDI core.
- *
- * If @num_names is non-zero, @board_name should be non-NULL, and @offset
- * should be at least sizeof(*board_name). These are used by the handler for
- * the %COMEDI_DEVCONFIG ioctl to match a hardware device and its driver by
- * board name. If @num_names is zero, the %COMEDI_DEVCONFIG ioctl matches a
- * hardware device and its driver by driver name. This is only useful if the
- * @attach handler is set. If @num_names is non-zero, the driver's @attach
- * handler will be called with the COMEDI device structure's board_ptr member
- * pointing to the matched pointer to a board name within the driver's private
- * array of static, read-only board type information.
- *
- * The @detach handler has two roles. If a COMEDI device was successfully
- * configured by the @attach or @auto_attach handler, it is called when the
- * device is being deconfigured (by the %COMEDI_DEVCONFIG ioctl, or due to
- * unloading of the driver, or due to device removal). It is also called when
- * the @attach or @auto_attach handler returns an error. Therefore, the
- * @attach or @auto_attach handlers can defer clean-up on error until the
- * @detach handler is called. If the @attach or @auto_attach handlers free
- * any resources themselves, they must prevent the @detach handler from
- * freeing the same resources. The @detach handler must not assume that all
- * resources requested by the @attach or @auto_attach handler were
- * successfully allocated.
- */
-struct comedi_driver {
- /* private: */
- struct comedi_driver *next; /* Next in list of COMEDI drivers. */
- /* public: */
- const char *driver_name;
- struct module *module;
- int (*attach)(struct comedi_device *dev, struct comedi_devconfig *it);
- void (*detach)(struct comedi_device *dev);
- int (*auto_attach)(struct comedi_device *dev, unsigned long context);
- unsigned int num_names;
- const char *const *board_name;
- int offset;
-};
-
-/**
- * struct comedi_device - Working data for a COMEDI device
- * @use_count: Number of open file objects.
- * @driver: Low-level COMEDI driver attached to this COMEDI device.
- * @pacer: Optional pointer to a dynamically allocated acquisition pacer
- * control. It is freed automatically after the COMEDI device is
- * detached from the low-level driver.
- * @private: Optional pointer to private data allocated by the low-level
- * driver. It is freed automatically after the COMEDI device is
- * detached from the low-level driver.
- * @class_dev: Sysfs comediX device.
- * @minor: Minor device number of COMEDI char device (0-47).
- * @detach_count: Counter incremented every time the COMEDI device is detached.
- * Used for checking a previous attachment is still valid.
- * @hw_dev: Optional pointer to the low-level hardware &struct device. It is
- * required for automatically configured COMEDI devices and optional for
- * COMEDI devices configured by the %COMEDI_DEVCONFIG ioctl, although
- * the bus-specific COMEDI functions only work if it is set correctly.
- * It is also passed to dma_alloc_coherent() for COMEDI subdevices that
- * have their 'async_dma_dir' member set to something other than
- * %DMA_NONE.
- * @board_name: Pointer to a COMEDI board name or a COMEDI driver name. When
- * the low-level driver's "attach" handler is called by the handler for
- * the %COMEDI_DEVCONFIG ioctl, it either points to a matched board name
- * string if the 'num_names' member of the &struct comedi_driver is
- * non-zero, otherwise it points to the low-level driver name string.
- * When the low-lever driver's "auto_attach" handler is called for an
- * automatically configured COMEDI device, it points to the low-level
- * driver name string. The low-level driver is free to change it in its
- * "attach" or "auto_attach" handler if it wishes.
- * @board_ptr: Optional pointer to private, read-only board type information in
- * the low-level driver. If the 'num_names' member of the &struct
- * comedi_driver is non-zero, the handler for the %COMEDI_DEVCONFIG ioctl
- * will point it to a pointer to a matched board name string within the
- * driver's private array of static, read-only board type information when
- * calling the driver's "attach" handler. The low-level driver is free to
- * change it.
- * @attached: Flag indicating that the COMEDI device is attached to a low-level
- * driver.
- * @ioenabled: Flag used to indicate that a PCI device has been enabled and
- * its regions requested.
- * @spinlock: Generic spin-lock for use by the low-level driver.
- * @mutex: Generic mutex for use by the COMEDI core module.
- * @attach_lock: &struct rw_semaphore used to guard against the COMEDI device
- * being detached while an operation is in progress. The down_write()
- * operation is only allowed while @mutex is held and is used when
- * changing @attached and @detach_count and calling the low-level driver's
- * "detach" handler. The down_read() operation is generally used without
- * holding @mutex.
- * @refcount: &struct kref reference counter for freeing COMEDI device.
- * @n_subdevices: Number of COMEDI subdevices allocated by the low-level
- * driver for this device.
- * @subdevices: Dynamically allocated array of COMEDI subdevices.
- * @mmio: Optional pointer to a remapped MMIO region set by the low-level
- * driver.
- * @iobase: Optional base of an I/O port region requested by the low-level
- * driver.
- * @iolen: Length of I/O port region requested at @iobase.
- * @irq: Optional IRQ number requested by the low-level driver.
- * @read_subdev: Optional pointer to a default COMEDI subdevice operated on by
- * the read() file operation. Set by the low-level driver.
- * @write_subdev: Optional pointer to a default COMEDI subdevice operated on by
- * the write() file operation. Set by the low-level driver.
- * @async_queue: Storage for fasync_helper().
- * @open: Optional pointer to a function set by the low-level driver to be
- * called when @use_count changes from 0 to 1.
- * @close: Optional pointer to a function set by the low-level driver to be
- * called when @use_count changed from 1 to 0.
- * @insn_device_config: Optional pointer to a handler for all sub-instructions
- * except %INSN_DEVICE_CONFIG_GET_ROUTES of the %INSN_DEVICE_CONFIG
- * instruction. If this is not initialized by the low-level driver, a
- * default handler will be set during post-configuration.
- * @get_valid_routes: Optional pointer to a handler for the
- * %INSN_DEVICE_CONFIG_GET_ROUTES sub-instruction of the
- * %INSN_DEVICE_CONFIG instruction set. If this is not initialized by the
- * low-level driver, a default handler that copies zero routes back to the
- * user will be used.
- *
- * This is the main control data structure for a COMEDI device (as far as the
- * COMEDI core is concerned). There are two groups of COMEDI devices -
- * "legacy" devices that are configured by the handler for the
- * %COMEDI_DEVCONFIG ioctl, and automatically configured devices resulting
- * from a call to comedi_auto_config() as a result of a bus driver probe in
- * a low-level COMEDI driver. The "legacy" COMEDI devices are allocated
- * during module initialization if the "comedi_num_legacy_minors" module
- * parameter is non-zero and use minor device numbers from 0 to
- * comedi_num_legacy_minors minus one. The automatically configured COMEDI
- * devices are allocated on demand and use minor device numbers from
- * comedi_num_legacy_minors to 47.
- */
-struct comedi_device {
- int use_count;
- struct comedi_driver *driver;
- struct comedi_8254 *pacer;
- void *private;
-
- struct device *class_dev;
- int minor;
- unsigned int detach_count;
- struct device *hw_dev;
-
- const char *board_name;
- const void *board_ptr;
- unsigned int attached:1;
- unsigned int ioenabled:1;
- spinlock_t spinlock; /* generic spin-lock for low-level driver */
- struct mutex mutex; /* generic mutex for COMEDI core */
- struct rw_semaphore attach_lock;
- struct kref refcount;
-
- int n_subdevices;
- struct comedi_subdevice *subdevices;
-
- /* dumb */
- void __iomem *mmio;
- unsigned long iobase;
- unsigned long iolen;
- unsigned int irq;
-
- struct comedi_subdevice *read_subdev;
- struct comedi_subdevice *write_subdev;
-
- struct fasync_struct *async_queue;
-
- int (*open)(struct comedi_device *dev);
- void (*close)(struct comedi_device *dev);
- int (*insn_device_config)(struct comedi_device *dev,
- struct comedi_insn *insn, unsigned int *data);
- unsigned int (*get_valid_routes)(struct comedi_device *dev,
- unsigned int n_pairs,
- unsigned int *pair_data);
-};
-
-/*
- * function prototypes
- */
-
-void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
-
-struct comedi_device *comedi_dev_get_from_minor(unsigned int minor);
-int comedi_dev_put(struct comedi_device *dev);
-
-bool comedi_is_subdevice_running(struct comedi_subdevice *s);
-
-void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size);
-void comedi_set_spriv_auto_free(struct comedi_subdevice *s);
-
-int comedi_check_chanlist(struct comedi_subdevice *s,
- int n,
- unsigned int *chanlist);
-
-/* range stuff */
-
-#define RANGE(a, b) {(a) * 1e6, (b) * 1e6, 0}
-#define RANGE_ext(a, b) {(a) * 1e6, (b) * 1e6, RF_EXTERNAL}
-#define RANGE_mA(a, b) {(a) * 1e6, (b) * 1e6, UNIT_mA}
-#define RANGE_unitless(a, b) {(a) * 1e6, (b) * 1e6, 0}
-#define BIP_RANGE(a) {-(a) * 1e6, (a) * 1e6, 0}
-#define UNI_RANGE(a) {0, (a) * 1e6, 0}
-
-extern const struct comedi_lrange range_bipolar10;
-extern const struct comedi_lrange range_bipolar5;
-extern const struct comedi_lrange range_bipolar2_5;
-extern const struct comedi_lrange range_unipolar10;
-extern const struct comedi_lrange range_unipolar5;
-extern const struct comedi_lrange range_unipolar2_5;
-extern const struct comedi_lrange range_0_20mA;
-extern const struct comedi_lrange range_4_20mA;
-extern const struct comedi_lrange range_0_32mA;
-extern const struct comedi_lrange range_unknown;
-
-#define range_digital range_unipolar5
-
-/**
- * struct comedi_lrange - Describes a COMEDI range table
- * @length: Number of entries in the range table.
- * @range: Array of &struct comedi_krange, one for each range.
- *
- * Each element of @range[] describes the minimum and maximum physical range
- * and the type of units. Typically, the type of unit is %UNIT_volt
- * (i.e. volts) and the minimum and maximum are in millionths of a volt.
- * There may also be a flag that indicates the minimum and maximum are merely
- * scale factors for an unknown, external reference.
- */
-struct comedi_lrange {
- int length;
- struct comedi_krange range[];
-};
-
-/**
- * comedi_range_is_bipolar() - Test if subdevice range is bipolar
- * @s: COMEDI subdevice.
- * @range: Index of range within a range table.
- *
- * Tests whether a range is bipolar by checking whether its minimum value
- * is negative.
- *
- * Assumes @range is valid. Does not work for subdevices using a
- * channel-specific range table list.
- *
- * Return:
- * %true if the range is bipolar.
- * %false if the range is unipolar.
- */
-static inline bool comedi_range_is_bipolar(struct comedi_subdevice *s,
- unsigned int range)
-{
- return s->range_table->range[range].min < 0;
-}
-
-/**
- * comedi_range_is_unipolar() - Test if subdevice range is unipolar
- * @s: COMEDI subdevice.
- * @range: Index of range within a range table.
- *
- * Tests whether a range is unipolar by checking whether its minimum value
- * is at least 0.
- *
- * Assumes @range is valid. Does not work for subdevices using a
- * channel-specific range table list.
- *
- * Return:
- * %true if the range is unipolar.
- * %false if the range is bipolar.
- */
-static inline bool comedi_range_is_unipolar(struct comedi_subdevice *s,
- unsigned int range)
-{
- return s->range_table->range[range].min >= 0;
-}
-
-/**
- * comedi_range_is_external() - Test if subdevice range is external
- * @s: COMEDI subdevice.
- * @range: Index of range within a range table.
- *
- * Tests whether a range is externally reference by checking whether its
- * %RF_EXTERNAL flag is set.
- *
- * Assumes @range is valid. Does not work for subdevices using a
- * channel-specific range table list.
- *
- * Return:
- * %true if the range is external.
- * %false if the range is internal.
- */
-static inline bool comedi_range_is_external(struct comedi_subdevice *s,
- unsigned int range)
-{
- return !!(s->range_table->range[range].flags & RF_EXTERNAL);
-}
-
-/**
- * comedi_chan_range_is_bipolar() - Test if channel-specific range is bipolar
- * @s: COMEDI subdevice.
- * @chan: The channel number.
- * @range: Index of range within a range table.
- *
- * Tests whether a range is bipolar by checking whether its minimum value
- * is negative.
- *
- * Assumes @chan and @range are valid. Only works for subdevices with a
- * channel-specific range table list.
- *
- * Return:
- * %true if the range is bipolar.
- * %false if the range is unipolar.
- */
-static inline bool comedi_chan_range_is_bipolar(struct comedi_subdevice *s,
- unsigned int chan,
- unsigned int range)
-{
- return s->range_table_list[chan]->range[range].min < 0;
-}
-
-/**
- * comedi_chan_range_is_unipolar() - Test if channel-specific range is unipolar
- * @s: COMEDI subdevice.
- * @chan: The channel number.
- * @range: Index of range within a range table.
- *
- * Tests whether a range is unipolar by checking whether its minimum value
- * is at least 0.
- *
- * Assumes @chan and @range are valid. Only works for subdevices with a
- * channel-specific range table list.
- *
- * Return:
- * %true if the range is unipolar.
- * %false if the range is bipolar.
- */
-static inline bool comedi_chan_range_is_unipolar(struct comedi_subdevice *s,
- unsigned int chan,
- unsigned int range)
-{
- return s->range_table_list[chan]->range[range].min >= 0;
-}
-
-/**
- * comedi_chan_range_is_external() - Test if channel-specific range is external
- * @s: COMEDI subdevice.
- * @chan: The channel number.
- * @range: Index of range within a range table.
- *
- * Tests whether a range is externally reference by checking whether its
- * %RF_EXTERNAL flag is set.
- *
- * Assumes @chan and @range are valid. Only works for subdevices with a
- * channel-specific range table list.
- *
- * Return:
- * %true if the range is bipolar.
- * %false if the range is unipolar.
- */
-static inline bool comedi_chan_range_is_external(struct comedi_subdevice *s,
- unsigned int chan,
- unsigned int range)
-{
- return !!(s->range_table_list[chan]->range[range].flags & RF_EXTERNAL);
-}
-
-/**
- * comedi_offset_munge() - Convert between offset binary and 2's complement
- * @s: COMEDI subdevice.
- * @val: Value to be converted.
- *
- * Toggles the highest bit of a sample value to toggle between offset binary
- * and 2's complement. Assumes that @s->maxdata is a power of 2 minus 1.
- *
- * Return: The converted value.
- */
-static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s,
- unsigned int val)
-{
- return val ^ s->maxdata ^ (s->maxdata >> 1);
-}
-
-/**
- * comedi_bytes_per_sample() - Determine subdevice sample size
- * @s: COMEDI subdevice.
- *
- * The sample size will be 4 (sizeof int) or 2 (sizeof short) depending on
- * whether the %SDF_LSAMPL subdevice flag is set or not.
- *
- * Return: The subdevice sample size.
- */
-static inline unsigned int comedi_bytes_per_sample(struct comedi_subdevice *s)
-{
- return s->subdev_flags & SDF_LSAMPL ? sizeof(int) : sizeof(short);
-}
-
-/**
- * comedi_sample_shift() - Determine log2 of subdevice sample size
- * @s: COMEDI subdevice.
- *
- * The sample size will be 4 (sizeof int) or 2 (sizeof short) depending on
- * whether the %SDF_LSAMPL subdevice flag is set or not. The log2 of the
- * sample size will be 2 or 1 and can be used as the right operand of a
- * bit-shift operator to multiply or divide something by the sample size.
- *
- * Return: log2 of the subdevice sample size.
- */
-static inline unsigned int comedi_sample_shift(struct comedi_subdevice *s)
-{
- return s->subdev_flags & SDF_LSAMPL ? 2 : 1;
-}
-
-/**
- * comedi_bytes_to_samples() - Convert a number of bytes to a number of samples
- * @s: COMEDI subdevice.
- * @nbytes: Number of bytes
- *
- * Return: The number of bytes divided by the subdevice sample size.
- */
-static inline unsigned int comedi_bytes_to_samples(struct comedi_subdevice *s,
- unsigned int nbytes)
-{
- return nbytes >> comedi_sample_shift(s);
-}
-
-/**
- * comedi_samples_to_bytes() - Convert a number of samples to a number of bytes
- * @s: COMEDI subdevice.
- * @nsamples: Number of samples.
- *
- * Return: The number of samples multiplied by the subdevice sample size.
- * (Does not check for arithmetic overflow.)
- */
-static inline unsigned int comedi_samples_to_bytes(struct comedi_subdevice *s,
- unsigned int nsamples)
-{
- return nsamples << comedi_sample_shift(s);
-}
-
-/**
- * comedi_check_trigger_src() - Trivially validate a comedi_cmd trigger source
- * @src: Pointer to the trigger source to validate.
- * @flags: Bitmask of valid %TRIG_* for the trigger.
- *
- * This is used in "step 1" of the do_cmdtest functions of comedi drivers
- * to validate the comedi_cmd triggers. The mask of the @src against the
- * @flags allows the userspace comedilib to pass all the comedi_cmd
- * triggers as %TRIG_ANY and get back a bitmask of the valid trigger sources.
- *
- * Return:
- * 0 if trigger sources in *@src are all supported.
- * -EINVAL if any trigger source in *@src is unsupported.
- */
-static inline int comedi_check_trigger_src(unsigned int *src,
- unsigned int flags)
-{
- unsigned int orig_src = *src;
-
- *src = orig_src & flags;
- if (*src == TRIG_INVALID || *src != orig_src)
- return -EINVAL;
- return 0;
-}
-
-/**
- * comedi_check_trigger_is_unique() - Make sure a trigger source is unique
- * @src: The trigger source to check.
- *
- * Return:
- * 0 if no more than one trigger source is set.
- * -EINVAL if more than one trigger source is set.
- */
-static inline int comedi_check_trigger_is_unique(unsigned int src)
-{
- /* this test is true if more than one _src bit is set */
- if ((src & (src - 1)) != 0)
- return -EINVAL;
- return 0;
-}
-
-/**
- * comedi_check_trigger_arg_is() - Trivially validate a trigger argument
- * @arg: Pointer to the trigger arg to validate.
- * @val: The value the argument should be.
- *
- * Forces *@arg to be @val.
- *
- * Return:
- * 0 if *@arg was already @val.
- * -EINVAL if *@arg differed from @val.
- */
-static inline int comedi_check_trigger_arg_is(unsigned int *arg,
- unsigned int val)
-{
- if (*arg != val) {
- *arg = val;
- return -EINVAL;
- }
- return 0;
-}
-
-/**
- * comedi_check_trigger_arg_min() - Trivially validate a trigger argument min
- * @arg: Pointer to the trigger arg to validate.
- * @val: The minimum value the argument should be.
- *
- * Forces *@arg to be at least @val, setting it to @val if necessary.
- *
- * Return:
- * 0 if *@arg was already at least @val.
- * -EINVAL if *@arg was less than @val.
- */
-static inline int comedi_check_trigger_arg_min(unsigned int *arg,
- unsigned int val)
-{
- if (*arg < val) {
- *arg = val;
- return -EINVAL;
- }
- return 0;
-}
-
-/**
- * comedi_check_trigger_arg_max() - Trivially validate a trigger argument max
- * @arg: Pointer to the trigger arg to validate.
- * @val: The maximum value the argument should be.
- *
- * Forces *@arg to be no more than @val, setting it to @val if necessary.
- *
- * Return:
- * 0 if*@arg was already no more than @val.
- * -EINVAL if *@arg was greater than @val.
- */
-static inline int comedi_check_trigger_arg_max(unsigned int *arg,
- unsigned int val)
-{
- if (*arg > val) {
- *arg = val;
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * Must set dev->hw_dev if you wish to dma directly into comedi's buffer.
- * Also useful for retrieving a previously configured hardware device of
- * known bus type. Set automatically for auto-configured devices.
- * Automatically set to NULL when detaching hardware device.
- */
-int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev);
-
-/**
- * comedi_buf_n_bytes_ready - Determine amount of unread data in buffer
- * @s: COMEDI subdevice.
- *
- * Determines the number of bytes of unread data in the asynchronous
- * acquisition data buffer for a subdevice. The data in question might not
- * have been fully "munged" yet.
- *
- * Returns: The amount of unread data in bytes.
- */
-static inline unsigned int comedi_buf_n_bytes_ready(struct comedi_subdevice *s)
-{
- return s->async->buf_write_count - s->async->buf_read_count;
-}
-
-unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, unsigned int n);
-unsigned int comedi_buf_write_free(struct comedi_subdevice *s, unsigned int n);
-
-unsigned int comedi_buf_read_n_available(struct comedi_subdevice *s);
-unsigned int comedi_buf_read_alloc(struct comedi_subdevice *s, unsigned int n);
-unsigned int comedi_buf_read_free(struct comedi_subdevice *s, unsigned int n);
-
-unsigned int comedi_buf_write_samples(struct comedi_subdevice *s,
- const void *data, unsigned int nsamples);
-unsigned int comedi_buf_read_samples(struct comedi_subdevice *s,
- void *data, unsigned int nsamples);
-
-/* drivers.c - general comedi driver functions */
-
-#define COMEDI_TIMEOUT_MS 1000
-
-int comedi_timeout(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn,
- int (*cb)(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned long context),
- unsigned long context);
-
-unsigned int comedi_handle_events(struct comedi_device *dev,
- struct comedi_subdevice *s);
-
-int comedi_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data,
- unsigned int mask);
-unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
- unsigned int *data);
-unsigned int comedi_bytes_per_scan_cmd(struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s);
-unsigned int comedi_nscans_left(struct comedi_subdevice *s,
- unsigned int nscans);
-unsigned int comedi_nsamples_left(struct comedi_subdevice *s,
- unsigned int nsamples);
-void comedi_inc_scan_progress(struct comedi_subdevice *s,
- unsigned int num_bytes);
-
-void *comedi_alloc_devpriv(struct comedi_device *dev, size_t size);
-int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices);
-int comedi_alloc_subdev_readback(struct comedi_subdevice *s);
-
-int comedi_readback_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-int comedi_load_firmware(struct comedi_device *dev, struct device *hw_dev,
- const char *name,
- int (*cb)(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context),
- unsigned long context);
-
-int __comedi_request_region(struct comedi_device *dev,
- unsigned long start, unsigned long len);
-int comedi_request_region(struct comedi_device *dev,
- unsigned long start, unsigned long len);
-void comedi_legacy_detach(struct comedi_device *dev);
-
-int comedi_auto_config(struct device *hardware_device,
- struct comedi_driver *driver, unsigned long context);
-void comedi_auto_unconfig(struct device *hardware_device);
-
-int comedi_driver_register(struct comedi_driver *driver);
-void comedi_driver_unregister(struct comedi_driver *driver);
-
-/**
- * module_comedi_driver() - Helper macro for registering a comedi driver
- * @__comedi_driver: comedi_driver struct
- *
- * Helper macro for comedi drivers which do not do anything special in module
- * init/exit. This eliminates a lot of boilerplate. Each module may only use
- * this macro once, and calling it replaces module_init() and module_exit().
- */
-#define module_comedi_driver(__comedi_driver) \
- module_driver(__comedi_driver, comedi_driver_register, \
- comedi_driver_unregister)
-
-#endif /* _COMEDIDEV_H */
diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h
deleted file mode 100644
index 0223c9cd9215..000000000000
--- a/drivers/staging/comedi/comedilib.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedilib.h
- * Header file for kcomedilib
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _LINUX_COMEDILIB_H
-#define _LINUX_COMEDILIB_H
-
-struct comedi_device *comedi_open(const char *path);
-int comedi_close(struct comedi_device *dev);
-int comedi_dio_get_config(struct comedi_device *dev, unsigned int subdev,
- unsigned int chan, unsigned int *io);
-int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
- unsigned int chan, unsigned int io);
-int comedi_dio_bitfield2(struct comedi_device *dev, unsigned int subdev,
- unsigned int mask, unsigned int *bits,
- unsigned int base_channel);
-int comedi_find_subdevice_by_type(struct comedi_device *dev, int type,
- unsigned int subd);
-int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice);
-
-#endif
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
deleted file mode 100644
index 750a6ff3c03c..000000000000
--- a/drivers/staging/comedi/drivers.c
+++ /dev/null
@@ -1,1184 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * module/drivers.c
- * functions for manipulating drivers
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/dma-direction.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-
-#include "comedidev.h"
-#include "comedi_internal.h"
-
-struct comedi_driver *comedi_drivers;
-/* protects access to comedi_drivers */
-DEFINE_MUTEX(comedi_drivers_list_lock);
-
-/**
- * comedi_set_hw_dev() - Set hardware device associated with COMEDI device
- * @dev: COMEDI device.
- * @hw_dev: Hardware device.
- *
- * For automatically configured COMEDI devices (resulting from a call to
- * comedi_auto_config() or one of its wrappers from the low-level COMEDI
- * driver), comedi_set_hw_dev() is called automatically by the COMEDI core
- * to associate the COMEDI device with the hardware device. It can also be
- * called directly by "legacy" low-level COMEDI drivers that rely on the
- * %COMEDI_DEVCONFIG ioctl to configure the hardware as long as the hardware
- * has a &struct device.
- *
- * If @dev->hw_dev is NULL, it gets a reference to @hw_dev and sets
- * @dev->hw_dev, otherwise, it does nothing. Calling it multiple times
- * with the same hardware device is not considered an error. If it gets
- * a reference to the hardware device, it will be automatically 'put' when
- * the device is detached from COMEDI.
- *
- * Returns 0 if @dev->hw_dev was NULL or the same as @hw_dev, otherwise
- * returns -EEXIST.
- */
-int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
-{
- if (hw_dev == dev->hw_dev)
- return 0;
- if (dev->hw_dev)
- return -EEXIST;
- dev->hw_dev = get_device(hw_dev);
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_set_hw_dev);
-
-static void comedi_clear_hw_dev(struct comedi_device *dev)
-{
- put_device(dev->hw_dev);
- dev->hw_dev = NULL;
-}
-
-/**
- * comedi_alloc_devpriv() - Allocate memory for the device private data
- * @dev: COMEDI device.
- * @size: Size of the memory to allocate.
- *
- * The allocated memory is zero-filled. @dev->private points to it on
- * return. The memory will be automatically freed when the COMEDI device is
- * "detached".
- *
- * Returns a pointer to the allocated memory, or NULL on failure.
- */
-void *comedi_alloc_devpriv(struct comedi_device *dev, size_t size)
-{
- dev->private = kzalloc(size, GFP_KERNEL);
- return dev->private;
-}
-EXPORT_SYMBOL_GPL(comedi_alloc_devpriv);
-
-/**
- * comedi_alloc_subdevices() - Allocate subdevices for COMEDI device
- * @dev: COMEDI device.
- * @num_subdevices: Number of subdevices to allocate.
- *
- * Allocates and initializes an array of &struct comedi_subdevice for the
- * COMEDI device. If successful, sets @dev->subdevices to point to the
- * first one and @dev->n_subdevices to the number.
- *
- * Returns 0 on success, -EINVAL if @num_subdevices is < 1, or -ENOMEM if
- * failed to allocate the memory.
- */
-int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)
-{
- struct comedi_subdevice *s;
- int i;
-
- if (num_subdevices < 1)
- return -EINVAL;
-
- s = kcalloc(num_subdevices, sizeof(*s), GFP_KERNEL);
- if (!s)
- return -ENOMEM;
- dev->subdevices = s;
- dev->n_subdevices = num_subdevices;
-
- for (i = 0; i < num_subdevices; ++i) {
- s = &dev->subdevices[i];
- s->device = dev;
- s->index = i;
- s->async_dma_dir = DMA_NONE;
- spin_lock_init(&s->spin_lock);
- s->minor = -1;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);
-
-/**
- * comedi_alloc_subdev_readback() - Allocate memory for the subdevice readback
- * @s: COMEDI subdevice.
- *
- * This is called by low-level COMEDI drivers to allocate an array to record
- * the last values written to a subdevice's analog output channels (at least
- * by the %INSN_WRITE instruction), to allow them to be read back by an
- * %INSN_READ instruction. It also provides a default handler for the
- * %INSN_READ instruction unless one has already been set.
- *
- * On success, @s->readback points to the first element of the array, which
- * is zero-filled. The low-level driver is responsible for updating its
- * contents. @s->insn_read will be set to comedi_readback_insn_read()
- * unless it is already non-NULL.
- *
- * Returns 0 on success, -EINVAL if the subdevice has no channels, or
- * -ENOMEM on allocation failure.
- */
-int comedi_alloc_subdev_readback(struct comedi_subdevice *s)
-{
- if (!s->n_chan)
- return -EINVAL;
-
- s->readback = kcalloc(s->n_chan, sizeof(*s->readback), GFP_KERNEL);
- if (!s->readback)
- return -ENOMEM;
-
- if (!s->insn_read)
- s->insn_read = comedi_readback_insn_read;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_alloc_subdev_readback);
-
-static void comedi_device_detach_cleanup(struct comedi_device *dev)
-{
- int i;
- struct comedi_subdevice *s;
-
- lockdep_assert_held(&dev->attach_lock);
- lockdep_assert_held(&dev->mutex);
- if (dev->subdevices) {
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- if (comedi_can_auto_free_spriv(s))
- kfree(s->private);
- comedi_free_subdevice_minor(s);
- if (s->async) {
- comedi_buf_alloc(dev, s, 0);
- kfree(s->async);
- }
- kfree(s->readback);
- }
- kfree(dev->subdevices);
- dev->subdevices = NULL;
- dev->n_subdevices = 0;
- }
- kfree(dev->private);
- kfree(dev->pacer);
- dev->private = NULL;
- dev->pacer = NULL;
- dev->driver = NULL;
- dev->board_name = NULL;
- dev->board_ptr = NULL;
- dev->mmio = NULL;
- dev->iobase = 0;
- dev->iolen = 0;
- dev->ioenabled = false;
- dev->irq = 0;
- dev->read_subdev = NULL;
- dev->write_subdev = NULL;
- dev->open = NULL;
- dev->close = NULL;
- comedi_clear_hw_dev(dev);
-}
-
-void comedi_device_detach(struct comedi_device *dev)
-{
- lockdep_assert_held(&dev->mutex);
- comedi_device_cancel_all(dev);
- down_write(&dev->attach_lock);
- dev->attached = false;
- dev->detach_count++;
- if (dev->driver)
- dev->driver->detach(dev);
- comedi_device_detach_cleanup(dev);
- up_write(&dev->attach_lock);
-}
-
-static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- return -EINVAL;
-}
-
-static int insn_device_inval(struct comedi_device *dev,
- struct comedi_insn *insn, unsigned int *data)
-{
- return -EINVAL;
-}
-
-static unsigned int get_zero_valid_routes(struct comedi_device *dev,
- unsigned int n_pairs,
- unsigned int *pair_data)
-{
- return 0;
-}
-
-int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- return -EINVAL;
-}
-
-/**
- * comedi_readback_insn_read() - A generic (*insn_read) for subdevice readback.
- * @dev: COMEDI device.
- * @s: COMEDI subdevice.
- * @insn: COMEDI instruction.
- * @data: Pointer to return the readback data.
- *
- * Handles the %INSN_READ instruction for subdevices that use the readback
- * array allocated by comedi_alloc_subdev_readback(). It may be used
- * directly as the subdevice's handler (@s->insn_read) or called via a
- * wrapper.
- *
- * @insn->n is normally 1, which will read a single value. If higher, the
- * same element of the readback array will be read multiple times.
- *
- * Returns @insn->n on success, or -EINVAL if @s->readback is NULL.
- */
-int comedi_readback_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- if (!s->readback)
- return -EINVAL;
-
- for (i = 0; i < insn->n; i++)
- data[i] = s->readback[chan];
-
- return insn->n;
-}
-EXPORT_SYMBOL_GPL(comedi_readback_insn_read);
-
-/**
- * comedi_timeout() - Busy-wait for a driver condition to occur
- * @dev: COMEDI device.
- * @s: COMEDI subdevice.
- * @insn: COMEDI instruction.
- * @cb: Callback to check for the condition.
- * @context: Private context from the driver.
- *
- * Busy-waits for up to a second (%COMEDI_TIMEOUT_MS) for the condition or
- * some error (other than -EBUSY) to occur. The parameters @dev, @s, @insn,
- * and @context are passed to the callback function, which returns -EBUSY to
- * continue waiting or some other value to stop waiting (generally 0 if the
- * condition occurred, or some error value).
- *
- * Returns -ETIMEDOUT if timed out, otherwise the return value from the
- * callback function.
- */
-int comedi_timeout(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- int (*cb)(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context),
- unsigned long context)
-{
- unsigned long timeout = jiffies + msecs_to_jiffies(COMEDI_TIMEOUT_MS);
- int ret;
-
- while (time_before(jiffies, timeout)) {
- ret = cb(dev, s, insn, context);
- if (ret != -EBUSY)
- return ret; /* success (0) or non EBUSY errno */
- cpu_relax();
- }
- return -ETIMEDOUT;
-}
-EXPORT_SYMBOL_GPL(comedi_timeout);
-
-/**
- * comedi_dio_insn_config() - Boilerplate (*insn_config) for DIO subdevices
- * @dev: COMEDI device.
- * @s: COMEDI subdevice.
- * @insn: COMEDI instruction.
- * @data: Instruction parameters and return data.
- * @mask: io_bits mask for grouped channels, or 0 for single channel.
- *
- * If @mask is 0, it is replaced with a single-bit mask corresponding to the
- * channel number specified by @insn->chanspec. Otherwise, @mask
- * corresponds to a group of channels (which should include the specified
- * channel) that are always configured together as inputs or outputs.
- *
- * Partially handles the %INSN_CONFIG_DIO_INPUT, %INSN_CONFIG_DIO_OUTPUTS,
- * and %INSN_CONFIG_DIO_QUERY instructions. The first two update
- * @s->io_bits to record the directions of the masked channels. The last
- * one sets @data[1] to the current direction of the group of channels
- * (%COMEDI_INPUT) or %COMEDI_OUTPUT) as recorded in @s->io_bits.
- *
- * The caller is responsible for updating the DIO direction in the hardware
- * registers if this function returns 0.
- *
- * Returns 0 for a %INSN_CONFIG_DIO_INPUT or %INSN_CONFIG_DIO_OUTPUT
- * instruction, @insn->n (> 0) for a %INSN_CONFIG_DIO_QUERY instruction, or
- * -EINVAL for some other instruction.
- */
-int comedi_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data,
- unsigned int mask)
-{
- unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
-
- if (!mask)
- mask = chan_mask;
-
- switch (data[0]) {
- case INSN_CONFIG_DIO_INPUT:
- s->io_bits &= ~mask;
- break;
-
- case INSN_CONFIG_DIO_OUTPUT:
- s->io_bits |= mask;
- break;
-
- case INSN_CONFIG_DIO_QUERY:
- data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
- return insn->n;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_dio_insn_config);
-
-/**
- * comedi_dio_update_state() - Update the internal state of DIO subdevices
- * @s: COMEDI subdevice.
- * @data: The channel mask and bits to update.
- *
- * Updates @s->state which holds the internal state of the outputs for DIO
- * or DO subdevices (up to 32 channels). @data[0] contains a bit-mask of
- * the channels to be updated. @data[1] contains a bit-mask of those
- * channels to be set to '1'. The caller is responsible for updating the
- * outputs in hardware according to @s->state. As a minimum, the channels
- * in the returned bit-mask need to be updated.
- *
- * Returns @mask with non-existent channels removed.
- */
-unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
- unsigned int *data)
-{
- unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1)
- : 0xffffffff;
- unsigned int mask = data[0] & chanmask;
- unsigned int bits = data[1];
-
- if (mask) {
- s->state &= ~mask;
- s->state |= (bits & mask);
- }
-
- return mask;
-}
-EXPORT_SYMBOL_GPL(comedi_dio_update_state);
-
-/**
- * comedi_bytes_per_scan_cmd() - Get length of asynchronous command "scan" in
- * bytes
- * @s: COMEDI subdevice.
- * @cmd: COMEDI command.
- *
- * Determines the overall scan length according to the subdevice type and the
- * number of channels in the scan for the specified command.
- *
- * For digital input, output or input/output subdevices, samples for
- * multiple channels are assumed to be packed into one or more unsigned
- * short or unsigned int values according to the subdevice's %SDF_LSAMPL
- * flag. For other types of subdevice, samples are assumed to occupy a
- * whole unsigned short or unsigned int according to the %SDF_LSAMPL flag.
- *
- * Returns the overall scan length in bytes.
- */
-unsigned int comedi_bytes_per_scan_cmd(struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int num_samples;
- unsigned int bits_per_sample;
-
- switch (s->type) {
- case COMEDI_SUBD_DI:
- case COMEDI_SUBD_DO:
- case COMEDI_SUBD_DIO:
- bits_per_sample = 8 * comedi_bytes_per_sample(s);
- num_samples = DIV_ROUND_UP(cmd->scan_end_arg, bits_per_sample);
- break;
- default:
- num_samples = cmd->scan_end_arg;
- break;
- }
- return comedi_samples_to_bytes(s, num_samples);
-}
-EXPORT_SYMBOL_GPL(comedi_bytes_per_scan_cmd);
-
-/**
- * comedi_bytes_per_scan() - Get length of asynchronous command "scan" in bytes
- * @s: COMEDI subdevice.
- *
- * Determines the overall scan length according to the subdevice type and the
- * number of channels in the scan for the current command.
- *
- * For digital input, output or input/output subdevices, samples for
- * multiple channels are assumed to be packed into one or more unsigned
- * short or unsigned int values according to the subdevice's %SDF_LSAMPL
- * flag. For other types of subdevice, samples are assumed to occupy a
- * whole unsigned short or unsigned int according to the %SDF_LSAMPL flag.
- *
- * Returns the overall scan length in bytes.
- */
-unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- return comedi_bytes_per_scan_cmd(s, cmd);
-}
-EXPORT_SYMBOL_GPL(comedi_bytes_per_scan);
-
-static unsigned int __comedi_nscans_left(struct comedi_subdevice *s,
- unsigned int nscans)
-{
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
-
- if (cmd->stop_src == TRIG_COUNT) {
- unsigned int scans_left = 0;
-
- if (async->scans_done < cmd->stop_arg)
- scans_left = cmd->stop_arg - async->scans_done;
-
- if (nscans > scans_left)
- nscans = scans_left;
- }
- return nscans;
-}
-
-/**
- * comedi_nscans_left() - Return the number of scans left in the command
- * @s: COMEDI subdevice.
- * @nscans: The expected number of scans or 0 for all available scans.
- *
- * If @nscans is 0, it is set to the number of scans available in the
- * async buffer.
- *
- * If the async command has a stop_src of %TRIG_COUNT, the @nscans will be
- * checked against the number of scans remaining to complete the command.
- *
- * The return value will then be either the expected number of scans or the
- * number of scans remaining to complete the command, whichever is fewer.
- */
-unsigned int comedi_nscans_left(struct comedi_subdevice *s,
- unsigned int nscans)
-{
- if (nscans == 0) {
- unsigned int nbytes = comedi_buf_read_n_available(s);
-
- nscans = nbytes / comedi_bytes_per_scan(s);
- }
- return __comedi_nscans_left(s, nscans);
-}
-EXPORT_SYMBOL_GPL(comedi_nscans_left);
-
-/**
- * comedi_nsamples_left() - Return the number of samples left in the command
- * @s: COMEDI subdevice.
- * @nsamples: The expected number of samples.
- *
- * Returns the number of samples remaining to complete the command, or the
- * specified expected number of samples (@nsamples), whichever is fewer.
- */
-unsigned int comedi_nsamples_left(struct comedi_subdevice *s,
- unsigned int nsamples)
-{
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned long long scans_left;
- unsigned long long samples_left;
-
- if (cmd->stop_src != TRIG_COUNT)
- return nsamples;
-
- scans_left = __comedi_nscans_left(s, cmd->stop_arg);
- if (!scans_left)
- return 0;
-
- samples_left = scans_left * cmd->scan_end_arg -
- comedi_bytes_to_samples(s, async->scan_progress);
-
- if (samples_left < nsamples)
- return samples_left;
- return nsamples;
-}
-EXPORT_SYMBOL_GPL(comedi_nsamples_left);
-
-/**
- * comedi_inc_scan_progress() - Update scan progress in asynchronous command
- * @s: COMEDI subdevice.
- * @num_bytes: Amount of data in bytes to increment scan progress.
- *
- * Increments the scan progress by the number of bytes specified by @num_bytes.
- * If the scan progress reaches or exceeds the scan length in bytes, reduce
- * it modulo the scan length in bytes and set the "end of scan" asynchronous
- * event flag (%COMEDI_CB_EOS) to be processed later.
- */
-void comedi_inc_scan_progress(struct comedi_subdevice *s,
- unsigned int num_bytes)
-{
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int scan_length = comedi_bytes_per_scan(s);
-
- /* track the 'cur_chan' for non-SDF_PACKED subdevices */
- if (!(s->subdev_flags & SDF_PACKED)) {
- async->cur_chan += comedi_bytes_to_samples(s, num_bytes);
- async->cur_chan %= cmd->chanlist_len;
- }
-
- async->scan_progress += num_bytes;
- if (async->scan_progress >= scan_length) {
- unsigned int nscans = async->scan_progress / scan_length;
-
- if (async->scans_done < (UINT_MAX - nscans))
- async->scans_done += nscans;
- else
- async->scans_done = UINT_MAX;
-
- async->scan_progress %= scan_length;
- async->events |= COMEDI_CB_EOS;
- }
-}
-EXPORT_SYMBOL_GPL(comedi_inc_scan_progress);
-
-/**
- * comedi_handle_events() - Handle events and possibly stop acquisition
- * @dev: COMEDI device.
- * @s: COMEDI subdevice.
- *
- * Handles outstanding asynchronous acquisition event flags associated
- * with the subdevice. Call the subdevice's @s->cancel() handler if the
- * "end of acquisition", "error" or "overflow" event flags are set in order
- * to stop the acquisition at the driver level.
- *
- * Calls comedi_event() to further process the event flags, which may mark
- * the asynchronous command as no longer running, possibly terminated with
- * an error, and may wake up tasks.
- *
- * Return a bit-mask of the handled events.
- */
-unsigned int comedi_handle_events(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int events = s->async->events;
-
- if (events == 0)
- return events;
-
- if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel)
- s->cancel(dev, s);
-
- comedi_event(dev, s);
-
- return events;
-}
-EXPORT_SYMBOL_GPL(comedi_handle_events);
-
-static int insn_rw_emulate_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct comedi_insn _insn;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int base_chan = (chan < 32) ? 0 : chan;
- unsigned int _data[2];
- int ret;
-
- memset(_data, 0, sizeof(_data));
- memset(&_insn, 0, sizeof(_insn));
- _insn.insn = INSN_BITS;
- _insn.chanspec = base_chan;
- _insn.n = 2;
- _insn.subdev = insn->subdev;
-
- if (insn->insn == INSN_WRITE) {
- if (!(s->subdev_flags & SDF_WRITABLE))
- return -EINVAL;
- _data[0] = 1 << (chan - base_chan); /* mask */
- _data[1] = data[0] ? (1 << (chan - base_chan)) : 0; /* bits */
- }
-
- ret = s->insn_bits(dev, s, &_insn, _data);
- if (ret < 0)
- return ret;
-
- if (insn->insn == INSN_READ)
- data[0] = (_data[1] >> (chan - base_chan)) & 1;
-
- return 1;
-}
-
-static int __comedi_device_postconfig_async(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_async *async;
- unsigned int buf_size;
- int ret;
-
- lockdep_assert_held(&dev->mutex);
- if ((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0) {
- dev_warn(dev->class_dev,
- "async subdevices must support SDF_CMD_READ or SDF_CMD_WRITE\n");
- return -EINVAL;
- }
- if (!s->do_cmdtest) {
- dev_warn(dev->class_dev,
- "async subdevices must have a do_cmdtest() function\n");
- return -EINVAL;
- }
- if (!s->cancel)
- dev_warn(dev->class_dev,
- "async subdevices should have a cancel() function\n");
-
- async = kzalloc(sizeof(*async), GFP_KERNEL);
- if (!async)
- return -ENOMEM;
-
- init_waitqueue_head(&async->wait_head);
- s->async = async;
-
- async->max_bufsize = comedi_default_buf_maxsize_kb * 1024;
- buf_size = comedi_default_buf_size_kb * 1024;
- if (buf_size > async->max_bufsize)
- buf_size = async->max_bufsize;
-
- if (comedi_buf_alloc(dev, s, buf_size) < 0) {
- dev_warn(dev->class_dev, "Buffer allocation failed\n");
- return -ENOMEM;
- }
- if (s->buf_change) {
- ret = s->buf_change(dev, s);
- if (ret < 0)
- return ret;
- }
-
- comedi_alloc_subdevice_minor(s);
-
- return 0;
-}
-
-static int __comedi_device_postconfig(struct comedi_device *dev)
-{
- struct comedi_subdevice *s;
- int ret;
- int i;
-
- lockdep_assert_held(&dev->mutex);
- if (!dev->insn_device_config)
- dev->insn_device_config = insn_device_inval;
-
- if (!dev->get_valid_routes)
- dev->get_valid_routes = get_zero_valid_routes;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
-
- if (s->type == COMEDI_SUBD_UNUSED)
- continue;
-
- if (s->type == COMEDI_SUBD_DO) {
- if (s->n_chan < 32)
- s->io_bits = (1 << s->n_chan) - 1;
- else
- s->io_bits = 0xffffffff;
- }
-
- if (s->len_chanlist == 0)
- s->len_chanlist = 1;
-
- if (s->do_cmd) {
- ret = __comedi_device_postconfig_async(dev, s);
- if (ret)
- return ret;
- }
-
- if (!s->range_table && !s->range_table_list)
- s->range_table = &range_unknown;
-
- if (!s->insn_read && s->insn_bits)
- s->insn_read = insn_rw_emulate_bits;
- if (!s->insn_write && s->insn_bits)
- s->insn_write = insn_rw_emulate_bits;
-
- if (!s->insn_read)
- s->insn_read = insn_inval;
- if (!s->insn_write)
- s->insn_write = insn_inval;
- if (!s->insn_bits)
- s->insn_bits = insn_inval;
- if (!s->insn_config)
- s->insn_config = insn_inval;
-
- if (!s->poll)
- s->poll = poll_invalid;
- }
-
- return 0;
-}
-
-/* do a little post-config cleanup */
-static int comedi_device_postconfig(struct comedi_device *dev)
-{
- int ret;
-
- lockdep_assert_held(&dev->mutex);
- ret = __comedi_device_postconfig(dev);
- if (ret < 0)
- return ret;
- down_write(&dev->attach_lock);
- dev->attached = true;
- up_write(&dev->attach_lock);
- return 0;
-}
-
-/*
- * Generic recognize function for drivers that register their supported
- * board names.
- *
- * 'driv->board_name' points to a 'const char *' member within the
- * zeroth element of an array of some private board information
- * structure, say 'struct foo_board' containing a member 'const char
- * *board_name' that is initialized to point to a board name string that
- * is one of the candidates matched against this function's 'name'
- * parameter.
- *
- * 'driv->offset' is the size of the private board information
- * structure, say 'sizeof(struct foo_board)', and 'driv->num_names' is
- * the length of the array of private board information structures.
- *
- * If one of the board names in the array of private board information
- * structures matches the name supplied to this function, the function
- * returns a pointer to the pointer to the board name, otherwise it
- * returns NULL. The return value ends up in the 'board_ptr' member of
- * a 'struct comedi_device' that the low-level comedi driver's
- * 'attach()' hook can convert to a point to a particular element of its
- * array of private board information structures by subtracting the
- * offset of the member that points to the board name. (No subtraction
- * is required if the board name pointer is the first member of the
- * private board information structure, which is generally the case.)
- */
-static void *comedi_recognize(struct comedi_driver *driv, const char *name)
-{
- char **name_ptr = (char **)driv->board_name;
- int i;
-
- for (i = 0; i < driv->num_names; i++) {
- if (strcmp(*name_ptr, name) == 0)
- return name_ptr;
- name_ptr = (void *)name_ptr + driv->offset;
- }
-
- return NULL;
-}
-
-static void comedi_report_boards(struct comedi_driver *driv)
-{
- unsigned int i;
- const char *const *name_ptr;
-
- pr_info("comedi: valid board names for %s driver are:\n",
- driv->driver_name);
-
- name_ptr = driv->board_name;
- for (i = 0; i < driv->num_names; i++) {
- pr_info(" %s\n", *name_ptr);
- name_ptr = (const char **)((char *)name_ptr + driv->offset);
- }
-
- if (driv->num_names == 0)
- pr_info(" %s\n", driv->driver_name);
-}
-
-/**
- * comedi_load_firmware() - Request and load firmware for a device
- * @dev: COMEDI device.
- * @device: Hardware device.
- * @name: The name of the firmware image.
- * @cb: Callback to the upload the firmware image.
- * @context: Private context from the driver.
- *
- * Sends a firmware request for the hardware device and waits for it. Calls
- * the callback function to upload the firmware to the device, them releases
- * the firmware.
- *
- * Returns 0 on success, -EINVAL if @cb is NULL, or a negative error number
- * from the firmware request or the callback function.
- */
-int comedi_load_firmware(struct comedi_device *dev,
- struct device *device,
- const char *name,
- int (*cb)(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context),
- unsigned long context)
-{
- const struct firmware *fw;
- int ret;
-
- if (!cb)
- return -EINVAL;
-
- ret = request_firmware(&fw, name, device);
- if (ret == 0) {
- ret = cb(dev, fw->data, fw->size, context);
- release_firmware(fw);
- }
-
- return ret < 0 ? ret : 0;
-}
-EXPORT_SYMBOL_GPL(comedi_load_firmware);
-
-/**
- * __comedi_request_region() - Request an I/O region for a legacy driver
- * @dev: COMEDI device.
- * @start: Base address of the I/O region.
- * @len: Length of the I/O region.
- *
- * Requests the specified I/O port region which must start at a non-zero
- * address.
- *
- * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
- * fails.
- */
-int __comedi_request_region(struct comedi_device *dev,
- unsigned long start, unsigned long len)
-{
- if (!start) {
- dev_warn(dev->class_dev,
- "%s: a I/O base address must be specified\n",
- dev->board_name);
- return -EINVAL;
- }
-
- if (!request_region(start, len, dev->board_name)) {
- dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n",
- dev->board_name, start, len);
- return -EIO;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(__comedi_request_region);
-
-/**
- * comedi_request_region() - Request an I/O region for a legacy driver
- * @dev: COMEDI device.
- * @start: Base address of the I/O region.
- * @len: Length of the I/O region.
- *
- * Requests the specified I/O port region which must start at a non-zero
- * address.
- *
- * On success, @dev->iobase is set to the base address of the region and
- * @dev->iolen is set to its length.
- *
- * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
- * fails.
- */
-int comedi_request_region(struct comedi_device *dev,
- unsigned long start, unsigned long len)
-{
- int ret;
-
- ret = __comedi_request_region(dev, start, len);
- if (ret == 0) {
- dev->iobase = start;
- dev->iolen = len;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(comedi_request_region);
-
-/**
- * comedi_legacy_detach() - A generic (*detach) function for legacy drivers
- * @dev: COMEDI device.
- *
- * This is a simple, generic 'detach' handler for legacy COMEDI devices that
- * just use a single I/O port region and possibly an IRQ and that don't need
- * any special clean-up for their private device or subdevice storage. It
- * can also be called by a driver-specific 'detach' handler.
- *
- * If @dev->irq is non-zero, the IRQ will be freed. If @dev->iobase and
- * @dev->iolen are both non-zero, the I/O port region will be released.
- */
-void comedi_legacy_detach(struct comedi_device *dev)
-{
- if (dev->irq) {
- free_irq(dev->irq, dev);
- dev->irq = 0;
- }
- if (dev->iobase && dev->iolen) {
- release_region(dev->iobase, dev->iolen);
- dev->iobase = 0;
- dev->iolen = 0;
- }
-}
-EXPORT_SYMBOL_GPL(comedi_legacy_detach);
-
-int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct comedi_driver *driv;
- int ret;
-
- lockdep_assert_held(&dev->mutex);
- if (dev->attached)
- return -EBUSY;
-
- mutex_lock(&comedi_drivers_list_lock);
- for (driv = comedi_drivers; driv; driv = driv->next) {
- if (!try_module_get(driv->module))
- continue;
- if (driv->num_names) {
- dev->board_ptr = comedi_recognize(driv, it->board_name);
- if (dev->board_ptr)
- break;
- } else if (strcmp(driv->driver_name, it->board_name) == 0) {
- break;
- }
- module_put(driv->module);
- }
- if (!driv) {
- /* recognize has failed if we get here */
- /* report valid board names before returning error */
- for (driv = comedi_drivers; driv; driv = driv->next) {
- if (!try_module_get(driv->module))
- continue;
- comedi_report_boards(driv);
- module_put(driv->module);
- }
- ret = -EIO;
- goto out;
- }
- if (!driv->attach) {
- /* driver does not support manual configuration */
- dev_warn(dev->class_dev,
- "driver '%s' does not support attach using comedi_config\n",
- driv->driver_name);
- module_put(driv->module);
- ret = -EIO;
- goto out;
- }
- dev->driver = driv;
- dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr
- : dev->driver->driver_name;
- ret = driv->attach(dev, it);
- if (ret >= 0)
- ret = comedi_device_postconfig(dev);
- if (ret < 0) {
- comedi_device_detach(dev);
- module_put(driv->module);
- }
- /* On success, the driver module count has been incremented. */
-out:
- mutex_unlock(&comedi_drivers_list_lock);
- return ret;
-}
-
-/**
- * comedi_auto_config() - Create a COMEDI device for a hardware device
- * @hardware_device: Hardware device.
- * @driver: COMEDI low-level driver for the hardware device.
- * @context: Driver context for the auto_attach handler.
- *
- * Allocates a new COMEDI device for the hardware device and calls the
- * low-level driver's 'auto_attach' handler to set-up the hardware and
- * allocate the COMEDI subdevices. Additional "post-configuration" setting
- * up is performed on successful return from the 'auto_attach' handler.
- * If the 'auto_attach' handler fails, the low-level driver's 'detach'
- * handler will be called as part of the clean-up.
- *
- * This is usually called from a wrapper function in a bus-specific COMEDI
- * module, which in turn is usually called from a bus device 'probe'
- * function in the low-level driver.
- *
- * Returns 0 on success, -EINVAL if the parameters are invalid or the
- * post-configuration determines the driver has set the COMEDI device up
- * incorrectly, -ENOMEM if failed to allocate memory, -EBUSY if run out of
- * COMEDI minor device numbers, or some negative error number returned by
- * the driver's 'auto_attach' handler.
- */
-int comedi_auto_config(struct device *hardware_device,
- struct comedi_driver *driver, unsigned long context)
-{
- struct comedi_device *dev;
- int ret;
-
- if (!hardware_device) {
- pr_warn("BUG! %s called with NULL hardware_device\n", __func__);
- return -EINVAL;
- }
- if (!driver) {
- dev_warn(hardware_device,
- "BUG! %s called with NULL comedi driver\n", __func__);
- return -EINVAL;
- }
-
- if (!driver->auto_attach) {
- dev_warn(hardware_device,
- "BUG! comedi driver '%s' has no auto_attach handler\n",
- driver->driver_name);
- return -EINVAL;
- }
-
- dev = comedi_alloc_board_minor(hardware_device);
- if (IS_ERR(dev)) {
- dev_warn(hardware_device,
- "driver '%s' could not create device.\n",
- driver->driver_name);
- return PTR_ERR(dev);
- }
- /* Note: comedi_alloc_board_minor() locked dev->mutex. */
- lockdep_assert_held(&dev->mutex);
-
- dev->driver = driver;
- dev->board_name = dev->driver->driver_name;
- ret = driver->auto_attach(dev, context);
- if (ret >= 0)
- ret = comedi_device_postconfig(dev);
-
- if (ret < 0) {
- dev_warn(hardware_device,
- "driver '%s' failed to auto-configure device.\n",
- driver->driver_name);
- mutex_unlock(&dev->mutex);
- comedi_release_hardware_device(hardware_device);
- } else {
- /*
- * class_dev should be set properly here
- * after a successful auto config
- */
- dev_info(dev->class_dev,
- "driver '%s' has successfully auto-configured '%s'.\n",
- driver->driver_name, dev->board_name);
- mutex_unlock(&dev->mutex);
- }
- return ret;
-}
-EXPORT_SYMBOL_GPL(comedi_auto_config);
-
-/**
- * comedi_auto_unconfig() - Unconfigure auto-allocated COMEDI device
- * @hardware_device: Hardware device previously passed to
- * comedi_auto_config().
- *
- * Cleans up and eventually destroys the COMEDI device allocated by
- * comedi_auto_config() for the same hardware device. As part of this
- * clean-up, the low-level COMEDI driver's 'detach' handler will be called.
- * (The COMEDI device itself will persist in an unattached state if it is
- * still open, until it is released, and any mmapped buffers will persist
- * until they are munmapped.)
- *
- * This is usually called from a wrapper module in a bus-specific COMEDI
- * module, which in turn is usually set as the bus device 'remove' function
- * in the low-level COMEDI driver.
- */
-void comedi_auto_unconfig(struct device *hardware_device)
-{
- if (!hardware_device)
- return;
- comedi_release_hardware_device(hardware_device);
-}
-EXPORT_SYMBOL_GPL(comedi_auto_unconfig);
-
-/**
- * comedi_driver_register() - Register a low-level COMEDI driver
- * @driver: Low-level COMEDI driver.
- *
- * The low-level COMEDI driver is added to the list of registered COMEDI
- * drivers. This is used by the handler for the "/proc/comedi" file and is
- * also used by the handler for the %COMEDI_DEVCONFIG ioctl to configure
- * "legacy" COMEDI devices (for those low-level drivers that support it).
- *
- * Returns 0.
- */
-int comedi_driver_register(struct comedi_driver *driver)
-{
- mutex_lock(&comedi_drivers_list_lock);
- driver->next = comedi_drivers;
- comedi_drivers = driver;
- mutex_unlock(&comedi_drivers_list_lock);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_driver_register);
-
-/**
- * comedi_driver_unregister() - Unregister a low-level COMEDI driver
- * @driver: Low-level COMEDI driver.
- *
- * The low-level COMEDI driver is removed from the list of registered COMEDI
- * drivers. Detaches any COMEDI devices attached to the driver, which will
- * result in the low-level driver's 'detach' handler being called for those
- * devices before this function returns.
- */
-void comedi_driver_unregister(struct comedi_driver *driver)
-{
- struct comedi_driver *prev;
- int i;
-
- /* unlink the driver */
- mutex_lock(&comedi_drivers_list_lock);
- if (comedi_drivers == driver) {
- comedi_drivers = driver->next;
- } else {
- for (prev = comedi_drivers; prev->next; prev = prev->next) {
- if (prev->next == driver) {
- prev->next = driver->next;
- break;
- }
- }
- }
- mutex_unlock(&comedi_drivers_list_lock);
-
- /* check for devices using this driver */
- for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
- struct comedi_device *dev = comedi_dev_get_from_minor(i);
-
- if (!dev)
- continue;
-
- mutex_lock(&dev->mutex);
- if (dev->attached && dev->driver == driver) {
- if (dev->use_count)
- dev_warn(dev->class_dev,
- "BUG! detaching device with use_count=%d\n",
- dev->use_count);
- comedi_device_detach(dev);
- }
- mutex_unlock(&dev->mutex);
- comedi_dev_put(dev);
- }
-}
-EXPORT_SYMBOL_GPL(comedi_driver_unregister);
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
deleted file mode 100644
index e23335c75867..000000000000
--- a/drivers/staging/comedi/drivers/8255.c
+++ /dev/null
@@ -1,125 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/8255.c
- * Driver for 8255
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: 8255
- * Description: generic 8255 support
- * Devices: [standard] 8255 (8255)
- * Author: ds
- * Status: works
- * Updated: Fri, 7 Jun 2002 12:56:45 -0700
- *
- * The classic in digital I/O. The 8255 appears in Comedi as a single
- * digital I/O subdevice with 24 channels. The channel 0 corresponds
- * to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
- * 7. Direction configuration is done in blocks, with channels 0-7,
- * 8-15, 16-19, and 20-23 making up the 4 blocks. The only 8255 mode
- * supported is mode 0.
- *
- * You should enable compilation this driver if you plan to use a board
- * that has an 8255 chip. For multifunction boards, the main driver will
- * configure the 8255 subdevice automatically.
- *
- * This driver also works independently with ISA and PCI cards that
- * directly map the 8255 registers to I/O ports, including cards with
- * multiple 8255 chips. To configure the driver for such a card, the
- * option list should be a list of the I/O port bases for each of the
- * 8255 chips. For example,
- *
- * comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
- *
- * Note that most PCI 8255 boards do NOT work with this driver, and
- * need a separate driver as a wrapper. For those that do work, the
- * I/O port base address can be found in the output of 'lspci -v'.
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include "8255.h"
-
-static int dev_8255_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- unsigned long iobase;
- int ret;
- int i;
-
- for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
- iobase = it->options[i];
- if (!iobase)
- break;
- }
- if (i == 0) {
- dev_warn(dev->class_dev, "no devices specified\n");
- return -EINVAL;
- }
-
- ret = comedi_alloc_subdevices(dev, i);
- if (ret)
- return ret;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- iobase = it->options[i];
-
- /*
- * __comedi_request_region() does not set dev->iobase.
- *
- * For 8255 devices that are manually attached using
- * comedi_config, the 'iobase' is the actual I/O port
- * base address of the chip.
- */
- ret = __comedi_request_region(dev, iobase, I8255_SIZE);
- if (ret) {
- s->type = COMEDI_SUBD_UNUSED;
- } else {
- ret = subdev_8255_init(dev, s, NULL, iobase);
- if (ret) {
- /*
- * Release the I/O port region here, as the
- * "detach" handler cannot find it.
- */
- release_region(iobase, I8255_SIZE);
- s->type = COMEDI_SUBD_UNUSED;
- return ret;
- }
- }
- }
-
- return 0;
-}
-
-static void dev_8255_detach(struct comedi_device *dev)
-{
- struct comedi_subdevice *s;
- int i;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- if (s->type != COMEDI_SUBD_UNUSED) {
- unsigned long regbase = subdev_8255_regbase(s);
-
- release_region(regbase, I8255_SIZE);
- }
- }
-}
-
-static struct comedi_driver dev_8255_driver = {
- .driver_name = "8255",
- .module = THIS_MODULE,
- .attach = dev_8255_attach,
- .detach = dev_8255_detach,
-};
-module_comedi_driver(dev_8255_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for standalone 8255 devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
deleted file mode 100644
index ceae3ca52e60..000000000000
--- a/drivers/staging/comedi/drivers/8255.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * module/8255.h
- * Header file for 8255
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _8255_H
-#define _8255_H
-
-#define I8255_SIZE 0x04
-
-#define I8255_DATA_A_REG 0x00
-#define I8255_DATA_B_REG 0x01
-#define I8255_DATA_C_REG 0x02
-#define I8255_CTRL_REG 0x03
-#define I8255_CTRL_C_LO_IO BIT(0)
-#define I8255_CTRL_B_IO BIT(1)
-#define I8255_CTRL_B_MODE BIT(2)
-#define I8255_CTRL_C_HI_IO BIT(3)
-#define I8255_CTRL_A_IO BIT(4)
-#define I8255_CTRL_A_MODE(x) ((x) << 5)
-#define I8255_CTRL_CW BIT(7)
-
-struct comedi_device;
-struct comedi_subdevice;
-
-int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
- int (*io)(struct comedi_device *dev, int dir, int port,
- int data, unsigned long regbase),
- unsigned long regbase);
-
-int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s,
- int (*io)(struct comedi_device *dev, int dir, int port,
- int data, unsigned long regbase),
- unsigned long regbase);
-
-unsigned long subdev_8255_regbase(struct comedi_subdevice *s);
-
-#endif
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
deleted file mode 100644
index 5a810f0e532a..000000000000
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ /dev/null
@@ -1,295 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * COMEDI driver for generic PCI based 8255 digital i/o boards
- * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Based on the tested adl_pci7296 driver written by:
- * Jon Grierson <jd@renko.co.uk>
- * and the experimental cb_pcidio driver written by:
- * Yoshiya Matsuzaka
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: 8255_pci
- * Description: Generic PCI based 8255 Digital I/O boards
- * Devices: [ADLink] PCI-7224 (adl_pci-7224), PCI-7248 (adl_pci-7248),
- * PCI-7296 (adl_pci-7296),
- * [Measurement Computing] PCI-DIO24 (cb_pci-dio24),
- * PCI-DIO24H (cb_pci-dio24h), PCI-DIO48H (cb_pci-dio48h),
- * PCI-DIO96H (cb_pci-dio96h),
- * [National Instruments] PCI-DIO-96 (ni_pci-dio-96),
- * PCI-DIO-96B (ni_pci-dio-96b), PXI-6508 (ni_pxi-6508),
- * PCI-6503 (ni_pci-6503), PCI-6503B (ni_pci-6503b),
- * PCI-6503X (ni_pci-6503x), PXI-6503 (ni_pxi-6503)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Wed, 12 Sep 2012 11:52:01 -0700
- * Status: untested
- *
- * These boards have one or more 8255 digital I/O chips, each of which
- * is supported as a separate 24-channel DIO subdevice.
- *
- * Boards with 24 DIO channels (1 DIO subdevice):
- *
- * PCI-7224, PCI-DIO24, PCI-DIO24H, PCI-6503, PCI-6503B, PCI-6503X,
- * PXI-6503
- *
- * Boards with 48 DIO channels (2 DIO subdevices):
- *
- * PCI-7248, PCI-DIO48H
- *
- * Boards with 96 DIO channels (4 DIO subdevices):
- *
- * PCI-7296, PCI-DIO96H, PCI-DIO-96, PCI-DIO-96B, PXI-6508
- *
- * Some of these boards also have an 8254 programmable timer/counter
- * chip. This chip is not currently supported by this driver.
- *
- * Interrupt support for these boards is also not currently supported.
- *
- * Configuration Options: not applicable, uses PCI auto config.
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-#include "8255.h"
-
-enum pci_8255_boardid {
- BOARD_ADLINK_PCI7224,
- BOARD_ADLINK_PCI7248,
- BOARD_ADLINK_PCI7296,
- BOARD_CB_PCIDIO24,
- BOARD_CB_PCIDIO24H,
- BOARD_CB_PCIDIO48H_OLD,
- BOARD_CB_PCIDIO48H_NEW,
- BOARD_CB_PCIDIO96H,
- BOARD_NI_PCIDIO96,
- BOARD_NI_PCIDIO96B,
- BOARD_NI_PXI6508,
- BOARD_NI_PCI6503,
- BOARD_NI_PCI6503B,
- BOARD_NI_PCI6503X,
- BOARD_NI_PXI_6503,
-};
-
-struct pci_8255_boardinfo {
- const char *name;
- int dio_badr;
- int n_8255;
- unsigned int has_mite:1;
-};
-
-static const struct pci_8255_boardinfo pci_8255_boards[] = {
- [BOARD_ADLINK_PCI7224] = {
- .name = "adl_pci-7224",
- .dio_badr = 2,
- .n_8255 = 1,
- },
- [BOARD_ADLINK_PCI7248] = {
- .name = "adl_pci-7248",
- .dio_badr = 2,
- .n_8255 = 2,
- },
- [BOARD_ADLINK_PCI7296] = {
- .name = "adl_pci-7296",
- .dio_badr = 2,
- .n_8255 = 4,
- },
- [BOARD_CB_PCIDIO24] = {
- .name = "cb_pci-dio24",
- .dio_badr = 2,
- .n_8255 = 1,
- },
- [BOARD_CB_PCIDIO24H] = {
- .name = "cb_pci-dio24h",
- .dio_badr = 2,
- .n_8255 = 1,
- },
- [BOARD_CB_PCIDIO48H_OLD] = {
- .name = "cb_pci-dio48h",
- .dio_badr = 1,
- .n_8255 = 2,
- },
- [BOARD_CB_PCIDIO48H_NEW] = {
- .name = "cb_pci-dio48h",
- .dio_badr = 2,
- .n_8255 = 2,
- },
- [BOARD_CB_PCIDIO96H] = {
- .name = "cb_pci-dio96h",
- .dio_badr = 2,
- .n_8255 = 4,
- },
- [BOARD_NI_PCIDIO96] = {
- .name = "ni_pci-dio-96",
- .dio_badr = 1,
- .n_8255 = 4,
- .has_mite = 1,
- },
- [BOARD_NI_PCIDIO96B] = {
- .name = "ni_pci-dio-96b",
- .dio_badr = 1,
- .n_8255 = 4,
- .has_mite = 1,
- },
- [BOARD_NI_PXI6508] = {
- .name = "ni_pxi-6508",
- .dio_badr = 1,
- .n_8255 = 4,
- .has_mite = 1,
- },
- [BOARD_NI_PCI6503] = {
- .name = "ni_pci-6503",
- .dio_badr = 1,
- .n_8255 = 1,
- .has_mite = 1,
- },
- [BOARD_NI_PCI6503B] = {
- .name = "ni_pci-6503b",
- .dio_badr = 1,
- .n_8255 = 1,
- .has_mite = 1,
- },
- [BOARD_NI_PCI6503X] = {
- .name = "ni_pci-6503x",
- .dio_badr = 1,
- .n_8255 = 1,
- .has_mite = 1,
- },
- [BOARD_NI_PXI_6503] = {
- .name = "ni_pxi-6503",
- .dio_badr = 1,
- .n_8255 = 1,
- .has_mite = 1,
- },
-};
-
-/* ripped from mite.h and mite_setup2() to avoid mite dependency */
-#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
-#define WENAB BIT(7) /* window enable */
-
-static int pci_8255_mite_init(struct pci_dev *pcidev)
-{
- void __iomem *mite_base;
- u32 main_phys_addr;
-
- /* ioremap the MITE registers (BAR 0) temporarily */
- mite_base = pci_ioremap_bar(pcidev, 0);
- if (!mite_base)
- return -ENOMEM;
-
- /* set data window to main registers (BAR 1) */
- main_phys_addr = pci_resource_start(pcidev, 1);
- writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
-
- /* finished with MITE registers */
- iounmap(mite_base);
- return 0;
-}
-
-static int pci_8255_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct pci_8255_boardinfo *board = NULL;
- struct comedi_subdevice *s;
- int ret;
- int i;
-
- if (context < ARRAY_SIZE(pci_8255_boards))
- board = &pci_8255_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- if (board->has_mite) {
- ret = pci_8255_mite_init(pcidev);
- if (ret)
- return ret;
- }
-
- if ((pci_resource_flags(pcidev, board->dio_badr) & IORESOURCE_MEM)) {
- dev->mmio = pci_ioremap_bar(pcidev, board->dio_badr);
- if (!dev->mmio)
- return -ENOMEM;
- } else {
- dev->iobase = pci_resource_start(pcidev, board->dio_badr);
- }
-
- /*
- * One, two, or four subdevices are setup by this driver depending
- * on the number of channels provided by the board. Each subdevice
- * has 24 channels supported by the 8255 module.
- */
- ret = comedi_alloc_subdevices(dev, board->n_8255);
- if (ret)
- return ret;
-
- for (i = 0; i < board->n_8255; i++) {
- s = &dev->subdevices[i];
- if (dev->mmio)
- ret = subdev_8255_mm_init(dev, s, NULL, i * I8255_SIZE);
- else
- ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct comedi_driver pci_8255_driver = {
- .driver_name = "8255_pci",
- .module = THIS_MODULE,
- .auto_attach = pci_8255_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int pci_8255_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &pci_8255_driver, id->driver_data);
-}
-
-static const struct pci_device_id pci_8255_pci_table[] = {
- { PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 },
- { PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 },
- { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 },
- { PCI_VDEVICE(CB, 0x0028), BOARD_CB_PCIDIO24 },
- { PCI_VDEVICE(CB, 0x0014), BOARD_CB_PCIDIO24H },
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, 0x0000, 0x0000),
- .driver_data = BOARD_CB_PCIDIO48H_OLD },
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, PCI_VENDOR_ID_CB, 0x000b),
- .driver_data = BOARD_CB_PCIDIO48H_NEW },
- { PCI_VDEVICE(CB, 0x0017), BOARD_CB_PCIDIO96H },
- { PCI_VDEVICE(NI, 0x0160), BOARD_NI_PCIDIO96 },
- { PCI_VDEVICE(NI, 0x1630), BOARD_NI_PCIDIO96B },
- { PCI_VDEVICE(NI, 0x13c0), BOARD_NI_PXI6508 },
- { PCI_VDEVICE(NI, 0x0400), BOARD_NI_PCI6503 },
- { PCI_VDEVICE(NI, 0x1250), BOARD_NI_PCI6503B },
- { PCI_VDEVICE(NI, 0x17d0), BOARD_NI_PCI6503X },
- { PCI_VDEVICE(NI, 0x1800), BOARD_NI_PXI_6503 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, pci_8255_pci_table);
-
-static struct pci_driver pci_8255_pci_driver = {
- .name = "8255_pci",
- .id_table = pci_8255_pci_table,
- .probe = pci_8255_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(pci_8255_driver, pci_8255_pci_driver);
-
-MODULE_DESCRIPTION("COMEDI - Generic PCI based 8255 Digital I/O boards");
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
deleted file mode 100644
index b24ac00cab73..000000000000
--- a/drivers/staging/comedi/drivers/Makefile
+++ /dev/null
@@ -1,175 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Makefile for individual comedi drivers
-#
-ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG
-
-# Comedi "helper" modules
-obj-$(CONFIG_COMEDI_8254) += comedi_8254.o
-obj-$(CONFIG_COMEDI_ISADMA) += comedi_isadma.o
-
-# Comedi misc drivers
-obj-$(CONFIG_COMEDI_BOND) += comedi_bond.o
-obj-$(CONFIG_COMEDI_TEST) += comedi_test.o
-obj-$(CONFIG_COMEDI_PARPORT) += comedi_parport.o
-
-# Comedi ISA drivers
-obj-$(CONFIG_COMEDI_AMPLC_DIO200_ISA) += amplc_dio200.o
-obj-$(CONFIG_COMEDI_AMPLC_PC236_ISA) += amplc_pc236.o
-obj-$(CONFIG_COMEDI_AMPLC_PC263_ISA) += amplc_pc263.o
-obj-$(CONFIG_COMEDI_PCL711) += pcl711.o
-obj-$(CONFIG_COMEDI_PCL724) += pcl724.o
-obj-$(CONFIG_COMEDI_PCL726) += pcl726.o
-obj-$(CONFIG_COMEDI_PCL730) += pcl730.o
-obj-$(CONFIG_COMEDI_PCL812) += pcl812.o
-obj-$(CONFIG_COMEDI_PCL816) += pcl816.o
-obj-$(CONFIG_COMEDI_PCL818) += pcl818.o
-obj-$(CONFIG_COMEDI_PCM3724) += pcm3724.o
-obj-$(CONFIG_COMEDI_RTI800) += rti800.o
-obj-$(CONFIG_COMEDI_RTI802) += rti802.o
-obj-$(CONFIG_COMEDI_DAC02) += dac02.o
-obj-$(CONFIG_COMEDI_DAS16M1) += das16m1.o
-obj-$(CONFIG_COMEDI_DAS08_ISA) += das08_isa.o
-obj-$(CONFIG_COMEDI_DAS16) += das16.o
-obj-$(CONFIG_COMEDI_DAS800) += das800.o
-obj-$(CONFIG_COMEDI_DAS1800) += das1800.o
-obj-$(CONFIG_COMEDI_DAS6402) += das6402.o
-obj-$(CONFIG_COMEDI_DT2801) += dt2801.o
-obj-$(CONFIG_COMEDI_DT2811) += dt2811.o
-obj-$(CONFIG_COMEDI_DT2814) += dt2814.o
-obj-$(CONFIG_COMEDI_DT2815) += dt2815.o
-obj-$(CONFIG_COMEDI_DT2817) += dt2817.o
-obj-$(CONFIG_COMEDI_DT282X) += dt282x.o
-obj-$(CONFIG_COMEDI_DMM32AT) += dmm32at.o
-obj-$(CONFIG_COMEDI_FL512) += fl512.o
-obj-$(CONFIG_COMEDI_AIO_AIO12_8) += aio_aio12_8.o
-obj-$(CONFIG_COMEDI_AIO_IIRO_16) += aio_iiro_16.o
-obj-$(CONFIG_COMEDI_II_PCI20KC) += ii_pci20kc.o
-obj-$(CONFIG_COMEDI_C6XDIGIO) += c6xdigio.o
-obj-$(CONFIG_COMEDI_MPC624) += mpc624.o
-obj-$(CONFIG_COMEDI_ADQ12B) += adq12b.o
-obj-$(CONFIG_COMEDI_NI_AT_A2150) += ni_at_a2150.o
-obj-$(CONFIG_COMEDI_NI_AT_AO) += ni_at_ao.o
-obj-$(CONFIG_COMEDI_NI_ATMIO) += ni_atmio.o
-obj-$(CONFIG_COMEDI_NI_ATMIO16D) += ni_atmio16d.o
-obj-$(CONFIG_COMEDI_NI_LABPC_ISA) += ni_labpc.o
-obj-$(CONFIG_COMEDI_PCMAD) += pcmad.o
-obj-$(CONFIG_COMEDI_PCMDA12) += pcmda12.o
-obj-$(CONFIG_COMEDI_PCMMIO) += pcmmio.o
-obj-$(CONFIG_COMEDI_PCMUIO) += pcmuio.o
-obj-$(CONFIG_COMEDI_MULTIQ3) += multiq3.o
-obj-$(CONFIG_COMEDI_S526) += s526.o
-
-# Comedi PCI drivers
-obj-$(CONFIG_COMEDI_8255_PCI) += 8255_pci.o
-obj-$(CONFIG_COMEDI_ADDI_WATCHDOG) += addi_watchdog.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_1516) += addi_apci_1516.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_1564) += addi_apci_1564.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_16XX) += addi_apci_16xx.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_2032) += addi_apci_2032.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_2200) += addi_apci_2200.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_3120) += addi_apci_3120.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o
-obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o
-obj-$(CONFIG_COMEDI_ADL_PCI6208) += adl_pci6208.o
-obj-$(CONFIG_COMEDI_ADL_PCI7X3X) += adl_pci7x3x.o
-obj-$(CONFIG_COMEDI_ADL_PCI8164) += adl_pci8164.o
-obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o
-obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o
-obj-$(CONFIG_COMEDI_ADV_PCI1710) += adv_pci1710.o
-obj-$(CONFIG_COMEDI_ADV_PCI1720) += adv_pci1720.o
-obj-$(CONFIG_COMEDI_ADV_PCI1723) += adv_pci1723.o
-obj-$(CONFIG_COMEDI_ADV_PCI1724) += adv_pci1724.o
-obj-$(CONFIG_COMEDI_ADV_PCI1760) += adv_pci1760.o
-obj-$(CONFIG_COMEDI_ADV_PCI_DIO) += adv_pci_dio.o
-obj-$(CONFIG_COMEDI_AMPLC_DIO200_PCI) += amplc_dio200_pci.o
-obj-$(CONFIG_COMEDI_AMPLC_PC236_PCI) += amplc_pci236.o
-obj-$(CONFIG_COMEDI_AMPLC_PC263_PCI) += amplc_pci263.o
-obj-$(CONFIG_COMEDI_AMPLC_PCI224) += amplc_pci224.o
-obj-$(CONFIG_COMEDI_AMPLC_PCI230) += amplc_pci230.o
-obj-$(CONFIG_COMEDI_CONTEC_PCI_DIO) += contec_pci_dio.o
-obj-$(CONFIG_COMEDI_DAS08_PCI) += das08_pci.o
-obj-$(CONFIG_COMEDI_DT3000) += dt3000.o
-obj-$(CONFIG_COMEDI_DYNA_PCI10XX) += dyna_pci10xx.o
-obj-$(CONFIG_COMEDI_GSC_HPDI) += gsc_hpdi.o
-obj-$(CONFIG_COMEDI_ICP_MULTI) += icp_multi.o
-obj-$(CONFIG_COMEDI_DAQBOARD2000) += daqboard2000.o
-obj-$(CONFIG_COMEDI_JR3_PCI) += jr3_pci.o
-obj-$(CONFIG_COMEDI_KE_COUNTER) += ke_counter.o
-obj-$(CONFIG_COMEDI_CB_PCIDAS64) += cb_pcidas64.o
-obj-$(CONFIG_COMEDI_CB_PCIDAS) += cb_pcidas.o
-obj-$(CONFIG_COMEDI_CB_PCIDDA) += cb_pcidda.o
-obj-$(CONFIG_COMEDI_CB_PCIMDAS) += cb_pcimdas.o
-obj-$(CONFIG_COMEDI_CB_PCIMDDA) += cb_pcimdda.o
-obj-$(CONFIG_COMEDI_ME4000) += me4000.o
-obj-$(CONFIG_COMEDI_ME_DAQ) += me_daq.o
-obj-$(CONFIG_COMEDI_NI_6527) += ni_6527.o
-obj-$(CONFIG_COMEDI_NI_65XX) += ni_65xx.o
-obj-$(CONFIG_COMEDI_NI_660X) += ni_660x.o
-obj-$(CONFIG_COMEDI_NI_670X) += ni_670x.o
-obj-$(CONFIG_COMEDI_NI_LABPC_PCI) += ni_labpc_pci.o
-obj-$(CONFIG_COMEDI_NI_PCIDIO) += ni_pcidio.o
-obj-$(CONFIG_COMEDI_NI_PCIMIO) += ni_pcimio.o
-obj-$(CONFIG_COMEDI_RTD520) += rtd520.o
-obj-$(CONFIG_COMEDI_S626) += s626.o
-obj-$(CONFIG_COMEDI_SSV_DNP) += ssv_dnp.o
-obj-$(CONFIG_COMEDI_MF6X4) += mf6x4.o
-
-# Comedi PCMCIA drivers
-obj-$(CONFIG_COMEDI_CB_DAS16_CS) += cb_das16_cs.o
-obj-$(CONFIG_COMEDI_DAS08_CS) += das08_cs.o
-obj-$(CONFIG_COMEDI_NI_DAQ_700_CS) += ni_daq_700.o
-obj-$(CONFIG_COMEDI_NI_DAQ_DIO24_CS) += ni_daq_dio24.o
-obj-$(CONFIG_COMEDI_NI_LABPC_CS) += ni_labpc_cs.o
-obj-$(CONFIG_COMEDI_NI_MIO_CS) += ni_mio_cs.o
-obj-$(CONFIG_COMEDI_QUATECH_DAQP_CS) += quatech_daqp_cs.o
-
-# Comedi USB drivers
-obj-$(CONFIG_COMEDI_DT9812) += dt9812.o
-obj-$(CONFIG_COMEDI_NI_USB6501) += ni_usb6501.o
-obj-$(CONFIG_COMEDI_USBDUX) += usbdux.o
-obj-$(CONFIG_COMEDI_USBDUXFAST) += usbduxfast.o
-obj-$(CONFIG_COMEDI_USBDUXSIGMA) += usbduxsigma.o
-obj-$(CONFIG_COMEDI_VMK80XX) += vmk80xx.o
-
-# Comedi NI drivers
-obj-$(CONFIG_COMEDI_MITE) += mite.o
-obj-$(CONFIG_COMEDI_NI_TIO) += ni_tio.o
-obj-$(CONFIG_COMEDI_NI_TIOCMD) += ni_tiocmd.o
-obj-$(CONFIG_COMEDI_NI_ROUTING) += ni_routing.o
-ni_routing-objs += ni_routes.o \
- ni_routing/ni_route_values.o \
- ni_routing/ni_route_values/ni_660x.o \
- ni_routing/ni_route_values/ni_eseries.o \
- ni_routing/ni_route_values/ni_mseries.o \
- ni_routing/ni_device_routes.o \
- ni_routing/ni_device_routes/pxi-6030e.o \
- ni_routing/ni_device_routes/pci-6070e.o \
- ni_routing/ni_device_routes/pci-6220.o \
- ni_routing/ni_device_routes/pci-6221.o \
- ni_routing/ni_device_routes/pxi-6224.o \
- ni_routing/ni_device_routes/pxi-6225.o \
- ni_routing/ni_device_routes/pci-6229.o \
- ni_routing/ni_device_routes/pci-6251.o \
- ni_routing/ni_device_routes/pxi-6251.o \
- ni_routing/ni_device_routes/pxie-6251.o \
- ni_routing/ni_device_routes/pci-6254.o \
- ni_routing/ni_device_routes/pci-6259.o \
- ni_routing/ni_device_routes/pci-6534.o \
- ni_routing/ni_device_routes/pxie-6535.o \
- ni_routing/ni_device_routes/pci-6602.o \
- ni_routing/ni_device_routes/pci-6713.o \
- ni_routing/ni_device_routes/pci-6723.o \
- ni_routing/ni_device_routes/pci-6733.o \
- ni_routing/ni_device_routes/pxi-6733.o \
- ni_routing/ni_device_routes/pxie-6738.o
-obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc_common.o
-obj-$(CONFIG_COMEDI_NI_LABPC_ISADMA) += ni_labpc_isadma.o
-
-obj-$(CONFIG_COMEDI_8255) += comedi_8255.o
-obj-$(CONFIG_COMEDI_8255_SA) += 8255.o
-obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200_common.o
-obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236_common.o
-obj-$(CONFIG_COMEDI_DAS08) += das08.o
-obj-$(CONFIG_COMEDI_TESTS) += tests/
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
deleted file mode 100644
index 81a246fbcc01..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_1032.c
+++ /dev/null
@@ -1,396 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_1032.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- * Project manager: Eric Stolz
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-/*
- * Driver: addi_apci_1032
- * Description: ADDI-DATA APCI-1032 Digital Input Board
- * Author: ADDI-DATA GmbH <info@addi-data.com>,
- * H Hartley Sweeten <hsweeten@visionengravers.com>
- * Status: untested
- * Devices: [ADDI-DATA] APCI-1032 (addi_apci_1032)
- *
- * Configuration options:
- * None; devices are configured automatically.
- *
- * This driver models the APCI-1032 as a 32-channel, digital input subdevice
- * plus an additional digital input subdevice to handle change-of-state (COS)
- * interrupts (if an interrupt handler can be set up successfully).
- *
- * The COS subdevice supports comedi asynchronous read commands.
- *
- * Change-Of-State (COS) interrupt configuration:
- *
- * Channels 0 to 15 are interruptible. These channels can be configured
- * to generate interrupts based on AND/OR logic for the desired channels.
- *
- * OR logic:
- * - reacts to rising or falling edges
- * - interrupt is generated when any enabled channel meets the desired
- * interrupt condition
- *
- * AND logic:
- * - reacts to changes in level of the selected inputs
- * - interrupt is generated when all enabled channels meet the desired
- * interrupt condition
- * - after an interrupt, a change in level must occur on the selected
- * inputs to release the IRQ logic
- *
- * The COS subdevice must be configured before setting up a comedi
- * asynchronous command:
- *
- * data[0] : INSN_CONFIG_DIGITAL_TRIG
- * data[1] : trigger number (= 0)
- * data[2] : configuration operation:
- * - COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
- * - COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
- * - COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
- * data[3] : left-shift for data[4] and data[5]
- * data[4] : rising-edge/high level channels
- * data[5] : falling-edge/low level channels
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-#include "amcc_s5933.h"
-
-/*
- * I/O Register Map
- */
-#define APCI1032_DI_REG 0x00
-#define APCI1032_MODE1_REG 0x04
-#define APCI1032_MODE2_REG 0x08
-#define APCI1032_STATUS_REG 0x0c
-#define APCI1032_CTRL_REG 0x10
-#define APCI1032_CTRL_INT_MODE(x) (((x) & 0x1) << 1)
-#define APCI1032_CTRL_INT_OR APCI1032_CTRL_INT_MODE(0)
-#define APCI1032_CTRL_INT_AND APCI1032_CTRL_INT_MODE(1)
-#define APCI1032_CTRL_INT_ENA BIT(2)
-
-struct apci1032_private {
- unsigned long amcc_iobase; /* base of AMCC I/O registers */
- unsigned int mode1; /* rising-edge/high level channels */
- unsigned int mode2; /* falling-edge/low level channels */
- unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */
-};
-
-static int apci1032_reset(struct comedi_device *dev)
-{
- /* disable the interrupts */
- outl(0x0, dev->iobase + APCI1032_CTRL_REG);
- /* Reset the interrupt status register */
- inl(dev->iobase + APCI1032_STATUS_REG);
- /* Disable the and/or interrupt */
- outl(0x0, dev->iobase + APCI1032_MODE1_REG);
- outl(0x0, dev->iobase + APCI1032_MODE2_REG);
-
- return 0;
-}
-
-static int apci1032_cos_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1032_private *devpriv = dev->private;
- unsigned int shift, oldmask, himask, lomask;
-
- switch (data[0]) {
- case INSN_CONFIG_DIGITAL_TRIG:
- if (data[1] != 0)
- return -EINVAL;
- shift = data[3];
- if (shift < 32) {
- oldmask = (1U << shift) - 1;
- himask = data[4] << shift;
- lomask = data[5] << shift;
- } else {
- oldmask = 0xffffffffu;
- himask = 0;
- lomask = 0;
- }
- switch (data[2]) {
- case COMEDI_DIGITAL_TRIG_DISABLE:
- devpriv->ctrl = 0;
- devpriv->mode1 = 0;
- devpriv->mode2 = 0;
- apci1032_reset(dev);
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
- if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA |
- APCI1032_CTRL_INT_OR)) {
- /* switching to 'OR' mode */
- devpriv->ctrl = APCI1032_CTRL_INT_ENA |
- APCI1032_CTRL_INT_OR;
- /* wipe old channels */
- devpriv->mode1 = 0;
- devpriv->mode2 = 0;
- } else {
- /* preserve unspecified channels */
- devpriv->mode1 &= oldmask;
- devpriv->mode2 &= oldmask;
- }
- /* configure specified channels */
- devpriv->mode1 |= himask;
- devpriv->mode2 |= lomask;
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
- if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA |
- APCI1032_CTRL_INT_AND)) {
- /* switching to 'AND' mode */
- devpriv->ctrl = APCI1032_CTRL_INT_ENA |
- APCI1032_CTRL_INT_AND;
- /* wipe old channels */
- devpriv->mode1 = 0;
- devpriv->mode2 = 0;
- } else {
- /* preserve unspecified channels */
- devpriv->mode1 &= oldmask;
- devpriv->mode2 &= oldmask;
- }
- /* configure specified channels */
- devpriv->mode1 |= himask;
- devpriv->mode2 |= lomask;
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int apci1032_cos_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = s->state;
-
- return 0;
-}
-
-static int apci1032_cos_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-/*
- * Change-Of-State (COS) 'do_cmd' operation
- *
- * Enable the COS interrupt as configured by apci1032_cos_insn_config().
- */
-static int apci1032_cos_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci1032_private *devpriv = dev->private;
-
- if (!devpriv->ctrl) {
- dev_warn(dev->class_dev,
- "Interrupts disabled due to mode configuration!\n");
- return -EINVAL;
- }
-
- outl(devpriv->mode1, dev->iobase + APCI1032_MODE1_REG);
- outl(devpriv->mode2, dev->iobase + APCI1032_MODE2_REG);
- outl(devpriv->ctrl, dev->iobase + APCI1032_CTRL_REG);
-
- return 0;
-}
-
-static int apci1032_cos_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- return apci1032_reset(dev);
-}
-
-static irqreturn_t apci1032_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct apci1032_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int ctrl;
- unsigned short val;
-
- /* check interrupt is from this device */
- if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) &
- INTCSR_INTR_ASSERTED) == 0)
- return IRQ_NONE;
-
- /* check interrupt is enabled */
- ctrl = inl(dev->iobase + APCI1032_CTRL_REG);
- if ((ctrl & APCI1032_CTRL_INT_ENA) == 0)
- return IRQ_HANDLED;
-
- /* disable the interrupt */
- outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG);
-
- s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff;
- val = s->state;
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
-
- /* enable the interrupt */
- outl(ctrl, dev->iobase + APCI1032_CTRL_REG);
-
- return IRQ_HANDLED;
-}
-
-static int apci1032_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inl(dev->iobase + APCI1032_DI_REG);
-
- return insn->n;
-}
-
-static int apci1032_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct apci1032_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv->amcc_iobase = pci_resource_start(pcidev, 0);
- dev->iobase = pci_resource_start(pcidev, 1);
- apci1032_reset(dev);
- if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, apci1032_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- /* Allocate and Initialise DI Subdevice Structures */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1032_di_insn_bits;
-
- /* Change-Of-State (COS) interrupt subdevice */
- s = &dev->subdevices[1];
- if (dev->irq) {
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = apci1032_cos_insn_config;
- s->insn_bits = apci1032_cos_insn_bits;
- s->len_chanlist = 1;
- s->do_cmdtest = apci1032_cos_cmdtest;
- s->do_cmd = apci1032_cos_cmd;
- s->cancel = apci1032_cos_cancel;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- return 0;
-}
-
-static void apci1032_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- apci1032_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver apci1032_driver = {
- .driver_name = "addi_apci_1032",
- .module = THIS_MODULE,
- .auto_attach = apci1032_auto_attach,
- .detach = apci1032_detach,
-};
-
-static int apci1032_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci1032_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci1032_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci1032_pci_table);
-
-static struct pci_driver apci1032_pci_driver = {
- .name = "addi_apci_1032",
- .id_table = apci1032_pci_table,
- .probe = apci1032_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci1032_driver, apci1032_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("ADDI-DATA APCI-1032, 32 channel DI boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
deleted file mode 100644
index b04c15dcfb57..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ /dev/null
@@ -1,887 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_1500.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-#include "amcc_s5933.h"
-#include "z8536.h"
-
-/*
- * PCI Bar 0 Register map (devpriv->amcc)
- * see amcc_s5933.h for register and bit defines
- */
-
-/*
- * PCI Bar 1 Register map (dev->iobase)
- * see z8536.h for Z8536 internal registers and bit defines
- */
-#define APCI1500_Z8536_PORTC_REG 0x00
-#define APCI1500_Z8536_PORTB_REG 0x01
-#define APCI1500_Z8536_PORTA_REG 0x02
-#define APCI1500_Z8536_CTRL_REG 0x03
-
-/*
- * PCI Bar 2 Register map (devpriv->addon)
- */
-#define APCI1500_CLK_SEL_REG 0x00
-#define APCI1500_DI_REG 0x00
-#define APCI1500_DO_REG 0x02
-
-struct apci1500_private {
- unsigned long amcc;
- unsigned long addon;
-
- unsigned int clk_src;
-
- /* Digital trigger configuration [0]=AND [1]=OR */
- unsigned int pm[2]; /* Pattern Mask */
- unsigned int pt[2]; /* Pattern Transition */
- unsigned int pp[2]; /* Pattern Polarity */
-};
-
-static unsigned int z8536_read(struct comedi_device *dev, unsigned int reg)
-{
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
- val = inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return val;
-}
-
-static void z8536_write(struct comedi_device *dev,
- unsigned int val, unsigned int reg)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
- outb(val, dev->iobase + APCI1500_Z8536_CTRL_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static void z8536_reset(struct comedi_device *dev)
-{
- unsigned long flags;
-
- /*
- * Even if the state of the Z8536 is not known, the following
- * sequence will reset it and put it in State 0.
- */
- spin_lock_irqsave(&dev->spinlock, flags);
- inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
- outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
- inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
- outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
- outb(1, dev->iobase + APCI1500_Z8536_CTRL_REG);
- outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* Disable all Ports and Counter/Timers */
- z8536_write(dev, 0x00, Z8536_CFG_CTRL_REG);
-
- /*
- * Port A is connected to Ditial Input channels 0-7.
- * Configure the port to allow interrupt detection.
- */
- z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
- Z8536_PAB_MODE_SB |
- Z8536_PAB_MODE_PMS_DISABLE,
- Z8536_PA_MODE_REG);
- z8536_write(dev, 0xff, Z8536_PB_DPP_REG);
- z8536_write(dev, 0xff, Z8536_PA_DD_REG);
-
- /*
- * Port B is connected to Ditial Input channels 8-13.
- * Configure the port to allow interrupt detection.
- *
- * NOTE: Bits 7 and 6 of Port B are connected to internal
- * diagnostic signals and bit 7 is inverted.
- */
- z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
- Z8536_PAB_MODE_SB |
- Z8536_PAB_MODE_PMS_DISABLE,
- Z8536_PB_MODE_REG);
- z8536_write(dev, 0x7f, Z8536_PB_DPP_REG);
- z8536_write(dev, 0xff, Z8536_PB_DD_REG);
-
- /*
- * Not sure what Port C is connected to...
- */
- z8536_write(dev, 0x09, Z8536_PC_DPP_REG);
- z8536_write(dev, 0x0e, Z8536_PC_DD_REG);
-
- /*
- * Clear and disable all interrupt sources.
- *
- * Just in case, the reset of the Z8536 should have already
- * done this.
- */
- z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PA_CMDSTAT_REG);
- z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
-
- z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PB_CMDSTAT_REG);
- z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
-
- z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(0));
- z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(0));
-
- z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(1));
- z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(1));
-
- z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(2));
- z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(2));
-
- /* Disable all interrupts */
- z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
-}
-
-static void apci1500_port_enable(struct comedi_device *dev, bool enable)
-{
- unsigned int cfg;
-
- cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
- if (enable)
- cfg |= (Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
- else
- cfg &= ~(Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
- z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
-}
-
-static void apci1500_timer_enable(struct comedi_device *dev,
- unsigned int chan, bool enable)
-{
- unsigned int bit;
- unsigned int cfg;
-
- if (chan == 0)
- bit = Z8536_CFG_CTRL_CT1E;
- else if (chan == 1)
- bit = Z8536_CFG_CTRL_CT2E;
- else
- bit = Z8536_CFG_CTRL_PCE_CT3E;
-
- cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
- if (enable) {
- cfg |= bit;
- } else {
- cfg &= ~bit;
- z8536_write(dev, 0x00, Z8536_CT_CMDSTAT_REG(chan));
- }
- z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
-}
-
-static bool apci1500_ack_irq(struct comedi_device *dev,
- unsigned int reg)
-{
- unsigned int val;
-
- val = z8536_read(dev, reg);
- if ((val & Z8536_STAT_IE_IP) == Z8536_STAT_IE_IP) {
- val &= 0x0f; /* preserve any write bits */
- val |= Z8536_CMD_CLR_IP_IUS;
- z8536_write(dev, val, reg);
-
- return true;
- }
- return false;
-}
-
-static irqreturn_t apci1500_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct apci1500_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned short status = 0;
- unsigned int val;
-
- val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
- if (!(val & INTCSR_INTR_ASSERTED))
- return IRQ_NONE;
-
- if (apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG))
- status |= 0x01; /* port a event (inputs 0-7) */
-
- if (apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG)) {
- /* Tests if this is an external error */
- val = inb(dev->iobase + APCI1500_Z8536_PORTB_REG);
- val &= 0xc0;
- if (val) {
- if (val & 0x80) /* voltage error */
- status |= 0x40;
- if (val & 0x40) /* short circuit error */
- status |= 0x80;
- } else {
- status |= 0x02; /* port b event (inputs 8-13) */
- }
- }
-
- /*
- * NOTE: The 'status' returned by the sample matches the
- * interrupt mask information from the APCI-1500 Users Manual.
- *
- * Mask Meaning
- * ---------- ------------------------------------------
- * 0b00000001 Event 1 has occurred
- * 0b00000010 Event 2 has occurred
- * 0b00000100 Counter/timer 1 has run down (not implemented)
- * 0b00001000 Counter/timer 2 has run down (not implemented)
- * 0b00010000 Counter 3 has run down (not implemented)
- * 0b00100000 Watchdog has run down (not implemented)
- * 0b01000000 Voltage error
- * 0b10000000 Short-circuit error
- */
- comedi_buf_write_samples(s, &status, 1);
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int apci1500_di_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- /* Disables the main interrupt on the board */
- z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
-
- /* Disable Ports A & B */
- apci1500_port_enable(dev, false);
-
- /* Ack any pending interrupts */
- apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG);
- apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG);
-
- /* Disable pattern interrupts */
- z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
- z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
-
- /* Enable Ports A & B */
- apci1500_port_enable(dev, true);
-
- return 0;
-}
-
-static int apci1500_di_inttrig_start(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct apci1500_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int pa_mode = Z8536_PAB_MODE_PMS_DISABLE;
- unsigned int pb_mode = Z8536_PAB_MODE_PMS_DISABLE;
- unsigned int pa_trig = trig_num & 0x01;
- unsigned int pb_trig = (trig_num >> 1) & 0x01;
- bool valid_trig = false;
- unsigned int val;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- /* Disable Ports A & B */
- apci1500_port_enable(dev, false);
-
- /* Set Port A for selected trigger pattern */
- z8536_write(dev, devpriv->pm[pa_trig] & 0xff, Z8536_PA_PM_REG);
- z8536_write(dev, devpriv->pt[pa_trig] & 0xff, Z8536_PA_PT_REG);
- z8536_write(dev, devpriv->pp[pa_trig] & 0xff, Z8536_PA_PP_REG);
-
- /* Set Port B for selected trigger pattern */
- z8536_write(dev, (devpriv->pm[pb_trig] >> 8) & 0xff, Z8536_PB_PM_REG);
- z8536_write(dev, (devpriv->pt[pb_trig] >> 8) & 0xff, Z8536_PB_PT_REG);
- z8536_write(dev, (devpriv->pp[pb_trig] >> 8) & 0xff, Z8536_PB_PP_REG);
-
- /* Set Port A trigger mode (if enabled) and enable interrupt */
- if (devpriv->pm[pa_trig] & 0xff) {
- pa_mode = pa_trig ? Z8536_PAB_MODE_PMS_AND
- : Z8536_PAB_MODE_PMS_OR;
-
- val = z8536_read(dev, Z8536_PA_MODE_REG);
- val &= ~Z8536_PAB_MODE_PMS_MASK;
- val |= (pa_mode | Z8536_PAB_MODE_IMO);
- z8536_write(dev, val, Z8536_PA_MODE_REG);
-
- z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PA_CMDSTAT_REG);
-
- valid_trig = true;
-
- dev_dbg(dev->class_dev,
- "Port A configured for %s mode pattern detection\n",
- pa_trig ? "AND" : "OR");
- }
-
- /* Set Port B trigger mode (if enabled) and enable interrupt */
- if (devpriv->pm[pb_trig] & 0xff00) {
- pb_mode = pb_trig ? Z8536_PAB_MODE_PMS_AND
- : Z8536_PAB_MODE_PMS_OR;
-
- val = z8536_read(dev, Z8536_PB_MODE_REG);
- val &= ~Z8536_PAB_MODE_PMS_MASK;
- val |= (pb_mode | Z8536_PAB_MODE_IMO);
- z8536_write(dev, val, Z8536_PB_MODE_REG);
-
- z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PB_CMDSTAT_REG);
-
- valid_trig = true;
-
- dev_dbg(dev->class_dev,
- "Port B configured for %s mode pattern detection\n",
- pb_trig ? "AND" : "OR");
- }
-
- /* Enable Ports A & B */
- apci1500_port_enable(dev, true);
-
- if (!valid_trig) {
- dev_dbg(dev->class_dev,
- "digital trigger %d is not configured\n", trig_num);
- return -EINVAL;
- }
-
- /* Authorizes the main interrupt on the board */
- z8536_write(dev, Z8536_INT_CTRL_MIE | Z8536_INT_CTRL_DLC,
- Z8536_INT_CTRL_REG);
-
- return 0;
-}
-
-static int apci1500_di_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- s->async->inttrig = apci1500_di_inttrig_start;
-
- return 0;
-}
-
-static int apci1500_di_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- /*
- * Internal start source triggers:
- *
- * 0 AND mode for Port A (digital inputs 0-7)
- * AND mode for Port B (digital inputs 8-13 and internal signals)
- *
- * 1 OR mode for Port A (digital inputs 0-7)
- * AND mode for Port B (digital inputs 8-13 and internal signals)
- *
- * 2 AND mode for Port A (digital inputs 0-7)
- * OR mode for Port B (digital inputs 8-13 and internal signals)
- *
- * 3 OR mode for Port A (digital inputs 0-7)
- * OR mode for Port B (digital inputs 8-13 and internal signals)
- */
- err |= comedi_check_trigger_arg_max(&cmd->start_arg, 3);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-/*
- * The pattern-recognition logic must be configured before the digital
- * input async command is started.
- *
- * Digital input channels 0 to 13 can generate interrupts. Channels 14
- * and 15 are connected to internal board status/diagnostic signals.
- *
- * Channel 14 - Voltage error (the external supply is < 5V)
- * Channel 15 - Short-circuit/overtemperature error
- *
- * data[0] : INSN_CONFIG_DIGITAL_TRIG
- * data[1] : trigger number
- * 0 = AND mode
- * 1 = OR mode
- * data[2] : configuration operation:
- * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
- * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = edge interrupts
- * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = level interrupts
- * data[3] : left-shift for data[4] and data[5]
- * data[4] : rising-edge/high level channels
- * data[5] : falling-edge/low level channels
- */
-static int apci1500_di_cfg_trig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1500_private *devpriv = dev->private;
- unsigned int trig = data[1];
- unsigned int shift = data[3];
- unsigned int hi_mask;
- unsigned int lo_mask;
- unsigned int chan_mask;
- unsigned int old_mask;
- unsigned int pm;
- unsigned int pt;
- unsigned int pp;
- unsigned int invalid_chan;
-
- if (trig > 1) {
- dev_dbg(dev->class_dev,
- "invalid digital trigger number (0=AND, 1=OR)\n");
- return -EINVAL;
- }
-
- if (shift <= 16) {
- hi_mask = data[4] << shift;
- lo_mask = data[5] << shift;
- old_mask = (1U << shift) - 1;
- invalid_chan = (data[4] | data[5]) >> (16 - shift);
- } else {
- hi_mask = 0;
- lo_mask = 0;
- old_mask = 0xffff;
- invalid_chan = data[4] | data[5];
- }
- chan_mask = hi_mask | lo_mask;
-
- if (invalid_chan) {
- dev_dbg(dev->class_dev, "invalid digital trigger channel\n");
- return -EINVAL;
- }
-
- pm = devpriv->pm[trig] & old_mask;
- pt = devpriv->pt[trig] & old_mask;
- pp = devpriv->pp[trig] & old_mask;
-
- switch (data[2]) {
- case COMEDI_DIGITAL_TRIG_DISABLE:
- /* clear trigger configuration */
- pm = 0;
- pt = 0;
- pp = 0;
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
- pm |= chan_mask; /* enable channels */
- pt |= chan_mask; /* enable edge detection */
- pp |= hi_mask; /* rising-edge channels */
- pp &= ~lo_mask; /* falling-edge channels */
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
- pm |= chan_mask; /* enable channels */
- pt &= ~chan_mask; /* enable level detection */
- pp |= hi_mask; /* high level channels */
- pp &= ~lo_mask; /* low level channels */
- break;
- default:
- return -EINVAL;
- }
-
- /*
- * The AND mode trigger can only have one channel (max) enabled
- * for edge detection.
- */
- if (trig == 0) {
- int ret = 0;
- unsigned int src;
-
- src = pt & 0xff;
- if (src)
- ret |= comedi_check_trigger_is_unique(src);
-
- src = (pt >> 8) & 0xff;
- if (src)
- ret |= comedi_check_trigger_is_unique(src);
-
- if (ret) {
- dev_dbg(dev->class_dev,
- "invalid AND trigger configuration\n");
- return ret;
- }
- }
-
- /* save the trigger configuration */
- devpriv->pm[trig] = pm;
- devpriv->pt[trig] = pt;
- devpriv->pp[trig] = pp;
-
- return insn->n;
-}
-
-static int apci1500_di_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- switch (data[0]) {
- case INSN_CONFIG_DIGITAL_TRIG:
- return apci1500_di_cfg_trig(dev, s, insn, data);
- default:
- return -EINVAL;
- }
-}
-
-static int apci1500_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1500_private *devpriv = dev->private;
-
- data[1] = inw(devpriv->addon + APCI1500_DI_REG);
-
- return insn->n;
-}
-
-static int apci1500_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1500_private *devpriv = dev->private;
-
- if (comedi_dio_update_state(s, data))
- outw(s->state, devpriv->addon + APCI1500_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int apci1500_timer_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1500_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- val = data[1] & s->maxdata;
- z8536_write(dev, val & 0xff, Z8536_CT_RELOAD_LSB_REG(chan));
- z8536_write(dev, (val >> 8) & 0xff,
- Z8536_CT_RELOAD_MSB_REG(chan));
-
- apci1500_timer_enable(dev, chan, true);
- z8536_write(dev, Z8536_CT_CMDSTAT_GCB,
- Z8536_CT_CMDSTAT_REG(chan));
- break;
- case INSN_CONFIG_DISARM:
- apci1500_timer_enable(dev, chan, false);
- break;
-
- case INSN_CONFIG_GET_COUNTER_STATUS:
- data[1] = 0;
- val = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
- if (val & Z8536_CT_STAT_CIP)
- data[1] |= COMEDI_COUNTER_COUNTING;
- if (val & Z8536_CT_CMDSTAT_GCB)
- data[1] |= COMEDI_COUNTER_ARMED;
- if (val & Z8536_STAT_IP) {
- data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
- apci1500_ack_irq(dev, Z8536_CT_CMDSTAT_REG(chan));
- }
- data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
- COMEDI_COUNTER_TERMINAL_COUNT;
- break;
-
- case INSN_CONFIG_SET_COUNTER_MODE:
- /* Simulate the 8254 timer modes */
- switch (data[1]) {
- case I8254_MODE0:
- /* Interrupt on Terminal Count */
- val = Z8536_CT_MODE_ECE |
- Z8536_CT_MODE_DCS_ONESHOT;
- break;
- case I8254_MODE1:
- /* Hardware Retriggerable One-Shot */
- val = Z8536_CT_MODE_ETE |
- Z8536_CT_MODE_DCS_ONESHOT;
- break;
- case I8254_MODE2:
- /* Rate Generator */
- val = Z8536_CT_MODE_CSC |
- Z8536_CT_MODE_DCS_PULSE;
- break;
- case I8254_MODE3:
- /* Square Wave Mode */
- val = Z8536_CT_MODE_CSC |
- Z8536_CT_MODE_DCS_SQRWAVE;
- break;
- case I8254_MODE4:
- /* Software Triggered Strobe */
- val = Z8536_CT_MODE_REB |
- Z8536_CT_MODE_DCS_PULSE;
- break;
- case I8254_MODE5:
- /* Hardware Triggered Strobe (watchdog) */
- val = Z8536_CT_MODE_EOE |
- Z8536_CT_MODE_ETE |
- Z8536_CT_MODE_REB |
- Z8536_CT_MODE_DCS_PULSE;
- break;
- default:
- return -EINVAL;
- }
- apci1500_timer_enable(dev, chan, false);
- z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
- break;
-
- case INSN_CONFIG_SET_CLOCK_SRC:
- if (data[1] > 2)
- return -EINVAL;
- devpriv->clk_src = data[1];
- if (devpriv->clk_src == 2)
- devpriv->clk_src = 3;
- outw(devpriv->clk_src, devpriv->addon + APCI1500_CLK_SEL_REG);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- switch (devpriv->clk_src) {
- case 0:
- data[1] = 0; /* 111.86 kHz / 2 */
- data[2] = 17879; /* 17879 ns (approx) */
- break;
- case 1:
- data[1] = 1; /* 3.49 kHz / 2 */
- data[2] = 573066; /* 573066 ns (approx) */
- break;
- case 3:
- data[1] = 2; /* 1.747 kHz / 2 */
- data[2] = 1164822; /* 1164822 ns (approx) */
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case INSN_CONFIG_SET_GATE_SRC:
- if (chan == 0)
- return -EINVAL;
-
- val = z8536_read(dev, Z8536_CT_MODE_REG(chan));
- val &= Z8536_CT_MODE_EGE;
- if (data[1] == 1)
- val |= Z8536_CT_MODE_EGE;
- else if (data[1] > 1)
- return -EINVAL;
- z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
- break;
- case INSN_CONFIG_GET_GATE_SRC:
- if (chan == 0)
- return -EINVAL;
- break;
-
- default:
- return -EINVAL;
- }
- return insn->n;
-}
-
-static int apci1500_timer_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int cmd;
-
- cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
- cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */
- cmd |= Z8536_CT_CMD_TCB; /* set trigger */
-
- /* software trigger a timer, it only makes sense to do one write */
- if (insn->n)
- z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
-
- return insn->n;
-}
-
-static int apci1500_timer_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int cmd;
- unsigned int val;
- int i;
-
- cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
- cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */
- cmd |= Z8536_CT_CMD_RCC; /* set RCC */
-
- for (i = 0; i < insn->n; i++) {
- z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
-
- val = z8536_read(dev, Z8536_CT_VAL_MSB_REG(chan)) << 8;
- val |= z8536_read(dev, Z8536_CT_VAL_LSB_REG(chan));
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int apci1500_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct apci1500_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->iobase = pci_resource_start(pcidev, 1);
- devpriv->amcc = pci_resource_start(pcidev, 0);
- devpriv->addon = pci_resource_start(pcidev, 2);
-
- z8536_reset(dev);
-
- if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1500_di_insn_bits;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 1;
- s->insn_config = apci1500_di_insn_config;
- s->do_cmdtest = apci1500_di_cmdtest;
- s->do_cmd = apci1500_di_cmd;
- s->cancel = apci1500_di_cancel;
- }
-
- /* Digital Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1500_do_insn_bits;
-
- /* reset all the digital outputs */
- outw(0x0, devpriv->addon + APCI1500_DO_REG);
-
- /* Counter/Timer(Watchdog) subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 3;
- s->maxdata = 0xffff;
- s->range_table = &range_unknown;
- s->insn_config = apci1500_timer_insn_config;
- s->insn_write = apci1500_timer_insn_write;
- s->insn_read = apci1500_timer_insn_read;
-
- /* Enable the PCI interrupt */
- if (dev->irq) {
- outl(0x2000 | INTCSR_INBOX_FULL_INT,
- devpriv->amcc + AMCC_OP_REG_INTCSR);
- inl(devpriv->amcc + AMCC_OP_REG_IMB1);
- inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
- outl(INTCSR_INBOX_INTR_STATUS | 0x2000 | INTCSR_INBOX_FULL_INT,
- devpriv->amcc + AMCC_OP_REG_INTCSR);
- }
-
- return 0;
-}
-
-static void apci1500_detach(struct comedi_device *dev)
-{
- struct apci1500_private *devpriv = dev->private;
-
- if (devpriv->amcc)
- outl(0x0, devpriv->amcc + AMCC_OP_REG_INTCSR);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver apci1500_driver = {
- .driver_name = "addi_apci_1500",
- .module = THIS_MODULE,
- .auto_attach = apci1500_auto_attach,
- .detach = apci1500_detach,
-};
-
-static int apci1500_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci1500_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80fc) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci1500_pci_table);
-
-static struct pci_driver apci1500_pci_driver = {
- .name = "addi_apci_1500",
- .id_table = apci1500_pci_table,
- .probe = apci1500_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("ADDI-DATA APCI-1500, 16 channel DI / 16 channel DO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c
deleted file mode 100644
index 274ec9fb030c..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_1516.c
+++ /dev/null
@@ -1,216 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_1516.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- * Project manager: Eric Stolz
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-#include "addi_watchdog.h"
-
-/*
- * PCI bar 1 I/O Register map - Digital input/output
- */
-#define APCI1516_DI_REG 0x00
-#define APCI1516_DO_REG 0x04
-
-/*
- * PCI bar 2 I/O Register map - Watchdog (APCI-1516 and APCI-2016)
- */
-#define APCI1516_WDOG_REG 0x00
-
-enum apci1516_boardid {
- BOARD_APCI1016,
- BOARD_APCI1516,
- BOARD_APCI2016,
-};
-
-struct apci1516_boardinfo {
- const char *name;
- int di_nchan;
- int do_nchan;
- int has_wdog;
-};
-
-static const struct apci1516_boardinfo apci1516_boardtypes[] = {
- [BOARD_APCI1016] = {
- .name = "apci1016",
- .di_nchan = 16,
- },
- [BOARD_APCI1516] = {
- .name = "apci1516",
- .di_nchan = 8,
- .do_nchan = 8,
- .has_wdog = 1,
- },
- [BOARD_APCI2016] = {
- .name = "apci2016",
- .do_nchan = 16,
- .has_wdog = 1,
- },
-};
-
-struct apci1516_private {
- unsigned long wdog_iobase;
-};
-
-static int apci1516_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inw(dev->iobase + APCI1516_DI_REG);
-
- return insn->n;
-}
-
-static int apci1516_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- s->state = inw(dev->iobase + APCI1516_DO_REG);
-
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + APCI1516_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int apci1516_reset(struct comedi_device *dev)
-{
- const struct apci1516_boardinfo *board = dev->board_ptr;
- struct apci1516_private *devpriv = dev->private;
-
- if (!board->has_wdog)
- return 0;
-
- outw(0x0, dev->iobase + APCI1516_DO_REG);
-
- addi_watchdog_reset(devpriv->wdog_iobase);
-
- return 0;
-}
-
-static int apci1516_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct apci1516_boardinfo *board = NULL;
- struct apci1516_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- if (context < ARRAY_SIZE(apci1516_boardtypes))
- board = &apci1516_boardtypes[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->iobase = pci_resource_start(pcidev, 1);
- devpriv->wdog_iobase = pci_resource_start(pcidev, 2);
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Initialize the digital input subdevice */
- s = &dev->subdevices[0];
- if (board->di_nchan) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = board->di_nchan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1516_di_insn_bits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Initialize the digital output subdevice */
- s = &dev->subdevices[1];
- if (board->do_nchan) {
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->do_nchan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1516_do_insn_bits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Initialize the watchdog subdevice */
- s = &dev->subdevices[2];
- if (board->has_wdog) {
- ret = addi_watchdog_init(s, devpriv->wdog_iobase);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- apci1516_reset(dev);
- return 0;
-}
-
-static void apci1516_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- apci1516_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver apci1516_driver = {
- .driver_name = "addi_apci_1516",
- .module = THIS_MODULE,
- .auto_attach = apci1516_auto_attach,
- .detach = apci1516_detach,
-};
-
-static int apci1516_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci1516_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci1516_pci_table[] = {
- { PCI_VDEVICE(ADDIDATA, 0x1000), BOARD_APCI1016 },
- { PCI_VDEVICE(ADDIDATA, 0x1001), BOARD_APCI1516 },
- { PCI_VDEVICE(ADDIDATA, 0x1002), BOARD_APCI2016 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci1516_pci_table);
-
-static struct pci_driver apci1516_pci_driver = {
- .name = "addi_apci_1516",
- .id_table = apci1516_pci_table,
- .probe = apci1516_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci1516_driver, apci1516_pci_driver);
-
-MODULE_DESCRIPTION("ADDI-DATA APCI-1016/1516/2016, 16 channel DIO boards");
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
deleted file mode 100644
index 06fc7ed96200..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ /dev/null
@@ -1,820 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_1564.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-/*
- * Driver: addi_apci_1564
- * Description: ADDI-DATA APCI-1564 Digital I/O board
- * Devices: [ADDI-DATA] APCI-1564 (addi_apci_1564)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Thu, 02 Jun 2016 13:12:46 -0700
- * Status: untested
- *
- * Configuration Options: not applicable, uses comedi PCI auto config
- *
- * This board has the following features:
- * - 32 optically isolated digital inputs (24V), 16 of which can
- * generate change-of-state (COS) interrupts (channels 4 to 19)
- * - 32 optically isolated digital outputs (10V to 36V)
- * - 1 8-bit watchdog for resetting the outputs
- * - 1 12-bit timer
- * - 3 32-bit counters
- * - 2 diagnostic inputs
- *
- * The COS, timer, and counter subdevices all use the dev->read_subdev to
- * return the interrupt status. The sample data is updated and returned when
- * any of these subdevices generate an interrupt. The sample data format is:
- *
- * Bit Description
- * ----- ------------------------------------------
- * 31 COS interrupt
- * 30 timer interrupt
- * 29 counter 2 interrupt
- * 28 counter 1 interrupt
- * 27 counter 0 interrupt
- * 26:20 not used
- * 19:4 COS digital input state (channels 19 to 4)
- * 3:0 not used
- *
- * The COS interrupts must be configured using an INSN_CONFIG_DIGITAL_TRIG
- * instruction before they can be enabled by an async command. The COS
- * interrupts will stay active until canceled.
- *
- * The timer subdevice does not use an async command. All control is handled
- * by the (*insn_config).
- *
- * FIXME: The format of the ADDI_TCW_TIMEBASE_REG is not descibed in the
- * datasheet I have. The INSN_CONFIG_SET_CLOCK_SRC currently just writes
- * the raw data[1] to this register along with the raw data[2] value to the
- * ADDI_TCW_RELOAD_REG. If anyone tests this and can determine the actual
- * timebase/reload operation please let me know.
- *
- * The counter subdevice also does not use an async command. All control is
- * handled by the (*insn_config).
- *
- * FIXME: The operation of the counters is not really described in the
- * datasheet I have. The (*insn_config) needs more work.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-#include "addi_tcw.h"
-#include "addi_watchdog.h"
-
-/*
- * PCI BAR 0
- *
- * PLD Revision 1.0 I/O Mapping
- * 0x00 93C76 EEPROM
- * 0x04 - 0x18 Timer 12-Bit
- *
- * PLD Revision 2.x I/O Mapping
- * 0x00 93C76 EEPROM
- * 0x04 - 0x14 Digital Input
- * 0x18 - 0x25 Digital Output
- * 0x28 - 0x44 Watchdog 8-Bit
- * 0x48 - 0x64 Timer 12-Bit
- */
-#define APCI1564_EEPROM_REG 0x00
-#define APCI1564_EEPROM_VCC_STATUS BIT(8)
-#define APCI1564_EEPROM_TO_REV(x) (((x) >> 4) & 0xf)
-#define APCI1564_EEPROM_DI BIT(3)
-#define APCI1564_EEPROM_DO BIT(2)
-#define APCI1564_EEPROM_CS BIT(1)
-#define APCI1564_EEPROM_CLK BIT(0)
-#define APCI1564_REV1_TIMER_IOBASE 0x04
-#define APCI1564_REV2_MAIN_IOBASE 0x04
-#define APCI1564_REV2_TIMER_IOBASE 0x48
-
-/*
- * PCI BAR 1
- *
- * PLD Revision 1.0 I/O Mapping
- * 0x00 - 0x10 Digital Input
- * 0x14 - 0x20 Digital Output
- * 0x24 - 0x3c Watchdog 8-Bit
- *
- * PLD Revision 2.x I/O Mapping
- * 0x00 Counter_0
- * 0x20 Counter_1
- * 0x30 Counter_3
- */
-#define APCI1564_REV1_MAIN_IOBASE 0x00
-
-/*
- * dev->iobase Register Map
- * PLD Revision 1.0 - PCI BAR 1 + 0x00
- * PLD Revision 2.x - PCI BAR 0 + 0x04
- */
-#define APCI1564_DI_REG 0x00
-#define APCI1564_DI_INT_MODE1_REG 0x04
-#define APCI1564_DI_INT_MODE2_REG 0x08
-#define APCI1564_DI_INT_MODE_MASK 0x000ffff0 /* chans [19:4] */
-#define APCI1564_DI_INT_STATUS_REG 0x0c
-#define APCI1564_DI_IRQ_REG 0x10
-#define APCI1564_DI_IRQ_ENA BIT(2)
-#define APCI1564_DI_IRQ_MODE BIT(1) /* 1=AND, 0=OR */
-#define APCI1564_DO_REG 0x14
-#define APCI1564_DO_INT_CTRL_REG 0x18
-#define APCI1564_DO_INT_CTRL_CC_INT_ENA BIT(1)
-#define APCI1564_DO_INT_CTRL_VCC_INT_ENA BIT(0)
-#define APCI1564_DO_INT_STATUS_REG 0x1c
-#define APCI1564_DO_INT_STATUS_CC BIT(1)
-#define APCI1564_DO_INT_STATUS_VCC BIT(0)
-#define APCI1564_DO_IRQ_REG 0x20
-#define APCI1564_DO_IRQ_INTR BIT(0)
-#define APCI1564_WDOG_IOBASE 0x24
-
-/*
- * devpriv->timer Register Map (see addi_tcw.h for register/bit defines)
- * PLD Revision 1.0 - PCI BAR 0 + 0x04
- * PLD Revision 2.x - PCI BAR 0 + 0x48
- */
-
-/*
- * devpriv->counters Register Map (see addi_tcw.h for register/bit defines)
- * PLD Revision 2.x - PCI BAR 1 + 0x00
- */
-#define APCI1564_COUNTER(x) ((x) * 0x20)
-
-/*
- * The dev->read_subdev is used to return the interrupt events along with
- * the state of the interrupt capable inputs.
- */
-#define APCI1564_EVENT_COS BIT(31)
-#define APCI1564_EVENT_TIMER BIT(30)
-#define APCI1564_EVENT_COUNTER(x) BIT(27 + (x)) /* counter 0-2 */
-#define APCI1564_EVENT_MASK 0xfff0000f /* all but [19:4] */
-
-struct apci1564_private {
- unsigned long eeprom; /* base address of EEPROM register */
- unsigned long timer; /* base address of 12-bit timer */
- unsigned long counters; /* base address of 32-bit counters */
- unsigned int mode1; /* rising-edge/high level channels */
- unsigned int mode2; /* falling-edge/low level channels */
- unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */
-};
-
-static int apci1564_reset(struct comedi_device *dev)
-{
- struct apci1564_private *devpriv = dev->private;
-
- /* Disable the input interrupts and reset status register */
- outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG);
- inl(dev->iobase + APCI1564_DI_INT_STATUS_REG);
- outl(0x0, dev->iobase + APCI1564_DI_INT_MODE1_REG);
- outl(0x0, dev->iobase + APCI1564_DI_INT_MODE2_REG);
-
- /* Reset the output channels and disable interrupts */
- outl(0x0, dev->iobase + APCI1564_DO_REG);
- outl(0x0, dev->iobase + APCI1564_DO_INT_CTRL_REG);
-
- /* Reset the watchdog registers */
- addi_watchdog_reset(dev->iobase + APCI1564_WDOG_IOBASE);
-
- /* Reset the timer registers */
- outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG);
- outl(0x0, devpriv->timer + ADDI_TCW_RELOAD_REG);
-
- if (devpriv->counters) {
- unsigned long iobase = devpriv->counters + ADDI_TCW_CTRL_REG;
-
- /* Reset the counter registers */
- outl(0x0, iobase + APCI1564_COUNTER(0));
- outl(0x0, iobase + APCI1564_COUNTER(1));
- outl(0x0, iobase + APCI1564_COUNTER(2));
- }
-
- return 0;
-}
-
-static irqreturn_t apci1564_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct apci1564_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int status;
- unsigned int ctrl;
- unsigned int chan;
-
- s->state &= ~APCI1564_EVENT_MASK;
-
- status = inl(dev->iobase + APCI1564_DI_IRQ_REG);
- if (status & APCI1564_DI_IRQ_ENA) {
- /* get the COS interrupt state and set the event flag */
- s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG);
- s->state &= APCI1564_DI_INT_MODE_MASK;
- s->state |= APCI1564_EVENT_COS;
-
- /* clear the interrupt */
- outl(status & ~APCI1564_DI_IRQ_ENA,
- dev->iobase + APCI1564_DI_IRQ_REG);
- outl(status, dev->iobase + APCI1564_DI_IRQ_REG);
- }
-
- status = inl(devpriv->timer + ADDI_TCW_IRQ_REG);
- if (status & ADDI_TCW_IRQ) {
- s->state |= APCI1564_EVENT_TIMER;
-
- /* clear the interrupt */
- ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
- outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG);
- outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
- }
-
- if (devpriv->counters) {
- for (chan = 0; chan < 3; chan++) {
- unsigned long iobase;
-
- iobase = devpriv->counters + APCI1564_COUNTER(chan);
-
- status = inl(iobase + ADDI_TCW_IRQ_REG);
- if (status & ADDI_TCW_IRQ) {
- s->state |= APCI1564_EVENT_COUNTER(chan);
-
- /* clear the interrupt */
- ctrl = inl(iobase + ADDI_TCW_CTRL_REG);
- outl(0x0, iobase + ADDI_TCW_CTRL_REG);
- outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
- }
- }
- }
-
- if (s->state & APCI1564_EVENT_MASK) {
- comedi_buf_write_samples(s, &s->state, 1);
- comedi_handle_events(dev, s);
- }
-
- return IRQ_HANDLED;
-}
-
-static int apci1564_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inl(dev->iobase + APCI1564_DI_REG);
-
- return insn->n;
-}
-
-static int apci1564_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- s->state = inl(dev->iobase + APCI1564_DO_REG);
-
- if (comedi_dio_update_state(s, data))
- outl(s->state, dev->iobase + APCI1564_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int apci1564_diag_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inl(dev->iobase + APCI1564_DO_INT_STATUS_REG) & 3;
-
- return insn->n;
-}
-
-/*
- * Change-Of-State (COS) interrupt configuration
- *
- * Channels 4 to 19 are interruptible. These channels can be configured
- * to generate interrupts based on AND/OR logic for the desired channels.
- *
- * OR logic
- * - reacts to rising or falling edges
- * - interrupt is generated when any enabled channel
- * meet the desired interrupt condition
- *
- * AND logic
- * - reacts to changes in level of the selected inputs
- * - interrupt is generated when all enabled channels
- * meet the desired interrupt condition
- * - after an interrupt, a change in level must occur on
- * the selected inputs to release the IRQ logic
- *
- * The COS interrupt must be configured before it can be enabled.
- *
- * data[0] : INSN_CONFIG_DIGITAL_TRIG
- * data[1] : trigger number (= 0)
- * data[2] : configuration operation:
- * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
- * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
- * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
- * data[3] : left-shift for data[4] and data[5]
- * data[4] : rising-edge/high level channels
- * data[5] : falling-edge/low level channels
- */
-static int apci1564_cos_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1564_private *devpriv = dev->private;
- unsigned int shift, oldmask, himask, lomask;
-
- switch (data[0]) {
- case INSN_CONFIG_DIGITAL_TRIG:
- if (data[1] != 0)
- return -EINVAL;
- shift = data[3];
- if (shift < 32) {
- oldmask = (1U << shift) - 1;
- himask = data[4] << shift;
- lomask = data[5] << shift;
- } else {
- oldmask = 0xffffffffu;
- himask = 0;
- lomask = 0;
- }
- switch (data[2]) {
- case COMEDI_DIGITAL_TRIG_DISABLE:
- devpriv->ctrl = 0;
- devpriv->mode1 = 0;
- devpriv->mode2 = 0;
- outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG);
- inl(dev->iobase + APCI1564_DI_INT_STATUS_REG);
- outl(0x0, dev->iobase + APCI1564_DI_INT_MODE1_REG);
- outl(0x0, dev->iobase + APCI1564_DI_INT_MODE2_REG);
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
- if (devpriv->ctrl != APCI1564_DI_IRQ_ENA) {
- /* switching to 'OR' mode */
- devpriv->ctrl = APCI1564_DI_IRQ_ENA;
- /* wipe old channels */
- devpriv->mode1 = 0;
- devpriv->mode2 = 0;
- } else {
- /* preserve unspecified channels */
- devpriv->mode1 &= oldmask;
- devpriv->mode2 &= oldmask;
- }
- /* configure specified channels */
- devpriv->mode1 |= himask;
- devpriv->mode2 |= lomask;
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
- if (devpriv->ctrl != (APCI1564_DI_IRQ_ENA |
- APCI1564_DI_IRQ_MODE)) {
- /* switching to 'AND' mode */
- devpriv->ctrl = APCI1564_DI_IRQ_ENA |
- APCI1564_DI_IRQ_MODE;
- /* wipe old channels */
- devpriv->mode1 = 0;
- devpriv->mode2 = 0;
- } else {
- /* preserve unspecified channels */
- devpriv->mode1 &= oldmask;
- devpriv->mode2 &= oldmask;
- }
- /* configure specified channels */
- devpriv->mode1 |= himask;
- devpriv->mode2 |= lomask;
- break;
- default:
- return -EINVAL;
- }
-
- /* ensure the mode bits are in-range for channels [19:4] */
- devpriv->mode1 &= APCI1564_DI_INT_MODE_MASK;
- devpriv->mode2 &= APCI1564_DI_INT_MODE_MASK;
- break;
- default:
- return -EINVAL;
- }
- return insn->n;
-}
-
-static int apci1564_cos_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = s->state;
-
- return 0;
-}
-
-static int apci1564_cos_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-/*
- * Change-Of-State (COS) 'do_cmd' operation
- *
- * Enable the COS interrupt as configured by apci1564_cos_insn_config().
- */
-static int apci1564_cos_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci1564_private *devpriv = dev->private;
-
- if (!devpriv->ctrl && !(devpriv->mode1 || devpriv->mode2)) {
- dev_warn(dev->class_dev,
- "Interrupts disabled due to mode configuration!\n");
- return -EINVAL;
- }
-
- outl(devpriv->mode1, dev->iobase + APCI1564_DI_INT_MODE1_REG);
- outl(devpriv->mode2, dev->iobase + APCI1564_DI_INT_MODE2_REG);
- outl(devpriv->ctrl, dev->iobase + APCI1564_DI_IRQ_REG);
-
- return 0;
-}
-
-static int apci1564_cos_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG);
- inl(dev->iobase + APCI1564_DI_INT_STATUS_REG);
- outl(0x0, dev->iobase + APCI1564_DI_INT_MODE1_REG);
- outl(0x0, dev->iobase + APCI1564_DI_INT_MODE2_REG);
-
- return 0;
-}
-
-static int apci1564_timer_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1564_private *devpriv = dev->private;
- unsigned int val;
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- if (data[1] > s->maxdata)
- return -EINVAL;
- outl(data[1], devpriv->timer + ADDI_TCW_RELOAD_REG);
- outl(ADDI_TCW_CTRL_IRQ_ENA | ADDI_TCW_CTRL_TIMER_ENA,
- devpriv->timer + ADDI_TCW_CTRL_REG);
- break;
- case INSN_CONFIG_DISARM:
- outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG);
- break;
- case INSN_CONFIG_GET_COUNTER_STATUS:
- data[1] = 0;
- val = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
- if (val & ADDI_TCW_CTRL_IRQ_ENA)
- data[1] |= COMEDI_COUNTER_ARMED;
- if (val & ADDI_TCW_CTRL_TIMER_ENA)
- data[1] |= COMEDI_COUNTER_COUNTING;
- val = inl(devpriv->timer + ADDI_TCW_STATUS_REG);
- if (val & ADDI_TCW_STATUS_OVERFLOW)
- data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
- data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
- COMEDI_COUNTER_TERMINAL_COUNT;
- break;
- case INSN_CONFIG_SET_CLOCK_SRC:
- if (data[2] > s->maxdata)
- return -EINVAL;
- outl(data[1], devpriv->timer + ADDI_TCW_TIMEBASE_REG);
- outl(data[2], devpriv->timer + ADDI_TCW_RELOAD_REG);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- data[1] = inl(devpriv->timer + ADDI_TCW_TIMEBASE_REG);
- data[2] = inl(devpriv->timer + ADDI_TCW_RELOAD_REG);
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int apci1564_timer_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1564_private *devpriv = dev->private;
-
- /* just write the last to the reload register */
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- outl(val, devpriv->timer + ADDI_TCW_RELOAD_REG);
- }
-
- return insn->n;
-}
-
-static int apci1564_timer_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1564_private *devpriv = dev->private;
- int i;
-
- /* return the actual value of the timer */
- for (i = 0; i < insn->n; i++)
- data[i] = inl(devpriv->timer + ADDI_TCW_VAL_REG);
-
- return insn->n;
-}
-
-static int apci1564_counter_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1564_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
- unsigned int val;
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- val = inl(iobase + ADDI_TCW_CTRL_REG);
- val |= ADDI_TCW_CTRL_IRQ_ENA | ADDI_TCW_CTRL_CNTR_ENA;
- outl(data[1], iobase + ADDI_TCW_RELOAD_REG);
- outl(val, iobase + ADDI_TCW_CTRL_REG);
- break;
- case INSN_CONFIG_DISARM:
- val = inl(iobase + ADDI_TCW_CTRL_REG);
- val &= ~(ADDI_TCW_CTRL_IRQ_ENA | ADDI_TCW_CTRL_CNTR_ENA);
- outl(val, iobase + ADDI_TCW_CTRL_REG);
- break;
- case INSN_CONFIG_SET_COUNTER_MODE:
- /*
- * FIXME: The counter operation is not described in the
- * datasheet. For now just write the raw data[1] value to
- * the control register.
- */
- outl(data[1], iobase + ADDI_TCW_CTRL_REG);
- break;
- case INSN_CONFIG_GET_COUNTER_STATUS:
- data[1] = 0;
- val = inl(iobase + ADDI_TCW_CTRL_REG);
- if (val & ADDI_TCW_CTRL_IRQ_ENA)
- data[1] |= COMEDI_COUNTER_ARMED;
- if (val & ADDI_TCW_CTRL_CNTR_ENA)
- data[1] |= COMEDI_COUNTER_COUNTING;
- val = inl(iobase + ADDI_TCW_STATUS_REG);
- if (val & ADDI_TCW_STATUS_OVERFLOW)
- data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
- data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
- COMEDI_COUNTER_TERMINAL_COUNT;
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int apci1564_counter_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1564_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
-
- /* just write the last to the reload register */
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- outl(val, iobase + ADDI_TCW_RELOAD_REG);
- }
-
- return insn->n;
-}
-
-static int apci1564_counter_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci1564_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
- int i;
-
- /* return the actual value of the counter */
- for (i = 0; i < insn->n; i++)
- data[i] = inl(iobase + ADDI_TCW_VAL_REG);
-
- return insn->n;
-}
-
-static int apci1564_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct apci1564_private *devpriv;
- struct comedi_subdevice *s;
- unsigned int val;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- /* read the EEPROM register and check the I/O map revision */
- devpriv->eeprom = pci_resource_start(pcidev, 0);
- val = inl(devpriv->eeprom + APCI1564_EEPROM_REG);
- if (APCI1564_EEPROM_TO_REV(val) == 0) {
- /* PLD Revision 1.0 I/O Mapping */
- dev->iobase = pci_resource_start(pcidev, 1) +
- APCI1564_REV1_MAIN_IOBASE;
- devpriv->timer = devpriv->eeprom + APCI1564_REV1_TIMER_IOBASE;
- } else {
- /* PLD Revision 2.x I/O Mapping */
- dev->iobase = devpriv->eeprom + APCI1564_REV2_MAIN_IOBASE;
- devpriv->timer = devpriv->eeprom + APCI1564_REV2_TIMER_IOBASE;
- devpriv->counters = pci_resource_start(pcidev, 1);
- }
-
- apci1564_reset(dev);
-
- if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, apci1564_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, 7);
- if (ret)
- return ret;
-
- /* Allocate and Initialise DI Subdevice Structures */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1564_di_insn_bits;
-
- /* Allocate and Initialise DO Subdevice Structures */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1564_do_insn_bits;
-
- /* Change-Of-State (COS) interrupt subdevice */
- s = &dev->subdevices[2];
- if (dev->irq) {
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ | SDF_LSAMPL;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->len_chanlist = 1;
- s->insn_config = apci1564_cos_insn_config;
- s->insn_bits = apci1564_cos_insn_bits;
- s->do_cmdtest = apci1564_cos_cmdtest;
- s->do_cmd = apci1564_cos_cmd;
- s->cancel = apci1564_cos_cancel;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Timer subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 1;
- s->maxdata = 0x0fff;
- s->range_table = &range_digital;
- s->insn_config = apci1564_timer_insn_config;
- s->insn_write = apci1564_timer_insn_write;
- s->insn_read = apci1564_timer_insn_read;
-
- /* Counter subdevice */
- s = &dev->subdevices[4];
- if (devpriv->counters) {
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
- s->n_chan = 3;
- s->maxdata = 0xffffffff;
- s->range_table = &range_digital;
- s->insn_config = apci1564_counter_insn_config;
- s->insn_write = apci1564_counter_insn_write;
- s->insn_read = apci1564_counter_insn_read;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Initialize the watchdog subdevice */
- s = &dev->subdevices[5];
- ret = addi_watchdog_init(s, dev->iobase + APCI1564_WDOG_IOBASE);
- if (ret)
- return ret;
-
- /* Initialize the diagnostic status subdevice */
- s = &dev->subdevices[6];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 2;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci1564_diag_insn_bits;
-
- return 0;
-}
-
-static void apci1564_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- apci1564_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver apci1564_driver = {
- .driver_name = "addi_apci_1564",
- .module = THIS_MODULE,
- .auto_attach = apci1564_auto_attach,
- .detach = apci1564_detach,
-};
-
-static int apci1564_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci1564_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci1564_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci1564_pci_table);
-
-static struct pci_driver apci1564_pci_driver = {
- .name = "addi_apci_1564",
- .id_table = apci1564_pci_table,
- .probe = apci1564_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci1564_driver, apci1564_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("ADDI-DATA APCI-1564, 32 channel DI / 32 channel DO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c
deleted file mode 100644
index c306aa41df97..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_16xx.c
+++ /dev/null
@@ -1,178 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_16xx.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- * Project manager: S. Weber
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-/*
- * Register I/O map
- */
-#define APCI16XX_IN_REG(x) (((x) * 4) + 0x08)
-#define APCI16XX_OUT_REG(x) (((x) * 4) + 0x14)
-#define APCI16XX_DIR_REG(x) (((x) * 4) + 0x20)
-
-enum apci16xx_boardid {
- BOARD_APCI1648,
- BOARD_APCI1696,
-};
-
-struct apci16xx_boardinfo {
- const char *name;
- int n_chan;
-};
-
-static const struct apci16xx_boardinfo apci16xx_boardtypes[] = {
- [BOARD_APCI1648] = {
- .name = "apci1648",
- .n_chan = 48, /* 2 subdevices */
- },
- [BOARD_APCI1696] = {
- .name = "apci1696",
- .n_chan = 96, /* 3 subdevices */
- },
-};
-
-static int apci16xx_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x000000ff;
- else if (chan < 16)
- mask = 0x0000ff00;
- else if (chan < 24)
- mask = 0x00ff0000;
- else
- mask = 0xff000000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- outl(s->io_bits, dev->iobase + APCI16XX_DIR_REG(s->index));
-
- return insn->n;
-}
-
-static int apci16xx_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outl(s->state, dev->iobase + APCI16XX_OUT_REG(s->index));
-
- data[1] = inl(dev->iobase + APCI16XX_IN_REG(s->index));
-
- return insn->n;
-}
-
-static int apci16xx_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct apci16xx_boardinfo *board = NULL;
- struct comedi_subdevice *s;
- unsigned int n_subdevs;
- unsigned int last;
- int i;
- int ret;
-
- if (context < ARRAY_SIZE(apci16xx_boardtypes))
- board = &apci16xx_boardtypes[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->iobase = pci_resource_start(pcidev, 0);
-
- /*
- * Work out the number of subdevices needed to support all the
- * digital i/o channels on the board. Each subdevice supports
- * up to 32 channels.
- */
- n_subdevs = board->n_chan / 32;
- if ((n_subdevs * 32) < board->n_chan) {
- last = board->n_chan - (n_subdevs * 32);
- n_subdevs++;
- } else {
- last = 0;
- }
-
- ret = comedi_alloc_subdevices(dev, n_subdevs);
- if (ret)
- return ret;
-
- /* Initialize the TTL digital i/o subdevices */
- for (i = 0; i < n_subdevs; i++) {
- s = &dev->subdevices[i];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = ((i * 32) < board->n_chan) ? 32 : last;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = apci16xx_insn_config;
- s->insn_bits = apci16xx_dio_insn_bits;
-
- /* Default all channels to inputs */
- s->io_bits = 0;
- outl(s->io_bits, dev->iobase + APCI16XX_DIR_REG(i));
- }
-
- return 0;
-}
-
-static struct comedi_driver apci16xx_driver = {
- .driver_name = "addi_apci_16xx",
- .module = THIS_MODULE,
- .auto_attach = apci16xx_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int apci16xx_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci16xx_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci16xx_pci_table[] = {
- { PCI_VDEVICE(ADDIDATA, 0x1009), BOARD_APCI1648 },
- { PCI_VDEVICE(ADDIDATA, 0x100a), BOARD_APCI1696 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci16xx_pci_table);
-
-static struct pci_driver apci16xx_pci_driver = {
- .name = "addi_apci_16xx",
- .id_table = apci16xx_pci_table,
- .probe = apci16xx_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci16xx_driver, apci16xx_pci_driver);
-
-MODULE_DESCRIPTION("ADDI-DATA APCI-1648/1696, TTL I/O boards");
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c
deleted file mode 100644
index e9a2b37a4ae0..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_2032.c
+++ /dev/null
@@ -1,330 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_2032.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- * Project manager: Eric Stolz
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include "../comedi_pci.h"
-#include "addi_watchdog.h"
-
-/*
- * PCI bar 1 I/O Register map
- */
-#define APCI2032_DO_REG 0x00
-#define APCI2032_INT_CTRL_REG 0x04
-#define APCI2032_INT_CTRL_VCC_ENA BIT(0)
-#define APCI2032_INT_CTRL_CC_ENA BIT(1)
-#define APCI2032_INT_STATUS_REG 0x08
-#define APCI2032_INT_STATUS_VCC BIT(0)
-#define APCI2032_INT_STATUS_CC BIT(1)
-#define APCI2032_STATUS_REG 0x0c
-#define APCI2032_STATUS_IRQ BIT(0)
-#define APCI2032_WDOG_REG 0x10
-
-struct apci2032_int_private {
- spinlock_t spinlock; /* protects the following members */
- bool active; /* an async command is running */
- unsigned char enabled_isns; /* mask of enabled interrupt channels */
-};
-
-static int apci2032_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- s->state = inl(dev->iobase + APCI2032_DO_REG);
-
- if (comedi_dio_update_state(s, data))
- outl(s->state, dev->iobase + APCI2032_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int apci2032_int_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inl(dev->iobase + APCI2032_INT_STATUS_REG) & 3;
- return insn->n;
-}
-
-static void apci2032_int_stop(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci2032_int_private *subpriv = s->private;
-
- subpriv->active = false;
- subpriv->enabled_isns = 0;
- outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG);
-}
-
-static int apci2032_int_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int apci2032_int_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- struct apci2032_int_private *subpriv = s->private;
- unsigned char enabled_isns;
- unsigned int n;
- unsigned long flags;
-
- enabled_isns = 0;
- for (n = 0; n < cmd->chanlist_len; n++)
- enabled_isns |= 1 << CR_CHAN(cmd->chanlist[n]);
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
-
- subpriv->enabled_isns = enabled_isns;
- subpriv->active = true;
- outl(enabled_isns, dev->iobase + APCI2032_INT_CTRL_REG);
-
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 0;
-}
-
-static int apci2032_int_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci2032_int_private *subpriv = s->private;
- unsigned long flags;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- if (subpriv->active)
- apci2032_int_stop(dev, s);
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 0;
-}
-
-static irqreturn_t apci2032_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
- struct apci2032_int_private *subpriv;
- unsigned int val;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- /* Check if VCC OR CC interrupt has occurred */
- val = inl(dev->iobase + APCI2032_STATUS_REG) & APCI2032_STATUS_IRQ;
- if (!val)
- return IRQ_NONE;
-
- subpriv = s->private;
- spin_lock(&subpriv->spinlock);
-
- val = inl(dev->iobase + APCI2032_INT_STATUS_REG) & 3;
- /* Disable triggered interrupt sources. */
- outl(~val & 3, dev->iobase + APCI2032_INT_CTRL_REG);
- /*
- * Note: We don't reenable the triggered interrupt sources because they
- * are level-sensitive, hardware error status interrupt sources and
- * they'd keep triggering interrupts repeatedly.
- */
-
- if (subpriv->active && (val & subpriv->enabled_isns) != 0) {
- unsigned short bits = 0;
- int i;
-
- /* Bits in scan data correspond to indices in channel list. */
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (val & (1 << chan))
- bits |= (1 << i);
- }
-
- comedi_buf_write_samples(s, &bits, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
- }
-
- spin_unlock(&subpriv->spinlock);
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int apci2032_reset(struct comedi_device *dev)
-{
- outl(0x0, dev->iobase + APCI2032_DO_REG);
- outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG);
-
- addi_watchdog_reset(dev->iobase + APCI2032_WDOG_REG);
-
- return 0;
-}
-
-static int apci2032_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 1);
- apci2032_reset(dev);
-
- if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, apci2032_interrupt,
- IRQF_SHARED, dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Initialize the digital output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci2032_do_insn_bits;
-
- /* Initialize the watchdog subdevice */
- s = &dev->subdevices[1];
- ret = addi_watchdog_init(s, dev->iobase + APCI2032_WDOG_REG);
- if (ret)
- return ret;
-
- /* Initialize the interrupt subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 2;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci2032_int_insn_bits;
- if (dev->irq) {
- struct apci2032_int_private *subpriv;
-
- dev->read_subdev = s;
- subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
- if (!subpriv)
- return -ENOMEM;
- spin_lock_init(&subpriv->spinlock);
- s->private = subpriv;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ | SDF_PACKED;
- s->len_chanlist = 2;
- s->do_cmdtest = apci2032_int_cmdtest;
- s->do_cmd = apci2032_int_cmd;
- s->cancel = apci2032_int_cancel;
- }
-
- return 0;
-}
-
-static void apci2032_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- apci2032_reset(dev);
- comedi_pci_detach(dev);
- if (dev->read_subdev)
- kfree(dev->read_subdev->private);
-}
-
-static struct comedi_driver apci2032_driver = {
- .driver_name = "addi_apci_2032",
- .module = THIS_MODULE,
- .auto_attach = apci2032_auto_attach,
- .detach = apci2032_detach,
-};
-
-static int apci2032_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci2032_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci2032_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci2032_pci_table);
-
-static struct pci_driver apci2032_pci_driver = {
- .name = "addi_apci_2032",
- .id_table = apci2032_pci_table,
- .probe = apci2032_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci2032_driver, apci2032_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("ADDI-DATA APCI-2032, 32 channel DO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c
deleted file mode 100644
index 4c5aee784bd9..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_2200.c
+++ /dev/null
@@ -1,143 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_2200.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- * Project manager: Eric Stolz
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-#include "addi_watchdog.h"
-
-/*
- * I/O Register Map
- */
-#define APCI2200_DI_REG 0x00
-#define APCI2200_DO_REG 0x04
-#define APCI2200_WDOG_REG 0x08
-
-static int apci2200_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inw(dev->iobase + APCI2200_DI_REG);
-
- return insn->n;
-}
-
-static int apci2200_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- s->state = inw(dev->iobase + APCI2200_DO_REG);
-
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + APCI2200_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int apci2200_reset(struct comedi_device *dev)
-{
- outw(0x0, dev->iobase + APCI2200_DO_REG);
-
- addi_watchdog_reset(dev->iobase + APCI2200_WDOG_REG);
-
- return 0;
-}
-
-static int apci2200_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->iobase = pci_resource_start(pcidev, 1);
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Initialize the digital input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci2200_di_insn_bits;
-
- /* Initialize the digital output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci2200_do_insn_bits;
-
- /* Initialize the watchdog subdevice */
- s = &dev->subdevices[2];
- ret = addi_watchdog_init(s, dev->iobase + APCI2200_WDOG_REG);
- if (ret)
- return ret;
-
- apci2200_reset(dev);
- return 0;
-}
-
-static void apci2200_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- apci2200_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver apci2200_driver = {
- .driver_name = "addi_apci_2200",
- .module = THIS_MODULE,
- .auto_attach = apci2200_auto_attach,
- .detach = apci2200_detach,
-};
-
-static int apci2200_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci2200_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci2200_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci2200_pci_table);
-
-static struct pci_driver apci2200_pci_driver = {
- .name = "addi_apci_2200",
- .id_table = apci2200_pci_table,
- .probe = apci2200_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci2200_driver, apci2200_pci_driver);
-
-MODULE_DESCRIPTION("ADDI-DATA APCI-2200 Relay board, optically isolated");
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
deleted file mode 100644
index 1ed3b33d1a30..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ /dev/null
@@ -1,1117 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_3120.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-#include "amcc_s5933.h"
-
-/*
- * PCI BAR 0 register map (devpriv->amcc)
- * see amcc_s5933.h for register and bit defines
- */
-#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 BIT(29)
-
-/*
- * PCI BAR 1 register map (dev->iobase)
- */
-#define APCI3120_AI_FIFO_REG 0x00
-#define APCI3120_CTRL_REG 0x00
-#define APCI3120_CTRL_EXT_TRIG BIT(15)
-#define APCI3120_CTRL_GATE(x) BIT(12 + (x))
-#define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8)
-#define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0)
-#define APCI3120_AI_SOFTTRIG_REG 0x02
-#define APCI3120_STATUS_REG 0x02
-#define APCI3120_STATUS_EOC_INT BIT(15)
-#define APCI3120_STATUS_AMCC_INT BIT(14)
-#define APCI3120_STATUS_EOS_INT BIT(13)
-#define APCI3120_STATUS_TIMER2_INT BIT(12)
-#define APCI3120_STATUS_INT_MASK (0xf << 12)
-#define APCI3120_STATUS_TO_DI_BITS(x) (((x) >> 8) & 0xf)
-#define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf)
-#define APCI3120_STATUS_FIFO_FULL BIT(2)
-#define APCI3120_STATUS_FIFO_EMPTY BIT(1)
-#define APCI3120_STATUS_DA_READY BIT(0)
-#define APCI3120_TIMER_REG 0x04
-#define APCI3120_CHANLIST_REG 0x06
-#define APCI3120_CHANLIST_INDEX(x) (((x) & 0xf) << 8)
-#define APCI3120_CHANLIST_UNIPOLAR BIT(7)
-#define APCI3120_CHANLIST_GAIN(x) (((x) & 0x3) << 4)
-#define APCI3120_CHANLIST_MUX(x) (((x) & 0xf) << 0)
-#define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2))
-#define APCI3120_AO_MUX(x) (((x) & 0x3) << 14)
-#define APCI3120_AO_DATA(x) ((x) << 0)
-#define APCI3120_TIMER_MODE_REG 0x0c
-#define APCI3120_TIMER_MODE(_t, _m) ((_m) << ((_t) * 2))
-#define APCI3120_TIMER_MODE0 0 /* I8254_MODE0 */
-#define APCI3120_TIMER_MODE2 1 /* I8254_MODE2 */
-#define APCI3120_TIMER_MODE4 2 /* I8254_MODE4 */
-#define APCI3120_TIMER_MODE5 3 /* I8254_MODE5 */
-#define APCI3120_TIMER_MODE_MASK(_t) (3 << ((_t) * 2))
-#define APCI3120_CTR0_REG 0x0d
-#define APCI3120_CTR0_DO_BITS(x) ((x) << 4)
-#define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0)
-#define APCI3120_MODE_REG 0x0e
-#define APCI3120_MODE_TIMER2_CLK(x) (((x) & 0x3) << 6)
-#define APCI3120_MODE_TIMER2_CLK_OSC APCI3120_MODE_TIMER2_CLK(0)
-#define APCI3120_MODE_TIMER2_CLK_OUT1 APCI3120_MODE_TIMER2_CLK(1)
-#define APCI3120_MODE_TIMER2_CLK_EOC APCI3120_MODE_TIMER2_CLK(2)
-#define APCI3120_MODE_TIMER2_CLK_EOS APCI3120_MODE_TIMER2_CLK(3)
-#define APCI3120_MODE_TIMER2_CLK_MASK APCI3120_MODE_TIMER2_CLK(3)
-#define APCI3120_MODE_TIMER2_AS(x) (((x) & 0x3) << 4)
-#define APCI3120_MODE_TIMER2_AS_TIMER APCI3120_MODE_TIMER2_AS(0)
-#define APCI3120_MODE_TIMER2_AS_COUNTER APCI3120_MODE_TIMER2_AS(1)
-#define APCI3120_MODE_TIMER2_AS_WDOG APCI3120_MODE_TIMER2_AS(2)
-#define APCI3120_MODE_TIMER2_AS_MASK APCI3120_MODE_TIMER2_AS(3)
-#define APCI3120_MODE_SCAN_ENA BIT(3)
-#define APCI3120_MODE_TIMER2_IRQ_ENA BIT(2)
-#define APCI3120_MODE_EOS_IRQ_ENA BIT(1)
-#define APCI3120_MODE_EOC_IRQ_ENA BIT(0)
-
-/*
- * PCI BAR 2 register map (devpriv->addon)
- */
-#define APCI3120_ADDON_ADDR_REG 0x00
-#define APCI3120_ADDON_DATA_REG 0x02
-#define APCI3120_ADDON_CTRL_REG 0x04
-#define APCI3120_ADDON_CTRL_AMWEN_ENA BIT(1)
-#define APCI3120_ADDON_CTRL_A2P_FIFO_ENA BIT(0)
-
-/*
- * Board revisions
- */
-#define APCI3120_REVA 0xa
-#define APCI3120_REVB 0xb
-#define APCI3120_REVA_OSC_BASE 70 /* 70ns = 14.29MHz */
-#define APCI3120_REVB_OSC_BASE 50 /* 50ns = 20MHz */
-
-static const struct comedi_lrange apci3120_ai_range = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1)
- }
-};
-
-enum apci3120_boardid {
- BOARD_APCI3120,
- BOARD_APCI3001,
-};
-
-struct apci3120_board {
- const char *name;
- unsigned int ai_is_16bit:1;
- unsigned int has_ao:1;
-};
-
-static const struct apci3120_board apci3120_boardtypes[] = {
- [BOARD_APCI3120] = {
- .name = "apci3120",
- .ai_is_16bit = 1,
- .has_ao = 1,
- },
- [BOARD_APCI3001] = {
- .name = "apci3001",
- },
-};
-
-struct apci3120_dmabuf {
- unsigned short *virt;
- dma_addr_t hw;
- unsigned int size;
- unsigned int use_size;
-};
-
-struct apci3120_private {
- unsigned long amcc;
- unsigned long addon;
- unsigned int osc_base;
- unsigned int use_dma:1;
- unsigned int use_double_buffer:1;
- unsigned int cur_dmabuf:1;
- struct apci3120_dmabuf dmabuf[2];
- unsigned char do_bits;
- unsigned char timer_mode;
- unsigned char mode;
- unsigned short ctrl;
-};
-
-static void apci3120_addon_write(struct comedi_device *dev,
- unsigned int val, unsigned int reg)
-{
- struct apci3120_private *devpriv = dev->private;
-
- /* 16-bit interface for AMCC add-on registers */
-
- outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG);
- outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
-
- outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG);
- outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
-}
-
-static void apci3120_init_dma(struct comedi_device *dev,
- struct apci3120_dmabuf *dmabuf)
-{
- struct apci3120_private *devpriv = dev->private;
-
- /* AMCC - enable transfer count and reset A2P FIFO */
- outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
- devpriv->amcc + AMCC_OP_REG_AGCSTS);
-
- /* Add-On - enable transfer count and reset A2P FIFO */
- apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
- AMCC_OP_REG_AGCSTS);
-
- /* AMCC - enable transfers and reset A2P flags */
- outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS,
- devpriv->amcc + AMCC_OP_REG_MCSR);
-
- /* Add-On - DMA start address */
- apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR);
-
- /* Add-On - Number of acquisitions */
- apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC);
-
- /* AMCC - enable write complete (DMA) and set FIFO advance */
- outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL,
- devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- /* Add-On - enable DMA */
- outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA,
- devpriv->addon + APCI3120_ADDON_CTRL_REG);
-}
-
-static void apci3120_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci3120_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
- struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
- unsigned int dmalen0 = dmabuf0->size;
- unsigned int dmalen1 = dmabuf1->size;
- unsigned int scan_bytes;
-
- scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg);
-
- if (cmd->stop_src == TRIG_COUNT) {
- /*
- * Must we fill full first buffer? And must we fill
- * full second buffer when first is once filled?
- */
- if (dmalen0 > (cmd->stop_arg * scan_bytes))
- dmalen0 = cmd->stop_arg * scan_bytes;
- else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0))
- dmalen1 = cmd->stop_arg * scan_bytes - dmalen0;
- }
-
- if (cmd->flags & CMDF_WAKE_EOS) {
- /* don't we want wake up every scan? */
- if (dmalen0 > scan_bytes) {
- dmalen0 = scan_bytes;
- if (cmd->scan_end_arg & 1)
- dmalen0 += 2;
- }
- if (dmalen1 > scan_bytes) {
- dmalen1 = scan_bytes;
- if (cmd->scan_end_arg & 1)
- dmalen1 -= 2;
- if (dmalen1 < 4)
- dmalen1 = 4;
- }
- } else {
- /* isn't output buff smaller that our DMA buff? */
- if (dmalen0 > s->async->prealloc_bufsz)
- dmalen0 = s->async->prealloc_bufsz;
- if (dmalen1 > s->async->prealloc_bufsz)
- dmalen1 = s->async->prealloc_bufsz;
- }
- dmabuf0->use_size = dmalen0;
- dmabuf1->use_size = dmalen1;
-
- apci3120_init_dma(dev, dmabuf0);
-}
-
-/*
- * There are three timers on the board. They all use the same base
- * clock with a fixed prescaler for each timer. The base clock used
- * depends on the board version and type.
- *
- * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns)
- * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns)
- * APCI-3001 boards OSC = 20MHz base clock (50ns)
- *
- * The prescalers for each timer are:
- * Timer 0 CLK = OSC/10
- * Timer 1 CLK = OSC/1000
- * Timer 2 CLK = OSC/1000
- */
-static unsigned int apci3120_ns_to_timer(struct comedi_device *dev,
- unsigned int timer,
- unsigned int ns,
- unsigned int flags)
-{
- struct apci3120_private *devpriv = dev->private;
- unsigned int prescale = (timer == 0) ? 10 : 1000;
- unsigned int timer_base = devpriv->osc_base * prescale;
- unsigned int divisor;
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_UP:
- divisor = DIV_ROUND_UP(ns, timer_base);
- break;
- case CMDF_ROUND_DOWN:
- divisor = ns / timer_base;
- break;
- case CMDF_ROUND_NEAREST:
- default:
- divisor = DIV_ROUND_CLOSEST(ns, timer_base);
- break;
- }
-
- if (timer == 2) {
- /* timer 2 is 24-bits */
- if (divisor > 0x00ffffff)
- divisor = 0x00ffffff;
- } else {
- /* timers 0 and 1 are 16-bits */
- if (divisor > 0xffff)
- divisor = 0xffff;
- }
- /* the timers require a minimum divisor of 2 */
- if (divisor < 2)
- divisor = 2;
-
- return divisor;
-}
-
-static void apci3120_clr_timer2_interrupt(struct comedi_device *dev)
-{
- /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
- inb(dev->iobase + APCI3120_CTR0_REG);
-}
-
-static void apci3120_timer_write(struct comedi_device *dev,
- unsigned int timer, unsigned int val)
-{
- struct apci3120_private *devpriv = dev->private;
-
- /* write 16-bit value to timer (lower 16-bits of timer 2) */
- outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
- APCI3120_CTR0_TIMER_SEL(timer),
- dev->iobase + APCI3120_CTR0_REG);
- outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG);
-
- if (timer == 2) {
- /* write upper 16-bits to timer 2 */
- outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
- APCI3120_CTR0_TIMER_SEL(timer + 1),
- dev->iobase + APCI3120_CTR0_REG);
- outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG);
- }
-}
-
-static unsigned int apci3120_timer_read(struct comedi_device *dev,
- unsigned int timer)
-{
- struct apci3120_private *devpriv = dev->private;
- unsigned int val;
-
- /* read 16-bit value from timer (lower 16-bits of timer 2) */
- outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
- APCI3120_CTR0_TIMER_SEL(timer),
- dev->iobase + APCI3120_CTR0_REG);
- val = inw(dev->iobase + APCI3120_TIMER_REG);
-
- if (timer == 2) {
- /* read upper 16-bits from timer 2 */
- outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
- APCI3120_CTR0_TIMER_SEL(timer + 1),
- dev->iobase + APCI3120_CTR0_REG);
- val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16);
- }
-
- return val;
-}
-
-static void apci3120_timer_set_mode(struct comedi_device *dev,
- unsigned int timer, unsigned int mode)
-{
- struct apci3120_private *devpriv = dev->private;
-
- devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer);
- devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode);
- outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG);
-}
-
-static void apci3120_timer_enable(struct comedi_device *dev,
- unsigned int timer, bool enable)
-{
- struct apci3120_private *devpriv = dev->private;
-
- if (enable)
- devpriv->ctrl |= APCI3120_CTRL_GATE(timer);
- else
- devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer);
- outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
-}
-
-static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable)
-{
- struct apci3120_private *devpriv = dev->private;
-
- if (enable)
- devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG;
- else
- devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG;
- outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
-}
-
-static void apci3120_set_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- int n_chan, unsigned int *chanlist)
-{
- struct apci3120_private *devpriv = dev->private;
- int i;
-
- /* set chanlist for scan */
- for (i = 0; i < n_chan; i++) {
- unsigned int chan = CR_CHAN(chanlist[i]);
- unsigned int range = CR_RANGE(chanlist[i]);
- unsigned int val;
-
- val = APCI3120_CHANLIST_MUX(chan) |
- APCI3120_CHANLIST_GAIN(range) |
- APCI3120_CHANLIST_INDEX(i);
-
- if (comedi_range_is_unipolar(s, range))
- val |= APCI3120_CHANLIST_UNIPOLAR;
-
- outw(val, dev->iobase + APCI3120_CHANLIST_REG);
- }
-
- /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
- inw(dev->iobase + APCI3120_TIMER_MODE_REG);
-
- /* set scan length (PR) and scan start (PA) */
- devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0);
- outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
-
- /* enable chanlist scanning if necessary */
- if (n_chan > 1)
- devpriv->mode |= APCI3120_MODE_SCAN_ENA;
-}
-
-static void apci3120_interrupt_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci3120_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- struct apci3120_dmabuf *dmabuf;
- unsigned int nbytes;
- unsigned int nsamples;
-
- dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
-
- nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC);
-
- if (nbytes < dmabuf->use_size)
- dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
- if (nbytes & 1) {
- dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
- async->events |= COMEDI_CB_ERROR;
- return;
- }
-
- nsamples = comedi_bytes_to_samples(s, nbytes);
- if (nsamples) {
- comedi_buf_write_samples(s, dmabuf->virt, nsamples);
-
- if (!(cmd->flags & CMDF_WAKE_EOS))
- async->events |= COMEDI_CB_EOS;
- }
-
- if ((async->events & COMEDI_CB_CANCEL_MASK) ||
- (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg))
- return;
-
- if (devpriv->use_double_buffer) {
- /* switch DMA buffers for next interrupt */
- devpriv->cur_dmabuf = !devpriv->cur_dmabuf;
- dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
- apci3120_init_dma(dev, dmabuf);
- } else {
- /* restart DMA if not using double buffering */
- apci3120_init_dma(dev, dmabuf);
- }
-}
-
-static irqreturn_t apci3120_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct apci3120_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int status;
- unsigned int int_amcc;
-
- status = inw(dev->iobase + APCI3120_STATUS_REG);
- int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- if (!(status & APCI3120_STATUS_INT_MASK) &&
- !(int_amcc & ANY_S593X_INT)) {
- dev_err(dev->class_dev, "IRQ from unknown source\n");
- return IRQ_NONE;
- }
-
- outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG)
- apci3120_exttrig_enable(dev, false);
-
- if (int_amcc & MASTER_ABORT_INT)
- dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
- if (int_amcc & TARGET_ABORT_INT)
- dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
-
- if ((status & APCI3120_STATUS_EOS_INT) &&
- (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
- unsigned short val;
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- val = inw(dev->iobase + APCI3120_AI_FIFO_REG);
- comedi_buf_write_samples(s, &val, 1);
- }
-
- devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
- outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
- }
-
- if (status & APCI3120_STATUS_TIMER2_INT) {
- /*
- * for safety...
- * timer2 interrupts are not enabled in the driver
- */
- apci3120_clr_timer2_interrupt(dev);
- }
-
- if (status & APCI3120_STATUS_AMCC_INT) {
- /* AMCC- Clear write complete interrupt (DMA) */
- outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- /* do some data transfer */
- apci3120_interrupt_dma(dev, s);
- }
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int apci3120_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci3120_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int divisor;
-
- /* set default mode bits */
- devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
- APCI3120_MODE_TIMER2_AS_TIMER;
-
- /* AMCC- Clear write complete interrupt (DMA) */
- outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- devpriv->cur_dmabuf = 0;
-
- /* load chanlist for command scan */
- apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);
-
- if (cmd->start_src == TRIG_EXT)
- apci3120_exttrig_enable(dev, true);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /*
- * Timer 1 is used in MODE2 (rate generator) to set the
- * start time for each scan.
- */
- divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
- cmd->flags);
- apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);
- apci3120_timer_write(dev, 1, divisor);
- }
-
- /*
- * Timer 0 is used in MODE2 (rate generator) to set the conversion
- * time for each acquisition.
- */
- divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
- apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);
- apci3120_timer_write(dev, 0, divisor);
-
- if (devpriv->use_dma)
- apci3120_setup_dma(dev, s);
- else
- devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
-
- /* set mode to enable acquisition */
- outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
-
- if (cmd->scan_begin_src == TRIG_TIMER)
- apci3120_timer_enable(dev, 1, true);
- apci3120_timer_enable(dev, 0, true);
-
- return 0;
-}
-
-static int apci3120_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int arg;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- 100000);
- }
-
- /* minimum conversion time per sample is 10us */
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* scan begin must be larger than the scan time */
- arg = cmd->convert_arg * cmd->scan_end_arg;
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int apci3120_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci3120_private *devpriv = dev->private;
-
- /* Add-On - disable DMA */
- outw(0, devpriv->addon + 4);
-
- /* Add-On - disable bus master */
- apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS);
-
- /* AMCC - disable bus master */
- outl(0, devpriv->amcc + AMCC_OP_REG_MCSR);
-
- /* disable all counters, ext trigger, and reset scan */
- devpriv->ctrl = 0;
- outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
-
- /* DISABLE_ALL_INTERRUPT */
- devpriv->mode = 0;
- outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
-
- inw(dev->iobase + APCI3120_STATUS_REG);
- devpriv->cur_dmabuf = 0;
-
- return 0;
-}
-
-static int apci3120_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + APCI3120_STATUS_REG);
- if ((status & APCI3120_STATUS_EOC_INT) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int apci3120_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci3120_private *devpriv = dev->private;
- unsigned int divisor;
- int ret;
- int i;
-
- /* set mode for A/D conversions by software trigger with timer 0 */
- devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
- APCI3120_MODE_TIMER2_AS_TIMER;
- outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
-
- /* load chanlist for single channel scan */
- apci3120_set_chanlist(dev, s, 1, &insn->chanspec);
-
- /*
- * Timer 0 is used in MODE4 (software triggered strobe) to set the
- * conversion time for each acquisition. Each conversion is triggered
- * when the divisor is written to the timer, The conversion is done
- * when the EOC bit in the status register is '0'.
- */
- apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4);
- apci3120_timer_enable(dev, 0, true);
-
- /* fixed conversion time of 10 us */
- divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST);
-
- for (i = 0; i < insn->n; i++) {
- /* trigger conversion */
- apci3120_timer_write(dev, 0, divisor);
-
- ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0);
- if (ret)
- return ret;
-
- data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG);
- }
-
- return insn->n;
-}
-
-static int apci3120_ao_ready(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + APCI3120_STATUS_REG);
- if (status & APCI3120_STATUS_DA_READY)
- return 0;
- return -EBUSY;
-}
-
-static int apci3120_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
- int ret;
-
- ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
- if (ret)
- return ret;
-
- outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
- dev->iobase + APCI3120_AO_REG(chan));
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int apci3120_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int status;
-
- status = inw(dev->iobase + APCI3120_STATUS_REG);
- data[1] = APCI3120_STATUS_TO_DI_BITS(status);
-
- return insn->n;
-}
-
-static int apci3120_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci3120_private *devpriv = dev->private;
-
- if (comedi_dio_update_state(s, data)) {
- devpriv->do_bits = s->state;
- outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits),
- dev->iobase + APCI3120_CTR0_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int apci3120_timer_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci3120_private *devpriv = dev->private;
- unsigned int divisor;
- unsigned int status;
- unsigned int mode;
- unsigned int timer_mode;
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- apci3120_clr_timer2_interrupt(dev);
- divisor = apci3120_ns_to_timer(dev, 2, data[1],
- CMDF_ROUND_DOWN);
- apci3120_timer_write(dev, 2, divisor);
- apci3120_timer_enable(dev, 2, true);
- break;
-
- case INSN_CONFIG_DISARM:
- apci3120_timer_enable(dev, 2, false);
- apci3120_clr_timer2_interrupt(dev);
- break;
-
- case INSN_CONFIG_GET_COUNTER_STATUS:
- data[1] = 0;
- data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
- COMEDI_COUNTER_TERMINAL_COUNT;
-
- if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) {
- data[1] |= COMEDI_COUNTER_ARMED;
- data[1] |= COMEDI_COUNTER_COUNTING;
- }
- status = inw(dev->iobase + APCI3120_STATUS_REG);
- if (status & APCI3120_STATUS_TIMER2_INT) {
- data[1] &= ~COMEDI_COUNTER_COUNTING;
- data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
- }
- break;
-
- case INSN_CONFIG_SET_COUNTER_MODE:
- switch (data[1]) {
- case I8254_MODE0:
- mode = APCI3120_MODE_TIMER2_AS_COUNTER;
- timer_mode = APCI3120_TIMER_MODE0;
- break;
- case I8254_MODE2:
- mode = APCI3120_MODE_TIMER2_AS_TIMER;
- timer_mode = APCI3120_TIMER_MODE2;
- break;
- case I8254_MODE4:
- mode = APCI3120_MODE_TIMER2_AS_TIMER;
- timer_mode = APCI3120_TIMER_MODE4;
- break;
- case I8254_MODE5:
- mode = APCI3120_MODE_TIMER2_AS_WDOG;
- timer_mode = APCI3120_TIMER_MODE5;
- break;
- default:
- return -EINVAL;
- }
- apci3120_timer_enable(dev, 2, false);
- apci3120_clr_timer2_interrupt(dev);
- apci3120_timer_set_mode(dev, 2, timer_mode);
- devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK;
- devpriv->mode |= mode;
- outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
- break;
-
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int apci3120_timer_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int i;
-
- for (i = 0; i < insn->n; i++)
- data[i] = apci3120_timer_read(dev, 2);
-
- return insn->n;
-}
-
-static void apci3120_dma_alloc(struct comedi_device *dev)
-{
- struct apci3120_private *devpriv = dev->private;
- struct apci3120_dmabuf *dmabuf;
- int order;
- int i;
-
- for (i = 0; i < 2; i++) {
- dmabuf = &devpriv->dmabuf[i];
- for (order = 2; order >= 0; order--) {
- dmabuf->virt = dma_alloc_coherent(dev->hw_dev,
- PAGE_SIZE << order,
- &dmabuf->hw,
- GFP_KERNEL);
- if (dmabuf->virt)
- break;
- }
- if (!dmabuf->virt)
- break;
- dmabuf->size = PAGE_SIZE << order;
-
- if (i == 0)
- devpriv->use_dma = 1;
- if (i == 1)
- devpriv->use_double_buffer = 1;
- }
-}
-
-static void apci3120_dma_free(struct comedi_device *dev)
-{
- struct apci3120_private *devpriv = dev->private;
- struct apci3120_dmabuf *dmabuf;
- int i;
-
- if (!devpriv)
- return;
-
- for (i = 0; i < 2; i++) {
- dmabuf = &devpriv->dmabuf[i];
- if (dmabuf->virt) {
- dma_free_coherent(dev->hw_dev, dmabuf->size,
- dmabuf->virt, dmabuf->hw);
- }
- }
-}
-
-static void apci3120_reset(struct comedi_device *dev)
-{
- /* disable all interrupt sources */
- outb(0, dev->iobase + APCI3120_MODE_REG);
-
- /* disable all counters, ext trigger, and reset scan */
- outw(0, dev->iobase + APCI3120_CTRL_REG);
-
- /* clear interrupt status */
- inw(dev->iobase + APCI3120_STATUS_REG);
-}
-
-static int apci3120_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct apci3120_board *board = NULL;
- struct apci3120_private *devpriv;
- struct comedi_subdevice *s;
- unsigned int status;
- int ret;
-
- if (context < ARRAY_SIZE(apci3120_boardtypes))
- board = &apci3120_boardtypes[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- pci_set_master(pcidev);
-
- dev->iobase = pci_resource_start(pcidev, 1);
- devpriv->amcc = pci_resource_start(pcidev, 0);
- devpriv->addon = pci_resource_start(pcidev, 2);
-
- apci3120_reset(dev);
-
- if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0) {
- dev->irq = pcidev->irq;
-
- apci3120_dma_alloc(dev);
- }
- }
-
- status = inw(dev->iobase + APCI3120_STATUS_REG);
- if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB ||
- context == BOARD_APCI3001)
- devpriv->osc_base = APCI3120_REVB_OSC_BASE;
- else
- devpriv->osc_base = APCI3120_REVA_OSC_BASE;
-
- ret = comedi_alloc_subdevices(dev, 5);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = board->ai_is_16bit ? 0xffff : 0x0fff;
- s->range_table = &apci3120_ai_range;
- s->insn_read = apci3120_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = apci3120_ai_cmdtest;
- s->do_cmd = apci3120_ai_cmd;
- s->cancel = apci3120_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = 8;
- s->maxdata = 0x3fff;
- s->range_table = &range_bipolar10;
- s->insn_write = apci3120_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci3120_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci3120_do_insn_bits;
-
- /* Timer subdevice */
- s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 1;
- s->maxdata = 0x00ffffff;
- s->insn_config = apci3120_timer_insn_config;
- s->insn_read = apci3120_timer_insn_read;
-
- return 0;
-}
-
-static void apci3120_detach(struct comedi_device *dev)
-{
- comedi_pci_detach(dev);
- apci3120_dma_free(dev);
-}
-
-static struct comedi_driver apci3120_driver = {
- .driver_name = "addi_apci_3120",
- .module = THIS_MODULE,
- .auto_attach = apci3120_auto_attach,
- .detach = apci3120_detach,
-};
-
-static int apci3120_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci3120_pci_table[] = {
- { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
- { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
-
-static struct pci_driver apci3120_pci_driver = {
- .name = "addi_apci_3120",
- .id_table = apci3120_pci_table,
- .probe = apci3120_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
deleted file mode 100644
index f0c9642f3f1a..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ /dev/null
@@ -1,417 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_3501.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- * Project manager: Eric Stolz
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-/*
- * Driver: addi_apci_3501
- * Description: ADDI-DATA APCI-3501 Analog output board
- * Devices: [ADDI-DATA] APCI-3501 (addi_apci_3501)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Mon, 20 Jun 2016 10:57:01 -0700
- * Status: untested
- *
- * Configuration Options: not applicable, uses comedi PCI auto config
- *
- * This board has the following features:
- * - 4 or 8 analog output channels
- * - 2 optically isolated digital inputs
- * - 2 optically isolated digital outputs
- * - 1 12-bit watchdog/timer
- *
- * There are 2 versions of the APCI-3501:
- * - APCI-3501-4 4 analog output channels
- * - APCI-3501-8 8 analog output channels
- *
- * These boards use the same PCI Vendor/Device IDs. The number of output
- * channels used by this driver is determined by reading the EEPROM on
- * the board.
- *
- * The watchdog/timer subdevice is not currently supported.
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-#include "amcc_s5933.h"
-
-/*
- * PCI bar 1 register I/O map
- */
-#define APCI3501_AO_CTRL_STATUS_REG 0x00
-#define APCI3501_AO_CTRL_BIPOLAR BIT(0)
-#define APCI3501_AO_STATUS_READY BIT(8)
-#define APCI3501_AO_DATA_REG 0x04
-#define APCI3501_AO_DATA_CHAN(x) ((x) << 0)
-#define APCI3501_AO_DATA_VAL(x) ((x) << 8)
-#define APCI3501_AO_DATA_BIPOLAR BIT(31)
-#define APCI3501_AO_TRIG_SCS_REG 0x08
-#define APCI3501_TIMER_BASE 0x20
-#define APCI3501_DO_REG 0x40
-#define APCI3501_DI_REG 0x50
-
-/*
- * AMCC S5933 NVRAM
- */
-#define NVRAM_USER_DATA_START 0x100
-
-#define NVCMD_BEGIN_READ (0x7 << 5)
-#define NVCMD_LOAD_LOW (0x4 << 5)
-#define NVCMD_LOAD_HIGH (0x5 << 5)
-
-/*
- * Function types stored in the eeprom
- */
-#define EEPROM_DIGITALINPUT 0
-#define EEPROM_DIGITALOUTPUT 1
-#define EEPROM_ANALOGINPUT 2
-#define EEPROM_ANALOGOUTPUT 3
-#define EEPROM_TIMER 4
-#define EEPROM_WATCHDOG 5
-#define EEPROM_TIMER_WATCHDOG_COUNTER 10
-
-struct apci3501_private {
- unsigned long amcc;
- unsigned char timer_mode;
-};
-
-static const struct comedi_lrange apci3501_ao_range = {
- 2, {
- BIP_RANGE(10),
- UNI_RANGE(10)
- }
-};
-
-static int apci3501_wait_for_dac(struct comedi_device *dev)
-{
- unsigned int status;
-
- do {
- status = inl(dev->iobase + APCI3501_AO_CTRL_STATUS_REG);
- } while (!(status & APCI3501_AO_STATUS_READY));
-
- return 0;
-}
-
-static int apci3501_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int cfg = APCI3501_AO_DATA_CHAN(chan);
- int ret;
- int i;
-
- /*
- * All analog output channels have the same output range.
- * 14-bit bipolar: 0-10V
- * 13-bit unipolar: +/-10V
- * Changing the range of one channel changes all of them!
- */
- if (range) {
- outl(0, dev->iobase + APCI3501_AO_CTRL_STATUS_REG);
- } else {
- cfg |= APCI3501_AO_DATA_BIPOLAR;
- outl(APCI3501_AO_CTRL_BIPOLAR,
- dev->iobase + APCI3501_AO_CTRL_STATUS_REG);
- }
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- if (range == 1) {
- if (data[i] > 0x1fff) {
- dev_err(dev->class_dev,
- "Unipolar resolution is only 13-bits\n");
- return -EINVAL;
- }
- }
-
- ret = apci3501_wait_for_dac(dev);
- if (ret)
- return ret;
-
- outl(cfg | APCI3501_AO_DATA_VAL(val),
- dev->iobase + APCI3501_AO_DATA_REG);
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int apci3501_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inl(dev->iobase + APCI3501_DI_REG) & 0x3;
-
- return insn->n;
-}
-
-static int apci3501_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- s->state = inl(dev->iobase + APCI3501_DO_REG);
-
- if (comedi_dio_update_state(s, data))
- outl(s->state, dev->iobase + APCI3501_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void apci3501_eeprom_wait(unsigned long iobase)
-{
- unsigned char val;
-
- do {
- val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD);
- } while (val & 0x80);
-}
-
-static unsigned short apci3501_eeprom_readw(unsigned long iobase,
- unsigned short addr)
-{
- unsigned short val = 0;
- unsigned char tmp;
- unsigned char i;
-
- /* Add the offset to the start of the user data */
- addr += NVRAM_USER_DATA_START;
-
- for (i = 0; i < 2; i++) {
- /* Load the low 8 bit address */
- outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD);
- apci3501_eeprom_wait(iobase);
- outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
- apci3501_eeprom_wait(iobase);
-
- /* Load the high 8 bit address */
- outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD);
- apci3501_eeprom_wait(iobase);
- outb(((addr + i) >> 8) & 0xff,
- iobase + AMCC_OP_REG_MCSR_NVDATA);
- apci3501_eeprom_wait(iobase);
-
- /* Read the eeprom data byte */
- outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
- apci3501_eeprom_wait(iobase);
- tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
- apci3501_eeprom_wait(iobase);
-
- if (i == 0)
- val |= tmp;
- else
- val |= (tmp << 8);
- }
-
- return val;
-}
-
-static int apci3501_eeprom_get_ao_n_chan(struct comedi_device *dev)
-{
- struct apci3501_private *devpriv = dev->private;
- unsigned char nfuncs;
- int i;
-
- nfuncs = apci3501_eeprom_readw(devpriv->amcc, 10) & 0xff;
-
- /* Read functionality details */
- for (i = 0; i < nfuncs; i++) {
- unsigned short offset = i * 4;
- unsigned short addr;
- unsigned char func;
- unsigned short val;
-
- func = apci3501_eeprom_readw(devpriv->amcc, 12 + offset) & 0x3f;
- addr = apci3501_eeprom_readw(devpriv->amcc, 14 + offset);
-
- if (func == EEPROM_ANALOGOUTPUT) {
- val = apci3501_eeprom_readw(devpriv->amcc, addr + 10);
- return (val >> 4) & 0x3ff;
- }
- }
- return 0;
-}
-
-static int apci3501_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct apci3501_private *devpriv = dev->private;
- unsigned short addr = CR_CHAN(insn->chanspec);
- unsigned int val;
- unsigned int i;
-
- if (insn->n) {
- /* No point reading the same EEPROM location more than once. */
- val = apci3501_eeprom_readw(devpriv->amcc, 2 * addr);
- for (i = 0; i < insn->n; i++)
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int apci3501_reset(struct comedi_device *dev)
-{
- unsigned int val;
- int chan;
- int ret;
-
- /* Reset all digital outputs to "0" */
- outl(0x0, dev->iobase + APCI3501_DO_REG);
-
- /* Default all analog outputs to 0V (bipolar) */
- outl(APCI3501_AO_CTRL_BIPOLAR,
- dev->iobase + APCI3501_AO_CTRL_STATUS_REG);
- val = APCI3501_AO_DATA_BIPOLAR | APCI3501_AO_DATA_VAL(0);
-
- /* Set all analog output channels */
- for (chan = 0; chan < 8; chan++) {
- ret = apci3501_wait_for_dac(dev);
- if (ret) {
- dev_warn(dev->class_dev,
- "%s: DAC not-ready for channel %i\n",
- __func__, chan);
- } else {
- outl(val | APCI3501_AO_DATA_CHAN(chan),
- dev->iobase + APCI3501_AO_DATA_REG);
- }
- }
-
- return 0;
-}
-
-static int apci3501_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct apci3501_private *devpriv;
- struct comedi_subdevice *s;
- int ao_n_chan;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv->amcc = pci_resource_start(pcidev, 0);
- dev->iobase = pci_resource_start(pcidev, 1);
-
- ao_n_chan = apci3501_eeprom_get_ao_n_chan(dev);
-
- ret = comedi_alloc_subdevices(dev, 5);
- if (ret)
- return ret;
-
- /* Initialize the analog output subdevice */
- s = &dev->subdevices[0];
- if (ao_n_chan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = ao_n_chan;
- s->maxdata = 0x3fff;
- s->range_table = &apci3501_ao_range;
- s->insn_write = apci3501_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Initialize the digital input subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 2;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci3501_di_insn_bits;
-
- /* Initialize the digital output subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci3501_do_insn_bits;
-
- /* Timer/Watchdog subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_UNUSED;
-
- /* Initialize the eeprom subdevice */
- s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->n_chan = 256;
- s->maxdata = 0xffff;
- s->insn_read = apci3501_eeprom_insn_read;
-
- apci3501_reset(dev);
- return 0;
-}
-
-static void apci3501_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- apci3501_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver apci3501_driver = {
- .driver_name = "addi_apci_3501",
- .module = THIS_MODULE,
- .auto_attach = apci3501_auto_attach,
- .detach = apci3501_detach,
-};
-
-static int apci3501_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci3501_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci3501_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci3501_pci_table);
-
-static struct pci_driver apci3501_pci_driver = {
- .name = "addi_apci_3501",
- .id_table = apci3501_pci_table,
- .probe = apci3501_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci3501_driver, apci3501_pci_driver);
-
-MODULE_DESCRIPTION("ADDI-DATA APCI-3501 Analog output board");
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
deleted file mode 100644
index a90d59377e18..000000000000
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ /dev/null
@@ -1,961 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * addi_apci_3xxx.c
- * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
- * Project manager: S. Weber
- *
- * ADDI-DATA GmbH
- * Dieselstrasse 3
- * D-77833 Ottersweier
- * Tel: +19(0)7223/9493-0
- * Fax: +49(0)7223/9493-92
- * http://www.addi-data.com
- * info@addi-data.com
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#define CONV_UNIT_NS BIT(0)
-#define CONV_UNIT_US BIT(1)
-#define CONV_UNIT_MS BIT(2)
-
-static const struct comedi_lrange apci3xxx_ai_range = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1)
- }
-};
-
-static const struct comedi_lrange apci3xxx_ao_range = {
- 2, {
- BIP_RANGE(10),
- UNI_RANGE(10)
- }
-};
-
-enum apci3xxx_boardid {
- BOARD_APCI3000_16,
- BOARD_APCI3000_8,
- BOARD_APCI3000_4,
- BOARD_APCI3006_16,
- BOARD_APCI3006_8,
- BOARD_APCI3006_4,
- BOARD_APCI3010_16,
- BOARD_APCI3010_8,
- BOARD_APCI3010_4,
- BOARD_APCI3016_16,
- BOARD_APCI3016_8,
- BOARD_APCI3016_4,
- BOARD_APCI3100_16_4,
- BOARD_APCI3100_8_4,
- BOARD_APCI3106_16_4,
- BOARD_APCI3106_8_4,
- BOARD_APCI3110_16_4,
- BOARD_APCI3110_8_4,
- BOARD_APCI3116_16_4,
- BOARD_APCI3116_8_4,
- BOARD_APCI3003,
- BOARD_APCI3002_16,
- BOARD_APCI3002_8,
- BOARD_APCI3002_4,
- BOARD_APCI3500,
-};
-
-struct apci3xxx_boardinfo {
- const char *name;
- int ai_subdev_flags;
- int ai_n_chan;
- unsigned int ai_maxdata;
- unsigned char ai_conv_units;
- unsigned int ai_min_acq_ns;
- unsigned int has_ao:1;
- unsigned int has_dig_in:1;
- unsigned int has_dig_out:1;
- unsigned int has_ttl_io:1;
-};
-
-static const struct apci3xxx_boardinfo apci3xxx_boardtypes[] = {
- [BOARD_APCI3000_16] = {
- .name = "apci3000-16",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3000_8] = {
- .name = "apci3000-8",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3000_4] = {
- .name = "apci3000-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 4,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3006_16] = {
- .name = "apci3006-16",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3006_8] = {
- .name = "apci3006-8",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3006_4] = {
- .name = "apci3006-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 4,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3010_16] = {
- .name = "apci3010-16",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3010_8] = {
- .name = "apci3010-8",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3010_4] = {
- .name = "apci3010-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 4,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3016_16] = {
- .name = "apci3016-16",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3016_8] = {
- .name = "apci3016-8",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3016_4] = {
- .name = "apci3016-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 4,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3100_16_4] = {
- .name = "apci3100-16-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ao = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3100_8_4] = {
- .name = "apci3100-8-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ao = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3106_16_4] = {
- .name = "apci3106-16-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ao = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3106_8_4] = {
- .name = "apci3106-8-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 10000,
- .has_ao = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3110_16_4] = {
- .name = "apci3110-16-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_ao = 1,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3110_8_4] = {
- .name = "apci3110-8-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0x0fff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_ao = 1,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3116_16_4] = {
- .name = "apci3116-16-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_ao = 1,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3116_8_4] = {
- .name = "apci3116-8-4",
- .ai_subdev_flags = SDF_COMMON | SDF_GROUND | SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_ao = 1,
- .has_dig_in = 1,
- .has_dig_out = 1,
- .has_ttl_io = 1,
- },
- [BOARD_APCI3003] = {
- .name = "apci3003",
- .ai_subdev_flags = SDF_DIFF,
- .ai_n_chan = 4,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US |
- CONV_UNIT_NS,
- .ai_min_acq_ns = 2500,
- .has_dig_in = 1,
- .has_dig_out = 1,
- },
- [BOARD_APCI3002_16] = {
- .name = "apci3002-16",
- .ai_subdev_flags = SDF_DIFF,
- .ai_n_chan = 16,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- },
- [BOARD_APCI3002_8] = {
- .name = "apci3002-8",
- .ai_subdev_flags = SDF_DIFF,
- .ai_n_chan = 8,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- },
- [BOARD_APCI3002_4] = {
- .name = "apci3002-4",
- .ai_subdev_flags = SDF_DIFF,
- .ai_n_chan = 4,
- .ai_maxdata = 0xffff,
- .ai_conv_units = CONV_UNIT_MS | CONV_UNIT_US,
- .ai_min_acq_ns = 5000,
- .has_dig_in = 1,
- .has_dig_out = 1,
- },
- [BOARD_APCI3500] = {
- .name = "apci3500",
- .has_ao = 1,
- .has_ttl_io = 1,
- },
-};
-
-struct apci3xxx_private {
- unsigned int ai_timer;
- unsigned char ai_time_base;
-};
-
-static irqreturn_t apci3xxx_irq_handler(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int status;
- unsigned int val;
-
- /* Test if interrupt occur */
- status = readl(dev->mmio + 16);
- if ((status & 0x2) == 0x2) {
- /* Reset the interrupt */
- writel(status, dev->mmio + 16);
-
- val = readl(dev->mmio + 28);
- comedi_buf_write_samples(s, &val, 1);
-
- s->async->events |= COMEDI_CB_EOA;
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
- }
- return IRQ_NONE;
-}
-
-static int apci3xxx_ai_started(struct comedi_device *dev)
-{
- if ((readl(dev->mmio + 8) & 0x80000) == 0x80000)
- return 1;
-
- return 0;
-}
-
-static int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
-{
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
- unsigned int delay_mode;
- unsigned int val;
-
- if (apci3xxx_ai_started(dev))
- return -EBUSY;
-
- /* Clear the FIFO */
- writel(0x10000, dev->mmio + 12);
-
- /* Get and save the delay mode */
- delay_mode = readl(dev->mmio + 4);
- delay_mode &= 0xfffffef0;
-
- /* Channel configuration selection */
- writel(delay_mode, dev->mmio + 4);
-
- /* Make the configuration */
- val = (range & 3) | ((range >> 2) << 6) |
- ((aref == AREF_DIFF) << 7);
- writel(val, dev->mmio + 0);
-
- /* Channel selection */
- writel(delay_mode | 0x100, dev->mmio + 4);
- writel(chan, dev->mmio + 0);
-
- /* Restore delay mode */
- writel(delay_mode, dev->mmio + 4);
-
- /* Set the number of sequence to 1 */
- writel(1, dev->mmio + 48);
-
- return 0;
-}
-
-static int apci3xxx_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = readl(dev->mmio + 20);
- if (status & 0x1)
- return 0;
- return -EBUSY;
-}
-
-static int apci3xxx_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- int i;
-
- ret = apci3xxx_ai_setup(dev, insn->chanspec);
- if (ret)
- return ret;
-
- for (i = 0; i < insn->n; i++) {
- /* Start the conversion */
- writel(0x80000, dev->mmio + 8);
-
- /* Wait the EOS */
- ret = comedi_timeout(dev, s, insn, apci3xxx_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* Read the analog value */
- data[i] = readl(dev->mmio + 28);
- }
-
- return insn->n;
-}
-
-static int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
- unsigned int *ns, unsigned int flags)
-{
- const struct apci3xxx_boardinfo *board = dev->board_ptr;
- struct apci3xxx_private *devpriv = dev->private;
- unsigned int base;
- unsigned int timer;
- int time_base;
-
- /* time_base: 0 = ns, 1 = us, 2 = ms */
- for (time_base = 0; time_base < 3; time_base++) {
- /* skip unsupported time bases */
- if (!(board->ai_conv_units & (1 << time_base)))
- continue;
-
- switch (time_base) {
- case 0:
- base = 1;
- break;
- case 1:
- base = 1000;
- break;
- case 2:
- base = 1000000;
- break;
- }
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- timer = DIV_ROUND_CLOSEST(*ns, base);
- break;
- case CMDF_ROUND_DOWN:
- timer = *ns / base;
- break;
- case CMDF_ROUND_UP:
- timer = DIV_ROUND_UP(*ns, base);
- break;
- }
-
- if (timer < 0x10000) {
- devpriv->ai_time_base = time_base;
- devpriv->ai_timer = timer;
- *ns = timer * time_base;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int apci3xxx_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct apci3xxx_boardinfo *board = dev->board_ptr;
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_min_acq_ns);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- arg = cmd->convert_arg;
- err |= apci3xxx_ai_ns_to_timer(dev, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int apci3xxx_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct apci3xxx_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- ret = apci3xxx_ai_setup(dev, cmd->chanlist[0]);
- if (ret)
- return ret;
-
- /* Set the convert timing unit */
- writel(devpriv->ai_time_base, dev->mmio + 36);
-
- /* Set the convert timing */
- writel(devpriv->ai_timer, dev->mmio + 32);
-
- /* Start the conversion */
- writel(0x180000, dev->mmio + 8);
-
- return 0;
-}
-
-static int apci3xxx_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- return 0;
-}
-
-static int apci3xxx_ao_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = readl(dev->mmio + 96);
- if (status & 0x100)
- return 0;
- return -EBUSY;
-}
-
-static int apci3xxx_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int ret;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- /* Set the range selection */
- writel(range, dev->mmio + 96);
-
- /* Write the analog value to the selected channel */
- writel((val << 8) | chan, dev->mmio + 100);
-
- /* Wait the end of transfer */
- ret = comedi_timeout(dev, s, insn, apci3xxx_ao_eoc, 0);
- if (ret)
- return ret;
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int apci3xxx_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inl(dev->iobase + 32) & 0xf;
-
- return insn->n;
-}
-
-static int apci3xxx_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- s->state = inl(dev->iobase + 48) & 0xf;
-
- if (comedi_dio_update_state(s, data))
- outl(s->state, dev->iobase + 48);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int apci3xxx_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask = 0;
- int ret;
-
- /*
- * Port 0 (channels 0-7) are always inputs
- * Port 1 (channels 8-15) are always outputs
- * Port 2 (channels 16-23) are programmable i/o
- */
- if (data[0] != INSN_CONFIG_DIO_QUERY) {
- /* ignore all other instructions for ports 0 and 1 */
- if (chan < 16)
- return -EINVAL;
-
- /* changing any channel in port 2 changes the entire port */
- mask = 0xff0000;
- }
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- /* update port 2 configuration */
- outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
-
- return insn->n;
-}
-
-static int apci3xxx_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0xff)
- outl(s->state & 0xff, dev->iobase + 80);
- if (mask & 0xff0000)
- outl((s->state >> 16) & 0xff, dev->iobase + 112);
- }
-
- val = inl(dev->iobase + 80);
- val |= (inl(dev->iobase + 64) << 8);
- if (s->io_bits & 0xff0000)
- val |= (inl(dev->iobase + 112) << 16);
- else
- val |= (inl(dev->iobase + 96) << 16);
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int apci3xxx_reset(struct comedi_device *dev)
-{
- unsigned int val;
- int i;
-
- /* Disable the interrupt */
- disable_irq(dev->irq);
-
- /* Clear the start command */
- writel(0, dev->mmio + 8);
-
- /* Reset the interrupt flags */
- val = readl(dev->mmio + 16);
- writel(val, dev->mmio + 16);
-
- /* clear the EOS */
- readl(dev->mmio + 20);
-
- /* Clear the FIFO */
- for (i = 0; i < 16; i++)
- val = readl(dev->mmio + 28);
-
- /* Enable the interrupt */
- enable_irq(dev->irq);
-
- return 0;
-}
-
-static int apci3xxx_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct apci3xxx_boardinfo *board = NULL;
- struct apci3xxx_private *devpriv;
- struct comedi_subdevice *s;
- int n_subdevices;
- int subdev;
- int ret;
-
- if (context < ARRAY_SIZE(apci3xxx_boardtypes))
- board = &apci3xxx_boardtypes[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->iobase = pci_resource_start(pcidev, 2);
- dev->mmio = pci_ioremap_bar(pcidev, 3);
- if (!dev->mmio)
- return -ENOMEM;
-
- if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, apci3xxx_irq_handler,
- IRQF_SHARED, dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- n_subdevices = (board->ai_n_chan ? 0 : 1) + board->has_ao +
- board->has_dig_in + board->has_dig_out +
- board->has_ttl_io;
- ret = comedi_alloc_subdevices(dev, n_subdevices);
- if (ret)
- return ret;
-
- subdev = 0;
-
- /* Analog Input subdevice */
- if (board->ai_n_chan) {
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | board->ai_subdev_flags;
- s->n_chan = board->ai_n_chan;
- s->maxdata = board->ai_maxdata;
- s->range_table = &apci3xxx_ai_range;
- s->insn_read = apci3xxx_ai_insn_read;
- if (dev->irq) {
- /*
- * FIXME: The hardware supports multiple scan modes
- * but the original addi-data driver only supported
- * reading a single channel with interrupts. Need a
- * proper datasheet to fix this.
- *
- * The following scan modes are supported by the
- * hardware:
- * 1) Single software scan
- * 2) Single hardware triggered scan
- * 3) Continuous software scan
- * 4) Continuous software scan with timer delay
- * 5) Continuous hardware triggered scan
- * 6) Continuous hardware triggered scan with timer
- * delay
- *
- * For now, limit the chanlist to a single channel.
- */
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 1;
- s->do_cmdtest = apci3xxx_ai_cmdtest;
- s->do_cmd = apci3xxx_ai_cmd;
- s->cancel = apci3xxx_ai_cancel;
- }
-
- subdev++;
- }
-
- /* Analog Output subdevice */
- if (board->has_ao) {
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = 4;
- s->maxdata = 0x0fff;
- s->range_table = &apci3xxx_ao_range;
- s->insn_write = apci3xxx_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- subdev++;
- }
-
- /* Digital Input subdevice */
- if (board->has_dig_in) {
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci3xxx_di_insn_bits;
-
- subdev++;
- }
-
- /* Digital Output subdevice */
- if (board->has_dig_out) {
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = apci3xxx_do_insn_bits;
-
- subdev++;
- }
-
- /* TTL Digital I/O subdevice */
- if (board->has_ttl_io) {
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->io_bits = 0xff; /* channels 0-7 are always outputs */
- s->range_table = &range_digital;
- s->insn_config = apci3xxx_dio_insn_config;
- s->insn_bits = apci3xxx_dio_insn_bits;
-
- subdev++;
- }
-
- apci3xxx_reset(dev);
- return 0;
-}
-
-static void apci3xxx_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- apci3xxx_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver apci3xxx_driver = {
- .driver_name = "addi_apci_3xxx",
- .module = THIS_MODULE,
- .auto_attach = apci3xxx_auto_attach,
- .detach = apci3xxx_detach,
-};
-
-static int apci3xxx_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data);
-}
-
-static const struct pci_device_id apci3xxx_pci_table[] = {
- { PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 },
- { PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 },
- { PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3013), BOARD_APCI3006_16 },
- { PCI_VDEVICE(ADDIDATA, 0x3014), BOARD_APCI3006_8 },
- { PCI_VDEVICE(ADDIDATA, 0x3015), BOARD_APCI3006_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3016), BOARD_APCI3010_16 },
- { PCI_VDEVICE(ADDIDATA, 0x3017), BOARD_APCI3010_8 },
- { PCI_VDEVICE(ADDIDATA, 0x3018), BOARD_APCI3010_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3019), BOARD_APCI3016_16 },
- { PCI_VDEVICE(ADDIDATA, 0x301a), BOARD_APCI3016_8 },
- { PCI_VDEVICE(ADDIDATA, 0x301b), BOARD_APCI3016_4 },
- { PCI_VDEVICE(ADDIDATA, 0x301c), BOARD_APCI3100_16_4 },
- { PCI_VDEVICE(ADDIDATA, 0x301d), BOARD_APCI3100_8_4 },
- { PCI_VDEVICE(ADDIDATA, 0x301e), BOARD_APCI3106_16_4 },
- { PCI_VDEVICE(ADDIDATA, 0x301f), BOARD_APCI3106_8_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3020), BOARD_APCI3110_16_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3021), BOARD_APCI3110_8_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3022), BOARD_APCI3116_16_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3023), BOARD_APCI3116_8_4 },
- { PCI_VDEVICE(ADDIDATA, 0x300B), BOARD_APCI3003 },
- { PCI_VDEVICE(ADDIDATA, 0x3002), BOARD_APCI3002_16 },
- { PCI_VDEVICE(ADDIDATA, 0x3003), BOARD_APCI3002_8 },
- { PCI_VDEVICE(ADDIDATA, 0x3004), BOARD_APCI3002_4 },
- { PCI_VDEVICE(ADDIDATA, 0x3024), BOARD_APCI3500 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci3xxx_pci_table);
-
-static struct pci_driver apci3xxx_pci_driver = {
- .name = "addi_apci_3xxx",
- .id_table = apci3xxx_pci_table,
- .probe = apci3xxx_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_tcw.h b/drivers/staging/comedi/drivers/addi_tcw.h
deleted file mode 100644
index 2b44d3a04484..000000000000
--- a/drivers/staging/comedi/drivers/addi_tcw.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ADDI_TCW_H
-#define _ADDI_TCW_H
-
-/*
- * Following are the generic definitions for the ADDI-DATA timer/counter/
- * watchdog (TCW) registers and bits. Some of the registers are not used
- * depending on the use of the TCW.
- */
-
-#define ADDI_TCW_VAL_REG 0x00
-
-#define ADDI_TCW_SYNC_REG 0x00
-#define ADDI_TCW_SYNC_CTR_TRIG BIT(8)
-#define ADDI_TCW_SYNC_CTR_DIS BIT(7)
-#define ADDI_TCW_SYNC_CTR_ENA BIT(6)
-#define ADDI_TCW_SYNC_TIMER_TRIG BIT(5)
-#define ADDI_TCW_SYNC_TIMER_DIS BIT(4)
-#define ADDI_TCW_SYNC_TIMER_ENA BIT(3)
-#define ADDI_TCW_SYNC_WDOG_TRIG BIT(2)
-#define ADDI_TCW_SYNC_WDOG_DIS BIT(1)
-#define ADDI_TCW_SYNC_WDOG_ENA BIT(0)
-
-#define ADDI_TCW_RELOAD_REG 0x04
-
-#define ADDI_TCW_TIMEBASE_REG 0x08
-
-#define ADDI_TCW_CTRL_REG 0x0c
-#define ADDI_TCW_CTRL_EXT_CLK_STATUS BIT(21)
-#define ADDI_TCW_CTRL_CASCADE BIT(20)
-#define ADDI_TCW_CTRL_CNTR_ENA BIT(19)
-#define ADDI_TCW_CTRL_CNT_UP BIT(18)
-#define ADDI_TCW_CTRL_EXT_CLK(x) (((x) & 3) << 16)
-#define ADDI_TCW_CTRL_EXT_CLK_MASK ADDI_TCW_CTRL_EXT_CLK(3)
-#define ADDI_TCW_CTRL_MODE(x) (((x) & 7) << 13)
-#define ADDI_TCW_CTRL_MODE_MASK ADDI_TCW_CTRL_MODE(7)
-#define ADDI_TCW_CTRL_OUT(x) (((x) & 3) << 11)
-#define ADDI_TCW_CTRL_OUT_MASK ADDI_TCW_CTRL_OUT(3)
-#define ADDI_TCW_CTRL_GATE BIT(10)
-#define ADDI_TCW_CTRL_TRIG BIT(9)
-#define ADDI_TCW_CTRL_EXT_GATE(x) (((x) & 3) << 7)
-#define ADDI_TCW_CTRL_EXT_GATE_MASK ADDI_TCW_CTRL_EXT_GATE(3)
-#define ADDI_TCW_CTRL_EXT_TRIG(x) (((x) & 3) << 5)
-#define ADDI_TCW_CTRL_EXT_TRIG_MASK ADDI_TCW_CTRL_EXT_TRIG(3)
-#define ADDI_TCW_CTRL_TIMER_ENA BIT(4)
-#define ADDI_TCW_CTRL_RESET_ENA BIT(3)
-#define ADDI_TCW_CTRL_WARN_ENA BIT(2)
-#define ADDI_TCW_CTRL_IRQ_ENA BIT(1)
-#define ADDI_TCW_CTRL_ENA BIT(0)
-
-#define ADDI_TCW_STATUS_REG 0x10
-#define ADDI_TCW_STATUS_SOFT_CLR BIT(3)
-#define ADDI_TCW_STATUS_HARDWARE_TRIG BIT(2)
-#define ADDI_TCW_STATUS_SOFT_TRIG BIT(1)
-#define ADDI_TCW_STATUS_OVERFLOW BIT(0)
-
-#define ADDI_TCW_IRQ_REG 0x14
-#define ADDI_TCW_IRQ BIT(0)
-
-#define ADDI_TCW_WARN_TIMEVAL_REG 0x18
-
-#define ADDI_TCW_WARN_TIMEBASE_REG 0x1c
-
-#endif
diff --git a/drivers/staging/comedi/drivers/addi_watchdog.c b/drivers/staging/comedi/drivers/addi_watchdog.c
deleted file mode 100644
index 69b323fb869f..000000000000
--- a/drivers/staging/comedi/drivers/addi_watchdog.c
+++ /dev/null
@@ -1,140 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * COMEDI driver for the watchdog subdevice found on some addi-data boards
- * Copyright (c) 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Based on implementations in various addi-data COMEDI drivers.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-#include "addi_tcw.h"
-#include "addi_watchdog.h"
-
-struct addi_watchdog_private {
- unsigned long iobase;
- unsigned int wdog_ctrl;
-};
-
-/*
- * The watchdog subdevice is configured with two INSN_CONFIG instructions:
- *
- * Enable the watchdog and set the reload timeout:
- * data[0] = INSN_CONFIG_ARM
- * data[1] = timeout reload value
- *
- * Disable the watchdog:
- * data[0] = INSN_CONFIG_DISARM
- */
-static int addi_watchdog_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct addi_watchdog_private *spriv = s->private;
- unsigned int reload;
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- spriv->wdog_ctrl = ADDI_TCW_CTRL_ENA;
- reload = data[1] & s->maxdata;
- outl(reload, spriv->iobase + ADDI_TCW_RELOAD_REG);
-
- /* Time base is 20ms, let the user know the timeout */
- dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n",
- 20 * reload + 20);
- break;
- case INSN_CONFIG_DISARM:
- spriv->wdog_ctrl = 0;
- break;
- default:
- return -EINVAL;
- }
-
- outl(spriv->wdog_ctrl, spriv->iobase + ADDI_TCW_CTRL_REG);
-
- return insn->n;
-}
-
-static int addi_watchdog_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct addi_watchdog_private *spriv = s->private;
- int i;
-
- for (i = 0; i < insn->n; i++)
- data[i] = inl(spriv->iobase + ADDI_TCW_STATUS_REG);
-
- return insn->n;
-}
-
-static int addi_watchdog_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct addi_watchdog_private *spriv = s->private;
- int i;
-
- if (spriv->wdog_ctrl == 0) {
- dev_warn(dev->class_dev, "watchdog is disabled\n");
- return -EINVAL;
- }
-
- /* "ping" the watchdog */
- for (i = 0; i < insn->n; i++) {
- outl(spriv->wdog_ctrl | ADDI_TCW_CTRL_TRIG,
- spriv->iobase + ADDI_TCW_CTRL_REG);
- }
-
- return insn->n;
-}
-
-void addi_watchdog_reset(unsigned long iobase)
-{
- outl(0x0, iobase + ADDI_TCW_CTRL_REG);
- outl(0x0, iobase + ADDI_TCW_RELOAD_REG);
-}
-EXPORT_SYMBOL_GPL(addi_watchdog_reset);
-
-int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase)
-{
- struct addi_watchdog_private *spriv;
-
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
-
- spriv->iobase = iobase;
-
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 1;
- s->maxdata = 0xff;
- s->insn_config = addi_watchdog_insn_config;
- s->insn_read = addi_watchdog_insn_read;
- s->insn_write = addi_watchdog_insn_write;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(addi_watchdog_init);
-
-static int __init addi_watchdog_module_init(void)
-{
- return 0;
-}
-module_init(addi_watchdog_module_init);
-
-static void __exit addi_watchdog_module_exit(void)
-{
-}
-module_exit(addi_watchdog_module_exit);
-
-MODULE_DESCRIPTION("ADDI-DATA Watchdog subdevice");
-MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi_watchdog.h b/drivers/staging/comedi/drivers/addi_watchdog.h
deleted file mode 100644
index 7523084a0742..000000000000
--- a/drivers/staging/comedi/drivers/addi_watchdog.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ADDI_WATCHDOG_H
-#define _ADDI_WATCHDOG_H
-
-struct comedi_subdevice;
-
-void addi_watchdog_reset(unsigned long iobase);
-int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase);
-
-#endif
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
deleted file mode 100644
index 9ae4cc523dd4..000000000000
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ /dev/null
@@ -1,201 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * adl_pci6208.c
- * Comedi driver for ADLink 6208 series cards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: adl_pci6208
- * Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
- * Devices: [ADLink] PCI-6208 (adl_pci6208), PCI-6216
- * Author: nsyeow <nsyeow@pd.jaring.my>
- * Updated: Wed, 11 Feb 2015 11:37:18 +0000
- * Status: untested
- *
- * Configuration Options: not applicable, uses PCI auto config
- *
- * All supported devices share the same PCI device ID and are treated as a
- * PCI-6216 with 16 analog output channels. On a PCI-6208, the upper 8
- * channels exist in registers, but don't go to DAC chips.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI-6208/6216-GL register map
- */
-#define PCI6208_AO_CONTROL(x) (0x00 + (2 * (x)))
-#define PCI6208_AO_STATUS 0x00
-#define PCI6208_AO_STATUS_DATA_SEND BIT(0)
-#define PCI6208_DIO 0x40
-#define PCI6208_DIO_DO_MASK (0x0f)
-#define PCI6208_DIO_DO_SHIFT (0)
-#define PCI6208_DIO_DI_MASK (0xf0)
-#define PCI6208_DIO_DI_SHIFT (4)
-
-static int pci6208_ao_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + PCI6208_AO_STATUS);
- if ((status & PCI6208_AO_STATUS_DATA_SEND) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int pci6208_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- /* D/A transfer rate is 2.2us */
- ret = comedi_timeout(dev, s, insn, pci6208_ao_eoc, 0);
- if (ret)
- return ret;
-
- /* the hardware expects two's complement values */
- outw(comedi_offset_munge(s, val),
- dev->iobase + PCI6208_AO_CONTROL(chan));
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int pci6208_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int val;
-
- val = inw(dev->iobase + PCI6208_DIO);
- val = (val & PCI6208_DIO_DI_MASK) >> PCI6208_DIO_DI_SHIFT;
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int pci6208_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + PCI6208_DIO);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pci6208_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- unsigned int val;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16; /* Only 8 usable on PCI-6208 */
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar10;
- s->insn_write = pci6208_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s = &dev->subdevices[1];
- /* digital input subdevice */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci6208_di_insn_bits;
-
- s = &dev->subdevices[2];
- /* digital output subdevice */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci6208_do_insn_bits;
-
- /*
- * Get the read back signals from the digital outputs
- * and save it as the initial state for the subdevice.
- */
- val = inw(dev->iobase + PCI6208_DIO);
- val = (val & PCI6208_DIO_DO_MASK) >> PCI6208_DIO_DO_SHIFT;
- s->state = val;
-
- return 0;
-}
-
-static struct comedi_driver adl_pci6208_driver = {
- .driver_name = "adl_pci6208",
- .module = THIS_MODULE,
- .auto_attach = pci6208_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int adl_pci6208_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adl_pci6208_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id adl_pci6208_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x6208) },
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
- 0x9999, 0x6208) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adl_pci6208_pci_table);
-
-static struct pci_driver adl_pci6208_pci_driver = {
- .name = "adl_pci6208",
- .id_table = adl_pci6208_pci_table,
- .probe = adl_pci6208_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for ADLink 6208 series cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c
deleted file mode 100644
index 8fc45638ff59..000000000000
--- a/drivers/staging/comedi/drivers/adl_pci7x3x.c
+++ /dev/null
@@ -1,542 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * COMEDI driver for the ADLINK PCI-723x/743x series boards.
- * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Based on the adl_pci7230 driver written by:
- * David Fernandez <dfcastelao@gmail.com>
- * and the adl_pci7432 driver written by:
- * Michel Lachaine <mike@mikelachaine.ca>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: adl_pci7x3x
- * Description: 32/64-Channel Isolated Digital I/O Boards
- * Devices: [ADLink] PCI-7230 (adl_pci7230), PCI-7233 (adl_pci7233),
- * PCI-7234 (adl_pci7234), PCI-7432 (adl_pci7432), PCI-7433 (adl_pci7433),
- * PCI-7434 (adl_pci7434)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Fri, 20 Nov 2020 14:49:36 +0000
- * Status: works (tested on PCI-7230)
- *
- * One or two subdevices are setup by this driver depending on
- * the number of digital inputs and/or outputs provided by the
- * board. Each subdevice has a maximum of 32 channels.
- *
- * PCI-7230 - 4 subdevices: 0 - 16 input, 1 - 16 output,
- * 2 - IRQ_IDI0, 3 - IRQ_IDI1
- * PCI-7233 - 1 subdevice: 0 - 32 input
- * PCI-7234 - 1 subdevice: 0 - 32 output
- * PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output
- * PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input
- * PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output
- *
- * The PCI-7230, PCI-7432 and PCI-7433 boards also support external
- * interrupt signals on digital input channels 0 and 1. The PCI-7233
- * has dual-interrupt sources for change-of-state (COS) on any 16
- * digital input channels of LSB and for COS on any 16 digital input
- * lines of MSB.
- *
- * Currently, this driver only supports interrupts for PCI-7230.
- *
- * Configuration Options: not applicable, uses comedi PCI auto config
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-#include "plx9052.h"
-
-/*
- * Register I/O map (32-bit access only)
- */
-#define PCI7X3X_DIO_REG 0x0000 /* in the DigIO Port area */
-#define PCI743X_DIO_REG 0x0004
-
-#define ADL_PT_CLRIRQ 0x0040 /* in the DigIO Port area */
-
-#define LINTI1_EN_ACT_IDI0 (PLX9052_INTCSR_LI1ENAB | PLX9052_INTCSR_LI1STAT)
-#define LINTI2_EN_ACT_IDI1 (PLX9052_INTCSR_LI2ENAB | PLX9052_INTCSR_LI2STAT)
-#define EN_PCI_LINT2H_LINT1H \
- (PLX9052_INTCSR_PCIENAB | PLX9052_INTCSR_LI2POL | PLX9052_INTCSR_LI1POL)
-
-enum adl_pci7x3x_boardid {
- BOARD_PCI7230,
- BOARD_PCI7233,
- BOARD_PCI7234,
- BOARD_PCI7432,
- BOARD_PCI7433,
- BOARD_PCI7434,
-};
-
-struct adl_pci7x3x_boardinfo {
- const char *name;
- int nsubdevs;
- int di_nchan;
- int do_nchan;
- int irq_nchan;
-};
-
-static const struct adl_pci7x3x_boardinfo adl_pci7x3x_boards[] = {
- [BOARD_PCI7230] = {
- .name = "adl_pci7230",
- .nsubdevs = 4, /* IDI, IDO, IRQ_IDI0, IRQ_IDI1 */
- .di_nchan = 16,
- .do_nchan = 16,
- .irq_nchan = 2,
- },
- [BOARD_PCI7233] = {
- .name = "adl_pci7233",
- .nsubdevs = 1,
- .di_nchan = 32,
- },
- [BOARD_PCI7234] = {
- .name = "adl_pci7234",
- .nsubdevs = 1,
- .do_nchan = 32,
- },
- [BOARD_PCI7432] = {
- .name = "adl_pci7432",
- .nsubdevs = 2,
- .di_nchan = 32,
- .do_nchan = 32,
- },
- [BOARD_PCI7433] = {
- .name = "adl_pci7433",
- .nsubdevs = 2,
- .di_nchan = 64,
- },
- [BOARD_PCI7434] = {
- .name = "adl_pci7434",
- .nsubdevs = 2,
- .do_nchan = 64,
- }
-};
-
-struct adl_pci7x3x_dev_private_data {
- unsigned long lcr_io_base;
- unsigned int int_ctrl;
-};
-
-struct adl_pci7x3x_sd_private_data {
- spinlock_t subd_slock; /* spin-lock for cmd_running */
- unsigned long port_offset;
- short int cmd_running;
-};
-
-static void process_irq(struct comedi_device *dev, unsigned int subdev,
- unsigned short intcsr)
-{
- struct comedi_subdevice *s = &dev->subdevices[subdev];
- struct adl_pci7x3x_sd_private_data *sd_priv = s->private;
- unsigned long reg = sd_priv->port_offset;
- struct comedi_async *async_p = s->async;
-
- if (async_p) {
- unsigned short val = inw(dev->iobase + reg);
-
- spin_lock(&sd_priv->subd_slock);
- if (sd_priv->cmd_running)
- comedi_buf_write_samples(s, &val, 1);
- spin_unlock(&sd_priv->subd_slock);
- comedi_handle_events(dev, s);
- }
-}
-
-static irqreturn_t adl_pci7x3x_interrupt(int irq, void *p_device)
-{
- struct comedi_device *dev = p_device;
- struct adl_pci7x3x_dev_private_data *dev_private = dev->private;
- unsigned long cpu_flags;
- unsigned int intcsr;
- bool li1stat, li2stat;
-
- if (!dev->attached) {
- /* Ignore interrupt before device fully attached. */
- /* Might not even have allocated subdevices yet! */
- return IRQ_NONE;
- }
-
- /* Check if we are source of interrupt */
- spin_lock_irqsave(&dev->spinlock, cpu_flags);
- intcsr = inl(dev_private->lcr_io_base + PLX9052_INTCSR);
- li1stat = (intcsr & LINTI1_EN_ACT_IDI0) == LINTI1_EN_ACT_IDI0;
- li2stat = (intcsr & LINTI2_EN_ACT_IDI1) == LINTI2_EN_ACT_IDI1;
- if (li1stat || li2stat) {
- /* clear all current interrupt flags */
- /* Fixme: Reset all 2 Int Flags */
- outb(0x00, dev->iobase + ADL_PT_CLRIRQ);
- }
- spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
-
- /* SubDev 2, 3 = Isolated DigIn , on "SCSI2" jack!*/
-
- if (li1stat) /* 0x0005 LINTi1 is Enabled && IDI0 is 1 */
- process_irq(dev, 2, intcsr);
-
- if (li2stat) /* 0x0028 LINTi2 is Enabled && IDI1 is 1 */
- process_irq(dev, 3, intcsr);
-
- return IRQ_RETVAL(li1stat || li2stat);
-}
-
-static int adl_pci7x3x_asy_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int adl_pci7x3x_asy_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct adl_pci7x3x_dev_private_data *dev_private = dev->private;
- struct adl_pci7x3x_sd_private_data *sd_priv = s->private;
- unsigned long cpu_flags;
- unsigned int int_enab;
-
- if (s->index == 2) {
- /* enable LINTi1 == IDI sdi[0] Ch 0 IRQ ActHigh */
- int_enab = PLX9052_INTCSR_LI1ENAB;
- } else {
- /* enable LINTi2 == IDI sdi[0] Ch 1 IRQ ActHigh */
- int_enab = PLX9052_INTCSR_LI2ENAB;
- }
-
- spin_lock_irqsave(&dev->spinlock, cpu_flags);
- dev_private->int_ctrl |= int_enab;
- outl(dev_private->int_ctrl, dev_private->lcr_io_base + PLX9052_INTCSR);
- spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
-
- spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags);
- sd_priv->cmd_running = 1;
- spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags);
-
- return 0;
-}
-
-static int adl_pci7x3x_asy_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct adl_pci7x3x_dev_private_data *dev_private = dev->private;
- struct adl_pci7x3x_sd_private_data *sd_priv = s->private;
- unsigned long cpu_flags;
- unsigned int int_enab;
-
- spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags);
- sd_priv->cmd_running = 0;
- spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags);
- /* disable Interrupts */
- if (s->index == 2)
- int_enab = PLX9052_INTCSR_LI1ENAB;
- else
- int_enab = PLX9052_INTCSR_LI2ENAB;
- spin_lock_irqsave(&dev->spinlock, cpu_flags);
- dev_private->int_ctrl &= ~int_enab;
- outl(dev_private->int_ctrl, dev_private->lcr_io_base + PLX9052_INTCSR);
- spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
-
- return 0;
-}
-
-/* same as _di_insn_bits because the IRQ-pins are the DI-ports */
-static int adl_pci7x3x_dirq_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct adl_pci7x3x_sd_private_data *sd_priv = s->private;
- unsigned long reg = (unsigned long)sd_priv->port_offset;
-
- data[1] = inl(dev->iobase + reg);
-
- return insn->n;
-}
-
-static int adl_pci7x3x_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long reg = (unsigned long)s->private;
-
- if (comedi_dio_update_state(s, data)) {
- unsigned int val = s->state;
-
- if (s->n_chan == 16) {
- /*
- * It seems the PCI-7230 needs the 16-bit DO state
- * to be shifted left by 16 bits before being written
- * to the 32-bit register. Set the value in both
- * halves of the register to be sure.
- */
- val |= val << 16;
- }
- outl(val, dev->iobase + reg);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int adl_pci7x3x_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long reg = (unsigned long)s->private;
-
- data[1] = inl(dev->iobase + reg);
-
- return insn->n;
-}
-
-static int adl_pci7x3x_reset(struct comedi_device *dev)
-{
- struct adl_pci7x3x_dev_private_data *dev_private = dev->private;
-
- /* disable Interrupts */
- dev_private->int_ctrl = 0x00; /* Disable PCI + LINTi2 + LINTi1 */
- outl(dev_private->int_ctrl, dev_private->lcr_io_base + PLX9052_INTCSR);
-
- return 0;
-}
-
-static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct adl_pci7x3x_boardinfo *board = NULL;
- struct comedi_subdevice *s;
- struct adl_pci7x3x_dev_private_data *dev_private;
- int subdev;
- int nchan;
- int ret;
- int ic;
-
- if (context < ARRAY_SIZE(adl_pci7x3x_boards))
- board = &adl_pci7x3x_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- dev_private = comedi_alloc_devpriv(dev, sizeof(*dev_private));
- if (!dev_private)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
- dev_private->lcr_io_base = pci_resource_start(pcidev, 1);
-
- adl_pci7x3x_reset(dev);
-
- if (board->irq_nchan) {
- /* discard all evtl. old IRQs */
- outb(0x00, dev->iobase + ADL_PT_CLRIRQ);
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, adl_pci7x3x_interrupt,
- IRQF_SHARED, dev->board_name, dev);
- if (ret == 0) {
- dev->irq = pcidev->irq;
- /* 0x52 PCI + IDI Ch 1 Ch 0 IRQ Off ActHigh */
- dev_private->int_ctrl = EN_PCI_LINT2H_LINT1H;
- outl(dev_private->int_ctrl,
- dev_private->lcr_io_base + PLX9052_INTCSR);
- }
- }
- }
-
- ret = comedi_alloc_subdevices(dev, board->nsubdevs);
- if (ret)
- return ret;
-
- subdev = 0;
-
- if (board->di_nchan) {
- nchan = min(board->di_nchan, 32);
-
- s = &dev->subdevices[subdev];
- /* Isolated digital inputs 0 to 15/31 */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = nchan;
- s->maxdata = 1;
- s->insn_bits = adl_pci7x3x_di_insn_bits;
- s->range_table = &range_digital;
-
- s->private = (void *)PCI7X3X_DIO_REG;
-
- subdev++;
-
- nchan = board->di_nchan - nchan;
- if (nchan) {
- s = &dev->subdevices[subdev];
- /* Isolated digital inputs 32 to 63 */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = nchan;
- s->maxdata = 1;
- s->insn_bits = adl_pci7x3x_di_insn_bits;
- s->range_table = &range_digital;
-
- s->private = (void *)PCI743X_DIO_REG;
-
- subdev++;
- }
- }
-
- if (board->do_nchan) {
- nchan = min(board->do_nchan, 32);
-
- s = &dev->subdevices[subdev];
- /* Isolated digital outputs 0 to 15/31 */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = nchan;
- s->maxdata = 1;
- s->insn_bits = adl_pci7x3x_do_insn_bits;
- s->range_table = &range_digital;
-
- s->private = (void *)PCI7X3X_DIO_REG;
-
- subdev++;
-
- nchan = board->do_nchan - nchan;
- if (nchan) {
- s = &dev->subdevices[subdev];
- /* Isolated digital outputs 32 to 63 */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = nchan;
- s->maxdata = 1;
- s->insn_bits = adl_pci7x3x_do_insn_bits;
- s->range_table = &range_digital;
-
- s->private = (void *)PCI743X_DIO_REG;
-
- subdev++;
- }
- }
-
- for (ic = 0; ic < board->irq_nchan; ++ic) {
- struct adl_pci7x3x_sd_private_data *sd_priv;
-
- nchan = 1;
-
- s = &dev->subdevices[subdev];
- /* Isolated digital inputs 0 or 1 */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = nchan;
- s->maxdata = 1;
- s->insn_bits = adl_pci7x3x_dirq_insn_bits;
- s->range_table = &range_digital;
-
- sd_priv = comedi_alloc_spriv(s, sizeof(*sd_priv));
- if (!sd_priv)
- return -ENOMEM;
-
- spin_lock_init(&sd_priv->subd_slock);
- sd_priv->port_offset = PCI7X3X_DIO_REG;
- sd_priv->cmd_running = 0;
-
- if (dev->irq) {
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->len_chanlist = 1;
- s->do_cmdtest = adl_pci7x3x_asy_cmdtest;
- s->do_cmd = adl_pci7x3x_asy_cmd;
- s->cancel = adl_pci7x3x_asy_cancel;
- }
-
- subdev++;
- }
-
- return 0;
-}
-
-static void adl_pci7x3x_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- adl_pci7x3x_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver adl_pci7x3x_driver = {
- .driver_name = "adl_pci7x3x",
- .module = THIS_MODULE,
- .auto_attach = adl_pci7x3x_auto_attach,
- .detach = adl_pci7x3x_detach,
-};
-
-static int adl_pci7x3x_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adl_pci7x3x_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id adl_pci7x3x_pci_table[] = {
- { PCI_VDEVICE(ADLINK, 0x7230), BOARD_PCI7230 },
- { PCI_VDEVICE(ADLINK, 0x7233), BOARD_PCI7233 },
- { PCI_VDEVICE(ADLINK, 0x7234), BOARD_PCI7234 },
- { PCI_VDEVICE(ADLINK, 0x7432), BOARD_PCI7432 },
- { PCI_VDEVICE(ADLINK, 0x7433), BOARD_PCI7433 },
- { PCI_VDEVICE(ADLINK, 0x7434), BOARD_PCI7434 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adl_pci7x3x_pci_table);
-
-static struct pci_driver adl_pci7x3x_pci_driver = {
- .name = "adl_pci7x3x",
- .id_table = adl_pci7x3x_pci_table,
- .probe = adl_pci7x3x_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adl_pci7x3x_driver, adl_pci7x3x_pci_driver);
-
-MODULE_DESCRIPTION("ADLINK PCI-723x/743x Isolated Digital I/O boards");
-MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
deleted file mode 100644
index d5e1bda81557..000000000000
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ /dev/null
@@ -1,154 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/adl_pci8164.c
- *
- * Hardware comedi driver for PCI-8164 Adlink card
- * Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
- */
-
-/*
- * Driver: adl_pci8164
- * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
- * Devices: [ADLink] PCI-8164 (adl_pci8164)
- * Author: Michel Lachaine <mike@mikelachaine.ca>
- * Status: experimental
- * Updated: Mon, 14 Apr 2008 15:10:32 +0100
- *
- * Configuration Options: not applicable, uses PCI auto config
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-#define PCI8164_AXIS(x) ((x) * 0x08)
-#define PCI8164_CMD_MSTS_REG 0x00
-#define PCI8164_OTP_SSTS_REG 0x02
-#define PCI8164_BUF0_REG 0x04
-#define PCI8164_BUF1_REG 0x06
-
-static int adl_pci8164_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long offset = (unsigned long)s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++)
- data[i] = inw(dev->iobase + PCI8164_AXIS(chan) + offset);
-
- return insn->n;
-}
-
-static int adl_pci8164_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long offset = (unsigned long)s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++)
- outw(data[i], dev->iobase + PCI8164_AXIS(chan) + offset);
-
- return insn->n;
-}
-
-static int adl_pci8164_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* read MSTS register / write CMD register for each axis (channel) */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- s->insn_read = adl_pci8164_insn_read;
- s->insn_write = adl_pci8164_insn_write;
- s->private = (void *)PCI8164_CMD_MSTS_REG;
-
- /* read SSTS register / write OTP register for each axis (channel) */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- s->insn_read = adl_pci8164_insn_read;
- s->insn_write = adl_pci8164_insn_write;
- s->private = (void *)PCI8164_OTP_SSTS_REG;
-
- /* read/write BUF0 register for each axis (channel) */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- s->insn_read = adl_pci8164_insn_read;
- s->insn_write = adl_pci8164_insn_write;
- s->private = (void *)PCI8164_BUF0_REG;
-
- /* read/write BUF1 register for each axis (channel) */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- s->insn_read = adl_pci8164_insn_read;
- s->insn_write = adl_pci8164_insn_write;
- s->private = (void *)PCI8164_BUF1_REG;
-
- return 0;
-}
-
-static struct comedi_driver adl_pci8164_driver = {
- .driver_name = "adl_pci8164",
- .module = THIS_MODULE,
- .auto_attach = adl_pci8164_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int adl_pci8164_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adl_pci8164_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id adl_pci8164_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
-
-static struct pci_driver adl_pci8164_pci_driver = {
- .name = "adl_pci8164",
- .id_table = adl_pci8164_pci_table,
- .probe = adl_pci8164_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
deleted file mode 100644
index a062c5ab20e9..000000000000
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ /dev/null
@@ -1,747 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * adl_pci9111.c
- * Hardware driver for PCI9111 ADLink cards: PCI-9111HR
- * Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
- */
-
-/*
- * Driver: adl_pci9111
- * Description: Adlink PCI-9111HR
- * Devices: [ADLink] PCI-9111HR (adl_pci9111)
- * Author: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
- * Status: experimental
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * Supports:
- * - ai_insn read
- * - ao_insn read/write
- * - di_insn read
- * - do_insn read/write
- * - ai_do_cmd mode with the following sources:
- * - start_src TRIG_NOW
- * - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT
- * - convert_src TRIG_TIMER TRIG_EXT
- * - scan_end_src TRIG_COUNT
- * - stop_src TRIG_COUNT TRIG_NONE
- *
- * The scanned channels must be consecutive and start from 0. They must
- * all have the same range and aref.
- */
-
-/*
- * TODO:
- * - Really test implemented functionality.
- * - Add support for the PCI-9111DG with a probe routine to identify
- * the card type (perhaps with the help of the channel number readback
- * of the A/D Data register).
- * - Add external multiplexer support.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "plx9052.h"
-#include "comedi_8254.h"
-
-#define PCI9111_FIFO_HALF_SIZE 512
-
-#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000
-
-#define PCI9111_RANGE_SETTING_DELAY 10
-#define PCI9111_AI_INSTANT_READ_UDELAY_US 2
-
-/*
- * IO address map and bit defines
- */
-#define PCI9111_AI_FIFO_REG 0x00
-#define PCI9111_AO_REG 0x00
-#define PCI9111_DIO_REG 0x02
-#define PCI9111_EDIO_REG 0x04
-#define PCI9111_AI_CHANNEL_REG 0x06
-#define PCI9111_AI_RANGE_STAT_REG 0x08
-#define PCI9111_AI_STAT_AD_BUSY BIT(7)
-#define PCI9111_AI_STAT_FF_FF BIT(6)
-#define PCI9111_AI_STAT_FF_HF BIT(5)
-#define PCI9111_AI_STAT_FF_EF BIT(4)
-#define PCI9111_AI_RANGE(x) (((x) & 0x7) << 0)
-#define PCI9111_AI_RANGE_MASK PCI9111_AI_RANGE(7)
-#define PCI9111_AI_TRIG_CTRL_REG 0x0a
-#define PCI9111_AI_TRIG_CTRL_TRGEVENT BIT(5)
-#define PCI9111_AI_TRIG_CTRL_POTRG BIT(4)
-#define PCI9111_AI_TRIG_CTRL_PTRG BIT(3)
-#define PCI9111_AI_TRIG_CTRL_ETIS BIT(2)
-#define PCI9111_AI_TRIG_CTRL_TPST BIT(1)
-#define PCI9111_AI_TRIG_CTRL_ASCAN BIT(0)
-#define PCI9111_INT_CTRL_REG 0x0c
-#define PCI9111_INT_CTRL_ISC2 BIT(3)
-#define PCI9111_INT_CTRL_FFEN BIT(2)
-#define PCI9111_INT_CTRL_ISC1 BIT(1)
-#define PCI9111_INT_CTRL_ISC0 BIT(0)
-#define PCI9111_SOFT_TRIG_REG 0x0e
-#define PCI9111_8254_BASE_REG 0x40
-#define PCI9111_INT_CLR_REG 0x48
-
-/* PLX 9052 Local Interrupt 1 enabled and active */
-#define PCI9111_LI1_ACTIVE (PLX9052_INTCSR_LI1ENAB | \
- PLX9052_INTCSR_LI1STAT)
-
-/* PLX 9052 Local Interrupt 2 enabled and active */
-#define PCI9111_LI2_ACTIVE (PLX9052_INTCSR_LI2ENAB | \
- PLX9052_INTCSR_LI2STAT)
-
-static const struct comedi_lrange pci9111_ai_range = {
- 5, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625)
- }
-};
-
-struct pci9111_private_data {
- unsigned long lcr_io_base;
-
- unsigned int scan_delay;
- unsigned int chunk_counter;
- unsigned int chunk_num_samples;
-
- unsigned short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
-};
-
-static void plx9050_interrupt_control(unsigned long io_base,
- bool int1_enable,
- bool int1_active_high,
- bool int2_enable,
- bool int2_active_high,
- bool interrupt_enable)
-{
- int flags = 0;
-
- if (int1_enable)
- flags |= PLX9052_INTCSR_LI1ENAB;
- if (int1_active_high)
- flags |= PLX9052_INTCSR_LI1POL;
- if (int2_enable)
- flags |= PLX9052_INTCSR_LI2ENAB;
- if (int2_active_high)
- flags |= PLX9052_INTCSR_LI2POL;
-
- if (interrupt_enable)
- flags |= PLX9052_INTCSR_PCIENAB;
-
- outb(flags, io_base + PLX9052_INTCSR);
-}
-
-enum pci9111_ISC0_sources {
- irq_on_eoc,
- irq_on_fifo_half_full
-};
-
-enum pci9111_ISC1_sources {
- irq_on_timer_tick,
- irq_on_external_trigger
-};
-
-static void pci9111_interrupt_source_set(struct comedi_device *dev,
- enum pci9111_ISC0_sources irq_0_source,
- enum pci9111_ISC1_sources irq_1_source)
-{
- int flags;
-
- /* Read the current interrupt control bits */
- flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
- /* Shift the bits so they are compatible with the write register */
- flags >>= 4;
- /* Mask off the ISCx bits */
- flags &= 0xc0;
-
- /* Now set the new ISCx bits */
- if (irq_0_source == irq_on_fifo_half_full)
- flags |= PCI9111_INT_CTRL_ISC0;
-
- if (irq_1_source == irq_on_external_trigger)
- flags |= PCI9111_INT_CTRL_ISC1;
-
- outb(flags, dev->iobase + PCI9111_INT_CTRL_REG);
-}
-
-static void pci9111_fifo_reset(struct comedi_device *dev)
-{
- unsigned long int_ctrl_reg = dev->iobase + PCI9111_INT_CTRL_REG;
-
- /* To reset the FIFO, set FFEN sequence as 0 -> 1 -> 0 */
- outb(0, int_ctrl_reg);
- outb(PCI9111_INT_CTRL_FFEN, int_ctrl_reg);
- outb(0, int_ctrl_reg);
-}
-
-static int pci9111_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci9111_private_data *dev_private = dev->private;
-
- /* Disable interrupts */
- plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
- true, false);
-
- /* disable A/D triggers (software trigger mode) and auto scan off */
- outb(0, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-
- pci9111_fifo_reset(dev);
-
- return 0;
-}
-
-static int pci9111_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- if (chan != i) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must be consecutive channels,counting upwards from 0\n");
- return -EINVAL;
- }
-
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must all have the same gain\n");
- return -EINVAL;
- }
-
- if (aref != aref0) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must all have the same reference\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src,
- TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->scan_begin_src != TRIG_FOLLOW) {
- if (cmd->scan_begin_src != cmd->convert_src)
- err |= -EINVAL;
- }
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
- } else { /* TRIG_EXT */
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
- } else { /* TRIG_FOLLOW || TRIG_EXT */
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- /*
- * There's only one timer on this card, so the scan_begin timer
- * must be a multiple of chanlist_len*convert_arg
- */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->chanlist_len * cmd->convert_arg;
-
- if (arg < cmd->scan_begin_arg)
- arg *= (cmd->scan_begin_arg / arg);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= pci9111_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int pci9111_ai_do_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci9111_private_data *dev_private = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int last_chan = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- unsigned int trig = 0;
-
- /* Set channel scan limit */
- /* PCI9111 allows only scanning from channel 0 to channel n */
- /* TODO: handle the case of an external multiplexer */
-
- if (cmd->chanlist_len > 1)
- trig |= PCI9111_AI_TRIG_CTRL_ASCAN;
-
- outb(last_chan, dev->iobase + PCI9111_AI_CHANNEL_REG);
-
- /* Set gain - all channels use the same range */
- outb(PCI9111_AI_RANGE(range0), dev->iobase + PCI9111_AI_RANGE_STAT_REG);
-
- /* Set timer pacer */
- dev_private->scan_delay = 0;
- if (cmd->convert_src == TRIG_TIMER) {
- trig |= PCI9111_AI_TRIG_CTRL_TPST;
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- pci9111_fifo_reset(dev);
- pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
- irq_on_timer_tick);
- plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
- false, true, true);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- dev_private->scan_delay = (cmd->scan_begin_arg /
- (cmd->convert_arg * cmd->chanlist_len)) - 1;
- }
- } else { /* TRIG_EXT */
- trig |= PCI9111_AI_TRIG_CTRL_ETIS;
- pci9111_fifo_reset(dev);
- pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
- irq_on_timer_tick);
- plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
- false, true, true);
- }
- outb(trig, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-
- dev_private->chunk_counter = 0;
- dev_private->chunk_num_samples = cmd->chanlist_len *
- (1 + dev_private->scan_delay);
-
- return 0;
-}
-
-static void pci9111_ai_munge(struct comedi_device *dev,
- struct comedi_subdevice *s, void *data,
- unsigned int num_bytes,
- unsigned int start_chan_index)
-{
- unsigned short *array = data;
- unsigned int maxdata = s->maxdata;
- unsigned int invert = (maxdata + 1) >> 1;
- unsigned int shift = (maxdata == 0xffff) ? 0 : 4;
- unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
- unsigned int i;
-
- for (i = 0; i < num_samples; i++)
- array[i] = ((array[i] >> shift) & maxdata) ^ invert;
-}
-
-static void pci9111_handle_fifo_half_full(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci9111_private_data *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned short *buf = devpriv->ai_bounce_buffer;
- unsigned int samples;
-
- samples = comedi_nsamples_left(s, PCI9111_FIFO_HALF_SIZE);
- insw(dev->iobase + PCI9111_AI_FIFO_REG, buf, samples);
-
- if (devpriv->scan_delay < 1) {
- comedi_buf_write_samples(s, buf, samples);
- } else {
- unsigned int pos = 0;
- unsigned int to_read;
-
- while (pos < samples) {
- if (devpriv->chunk_counter < cmd->chanlist_len) {
- to_read = cmd->chanlist_len -
- devpriv->chunk_counter;
-
- if (to_read > samples - pos)
- to_read = samples - pos;
-
- comedi_buf_write_samples(s, buf + pos, to_read);
- } else {
- to_read = devpriv->chunk_num_samples -
- devpriv->chunk_counter;
-
- if (to_read > samples - pos)
- to_read = samples - pos;
- }
-
- pos += to_read;
- devpriv->chunk_counter += to_read;
-
- if (devpriv->chunk_counter >=
- devpriv->chunk_num_samples)
- devpriv->chunk_counter = 0;
- }
- }
-}
-
-static irqreturn_t pci9111_interrupt(int irq, void *p_device)
-{
- struct comedi_device *dev = p_device;
- struct pci9111_private_data *dev_private = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async;
- struct comedi_cmd *cmd;
- unsigned int status;
- unsigned long irq_flags;
- unsigned char intcsr;
-
- if (!dev->attached) {
- /* Ignore interrupt before device fully attached. */
- /* Might not even have allocated subdevices yet! */
- return IRQ_NONE;
- }
-
- async = s->async;
- cmd = &async->cmd;
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
-
- /* Check if we are source of interrupt */
- intcsr = inb(dev_private->lcr_io_base + PLX9052_INTCSR);
- if (!(((intcsr & PLX9052_INTCSR_PCIENAB) != 0) &&
- (((intcsr & PCI9111_LI1_ACTIVE) == PCI9111_LI1_ACTIVE) ||
- ((intcsr & PCI9111_LI2_ACTIVE) == PCI9111_LI2_ACTIVE)))) {
- /* Not the source of the interrupt. */
- /* (N.B. not using PLX9052_INTCSR_SOFTINT) */
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- return IRQ_NONE;
- }
-
- if ((intcsr & PCI9111_LI1_ACTIVE) == PCI9111_LI1_ACTIVE) {
- /* Interrupt comes from fifo_half-full signal */
-
- status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG);
-
- /* '0' means FIFO is full, data may have been lost */
- if (!(status & PCI9111_AI_STAT_FF_FF)) {
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- dev_dbg(dev->class_dev, "fifo overflow\n");
- outb(0, dev->iobase + PCI9111_INT_CLR_REG);
- async->events |= COMEDI_CB_ERROR;
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
- }
-
- /* '0' means FIFO is half-full */
- if (!(status & PCI9111_AI_STAT_FF_HF))
- pci9111_handle_fifo_half_full(dev, s);
- }
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
-
- outb(0, dev->iobase + PCI9111_INT_CLR_REG);
-
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int pci9111_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG);
- if (status & PCI9111_AI_STAT_FF_EF)
- return 0;
- return -EBUSY;
-}
-
-static int pci9111_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int maxdata = s->maxdata;
- unsigned int invert = (maxdata + 1) >> 1;
- unsigned int shift = (maxdata == 0xffff) ? 0 : 4;
- unsigned int status;
- int ret;
- int i;
-
- outb(chan, dev->iobase + PCI9111_AI_CHANNEL_REG);
-
- status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG);
- if ((status & PCI9111_AI_RANGE_MASK) != range) {
- outb(PCI9111_AI_RANGE(range),
- dev->iobase + PCI9111_AI_RANGE_STAT_REG);
- }
-
- pci9111_fifo_reset(dev);
-
- for (i = 0; i < insn->n; i++) {
- /* Generate a software trigger */
- outb(0, dev->iobase + PCI9111_SOFT_TRIG_REG);
-
- ret = comedi_timeout(dev, s, insn, pci9111_ai_eoc, 0);
- if (ret) {
- pci9111_fifo_reset(dev);
- return ret;
- }
-
- data[i] = inw(dev->iobase + PCI9111_AI_FIFO_REG);
- data[i] = ((data[i] >> shift) & maxdata) ^ invert;
- }
-
- return i;
-}
-
-static int pci9111_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outw(val, dev->iobase + PCI9111_AO_REG);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pci9111_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inw(dev->iobase + PCI9111_DIO_REG);
-
- return insn->n;
-}
-
-static int pci9111_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + PCI9111_DIO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pci9111_reset(struct comedi_device *dev)
-{
- struct pci9111_private_data *dev_private = dev->private;
-
- /* Set trigger source to software */
- plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
- true, false);
-
- /* disable A/D triggers (software trigger mode) and auto scan off */
- outb(0, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-
- return 0;
-}
-
-static int pci9111_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct pci9111_private_data *dev_private;
- struct comedi_subdevice *s;
- int ret;
-
- dev_private = comedi_alloc_devpriv(dev, sizeof(*dev_private));
- if (!dev_private)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev_private->lcr_io_base = pci_resource_start(pcidev, 1);
- dev->iobase = pci_resource_start(pcidev, 2);
-
- pci9111_reset(dev);
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, pci9111_interrupt,
- IRQF_SHARED, dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- dev->pacer = comedi_8254_init(dev->iobase + PCI9111_8254_BASE_REG,
- I8254_OSC_BASE_2MHZ, I8254_IO16, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON;
- s->n_chan = 16;
- s->maxdata = 0xffff;
- s->range_table = &pci9111_ai_range;
- s->insn_read = pci9111_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = pci9111_ai_do_cmd_test;
- s->do_cmd = pci9111_ai_do_cmd;
- s->cancel = pci9111_ai_cancel;
- s->munge = pci9111_ai_munge;
- }
-
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_COMMON;
- s->n_chan = 1;
- s->maxdata = 0x0fff;
- s->len_chanlist = 1;
- s->range_table = &range_bipolar10;
- s->insn_write = pci9111_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci9111_di_insn_bits;
-
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci9111_do_insn_bits;
-
- return 0;
-}
-
-static void pci9111_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- pci9111_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver adl_pci9111_driver = {
- .driver_name = "adl_pci9111",
- .module = THIS_MODULE,
- .auto_attach = pci9111_auto_attach,
- .detach = pci9111_detach,
-};
-
-static int pci9111_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adl_pci9111_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id pci9111_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x9111) },
- /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
-
-static struct pci_driver adl_pci9111_pci_driver = {
- .name = "adl_pci9111",
- .id_table = pci9111_pci_table,
- .probe = pci9111_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
deleted file mode 100644
index cda3a4267dca..000000000000
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ /dev/null
@@ -1,1736 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * comedi/drivers/adl_pci9118.c
- *
- * hardware driver for ADLink cards:
- * card: PCI-9118DG, PCI-9118HG, PCI-9118HR
- * driver: pci9118dg, pci9118hg, pci9118hr
- *
- * Author: Michal Dobes <dobes@tesnet.cz>
- *
- */
-
-/*
- * Driver: adl_pci9118
- * Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
- * Author: Michal Dobes <dobes@tesnet.cz>
- * Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
- * PCI-9118HR (pci9118hr)
- * Status: works
- *
- * This driver supports AI, AO, DI and DO subdevices.
- * AI subdevice supports cmd and insn interface,
- * other subdevices support only insn interface.
- * For AI:
- * - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
- * - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
- * - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
- * - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
- * cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
- * - If return value of cmdtest is 5 then you've bad channel list
- * (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
- * ranges).
- *
- * There are some hardware limitations:
- * a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
- * ended inputs.
- * b) DMA transfers must have the length aligned to two samples (32 bit),
- * so there is some problems if cmd->chanlist_len is odd. This driver tries
- * bypass this with adding one sample to the end of the every scan and discard
- * it on output but this can't be used if cmd->scan_begin_src=TRIG_FOLLOW
- * and is used flag CMDF_WAKE_EOS, then driver switch to interrupt driven mode
- * with interrupt after every sample.
- * c) If isn't used DMA then you can use only mode where
- * cmd->scan_begin_src=TRIG_FOLLOW.
- *
- * Configuration options:
- * [0] - PCI bus of device (optional)
- * [1] - PCI slot of device (optional)
- * If bus/slot is not specified, then first available PCI
- * card will be used.
- * [2] - 0= standard 8 DIFF/16 SE channels configuration
- * n = external multiplexer connected, 1 <= n <= 256
- * [3] - ignored
- * [4] - sample&hold signal - card can generate signal for external S&H board
- * 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
- * 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
- * long delay is requested in ns and sign polarity of the hold
- * (in this case external multiplexor can serve only 128 channels)
- * [5] - ignored
- */
-
-/*
- * FIXME
- *
- * All the supported boards have the same PCI vendor and device IDs, so
- * auto-attachment of PCI devices will always find the first board type.
- *
- * Perhaps the boards have different subdevice IDs that we could use to
- * distinguish them?
- *
- * Need some device attributes so the board type can be corrected after
- * attachment if necessary, and possibly to set other options supported by
- * manual attachment.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include "../comedi_pci.h"
-
-#include "amcc_s5933.h"
-#include "comedi_8254.h"
-
-/*
- * PCI BAR2 Register map (dev->iobase)
- */
-#define PCI9118_TIMER_BASE 0x00
-#define PCI9118_AI_FIFO_REG 0x10
-#define PCI9118_AO_REG(x) (0x10 + ((x) * 4))
-#define PCI9118_AI_STATUS_REG 0x18
-#define PCI9118_AI_STATUS_NFULL BIT(8) /* 0=FIFO full (fatal) */
-#define PCI9118_AI_STATUS_NHFULL BIT(7) /* 0=FIFO half full */
-#define PCI9118_AI_STATUS_NEPTY BIT(6) /* 0=FIFO empty */
-#define PCI9118_AI_STATUS_ACMP BIT(5) /* 1=about trigger complete */
-#define PCI9118_AI_STATUS_DTH BIT(4) /* 1=ext. digital trigger */
-#define PCI9118_AI_STATUS_BOVER BIT(3) /* 1=burst overrun (fatal) */
-#define PCI9118_AI_STATUS_ADOS BIT(2) /* 1=A/D over speed (warn) */
-#define PCI9118_AI_STATUS_ADOR BIT(1) /* 1=A/D overrun (fatal) */
-#define PCI9118_AI_STATUS_ADRDY BIT(0) /* 1=A/D ready */
-#define PCI9118_AI_CTRL_REG 0x18
-#define PCI9118_AI_CTRL_UNIP BIT(7) /* 1=unipolar */
-#define PCI9118_AI_CTRL_DIFF BIT(6) /* 1=differential inputs */
-#define PCI9118_AI_CTRL_SOFTG BIT(5) /* 1=8254 software gate */
-#define PCI9118_AI_CTRL_EXTG BIT(4) /* 1=8254 TGIN(pin 46) gate */
-#define PCI9118_AI_CTRL_EXTM BIT(3) /* 1=ext. trigger (pin 44) */
-#define PCI9118_AI_CTRL_TMRTR BIT(2) /* 1=8254 is trigger source */
-#define PCI9118_AI_CTRL_INT BIT(1) /* 1=enable interrupt */
-#define PCI9118_AI_CTRL_DMA BIT(0) /* 1=enable DMA */
-#define PCI9118_DIO_REG 0x1c
-#define PCI9118_SOFTTRG_REG 0x20
-#define PCI9118_AI_CHANLIST_REG 0x24
-#define PCI9118_AI_CHANLIST_RANGE(x) (((x) & 0x3) << 8)
-#define PCI9118_AI_CHANLIST_CHAN(x) ((x) << 0)
-#define PCI9118_AI_BURST_NUM_REG 0x28
-#define PCI9118_AI_AUTOSCAN_MODE_REG 0x2c
-#define PCI9118_AI_CFG_REG 0x30
-#define PCI9118_AI_CFG_PDTRG BIT(7) /* 1=positive trigger */
-#define PCI9118_AI_CFG_PETRG BIT(6) /* 1=positive ext. trigger */
-#define PCI9118_AI_CFG_BSSH BIT(5) /* 1=with sample & hold */
-#define PCI9118_AI_CFG_BM BIT(4) /* 1=burst mode */
-#define PCI9118_AI_CFG_BS BIT(3) /* 1=burst mode start */
-#define PCI9118_AI_CFG_PM BIT(2) /* 1=post trigger */
-#define PCI9118_AI_CFG_AM BIT(1) /* 1=about trigger */
-#define PCI9118_AI_CFG_START BIT(0) /* 1=trigger start */
-#define PCI9118_FIFO_RESET_REG 0x34
-#define PCI9118_INT_CTRL_REG 0x38
-#define PCI9118_INT_CTRL_TIMER BIT(3) /* timer interrupt */
-#define PCI9118_INT_CTRL_ABOUT BIT(2) /* about trigger complete */
-#define PCI9118_INT_CTRL_HFULL BIT(1) /* A/D FIFO half full */
-#define PCI9118_INT_CTRL_DTRG BIT(0) /* ext. digital trigger */
-
-#define START_AI_EXT 0x01 /* start measure on external trigger */
-#define STOP_AI_EXT 0x02 /* stop measure on external trigger */
-#define STOP_AI_INT 0x08 /* stop measure on internal trigger */
-
-static const struct comedi_lrange pci9118_ai_range = {
- 8, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange pci9118hg_ai_range = {
- 8, {
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.005),
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01)
- }
-};
-
-enum pci9118_boardid {
- BOARD_PCI9118DG,
- BOARD_PCI9118HG,
- BOARD_PCI9118HR,
-};
-
-struct pci9118_boardinfo {
- const char *name;
- unsigned int ai_is_16bit:1;
- unsigned int is_hg:1;
-};
-
-static const struct pci9118_boardinfo pci9118_boards[] = {
- [BOARD_PCI9118DG] = {
- .name = "pci9118dg",
- },
- [BOARD_PCI9118HG] = {
- .name = "pci9118hg",
- .is_hg = 1,
- },
- [BOARD_PCI9118HR] = {
- .name = "pci9118hr",
- .ai_is_16bit = 1,
- },
-};
-
-struct pci9118_dmabuf {
- unsigned short *virt; /* virtual address of buffer */
- dma_addr_t hw; /* hardware (bus) address of buffer */
- unsigned int size; /* size of dma buffer in bytes */
- unsigned int use_size; /* which size we may now use for transfer */
-};
-
-struct pci9118_private {
- unsigned long iobase_a; /* base+size for AMCC chip */
- unsigned int master:1;
- unsigned int dma_doublebuf:1;
- unsigned int ai_neverending:1;
- unsigned int usedma:1;
- unsigned int usemux:1;
- unsigned char ai_ctrl;
- unsigned char int_ctrl;
- unsigned char ai_cfg;
- unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
- unsigned int ai_n_realscanlen; /*
- * what we must transfer for one
- * outgoing scan include front/back adds
- */
- unsigned int ai_act_dmapos; /* position in actual real stream */
- unsigned int ai_add_front; /*
- * how many channels we must add
- * before scan to satisfy S&H?
- */
- unsigned int ai_add_back; /*
- * how many channels we must add
- * before scan to satisfy DMA?
- */
- unsigned int ai_flags;
- char ai12_startstop; /*
- * measure can start/stop
- * on external trigger
- */
- unsigned int dma_actbuf; /* which buffer is used now */
- struct pci9118_dmabuf dmabuf[2];
- int softsshdelay; /*
- * >0 use software S&H,
- * numer is requested delay in ns
- */
- unsigned char softsshsample; /*
- * polarity of S&H signal
- * in sample state
- */
- unsigned char softsshhold; /*
- * polarity of S&H signal
- * in hold state
- */
- unsigned int ai_ns_min;
-};
-
-static void pci9118_amcc_setup_dma(struct comedi_device *dev, unsigned int buf)
-{
- struct pci9118_private *devpriv = dev->private;
- struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[buf];
-
- /* set the master write address and transfer count */
- outl(dmabuf->hw, devpriv->iobase_a + AMCC_OP_REG_MWAR);
- outl(dmabuf->use_size, devpriv->iobase_a + AMCC_OP_REG_MWTC);
-}
-
-static void pci9118_amcc_dma_ena(struct comedi_device *dev, bool enable)
-{
- struct pci9118_private *devpriv = dev->private;
- unsigned int mcsr;
-
- mcsr = inl(devpriv->iobase_a + AMCC_OP_REG_MCSR);
- if (enable)
- mcsr |= RESET_A2P_FLAGS | A2P_HI_PRIORITY | EN_A2P_TRANSFERS;
- else
- mcsr &= ~EN_A2P_TRANSFERS;
- outl(mcsr, devpriv->iobase_a + AMCC_OP_REG_MCSR);
-}
-
-static void pci9118_amcc_int_ena(struct comedi_device *dev, bool enable)
-{
- struct pci9118_private *devpriv = dev->private;
- unsigned int intcsr;
-
- /* enable/disable interrupt for AMCC Incoming Mailbox 4 (32-bit) */
- intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
- if (enable)
- intcsr |= 0x1f00;
- else
- intcsr &= ~0x1f00;
- outl(intcsr, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
-}
-
-static void pci9118_ai_reset_fifo(struct comedi_device *dev)
-{
- /* writing any value resets the A/D FIFO */
- outl(0, dev->iobase + PCI9118_FIFO_RESET_REG);
-}
-
-static int pci9118_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct pci9118_private *devpriv = dev->private;
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
- int i;
-
- /* single channel scans are always ok */
- if (cmd->chanlist_len == 1)
- return 0;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- if (aref != aref0) {
- dev_err(dev->class_dev,
- "Differential and single ended inputs can't be mixed!\n");
- return -EINVAL;
- }
- if (comedi_range_is_bipolar(s, range) !=
- comedi_range_is_bipolar(s, range0)) {
- dev_err(dev->class_dev,
- "Bipolar and unipolar ranges can't be mixed!\n");
- return -EINVAL;
- }
- if (!devpriv->usemux && aref == AREF_DIFF &&
- (chan >= (s->n_chan / 2))) {
- dev_err(dev->class_dev,
- "AREF_DIFF is only available for the first 8 channels!\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static void pci9118_set_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- int n_chan, unsigned int *chanlist,
- int frontadd, int backadd)
-{
- struct pci9118_private *devpriv = dev->private;
- unsigned int chan0 = CR_CHAN(chanlist[0]);
- unsigned int range0 = CR_RANGE(chanlist[0]);
- unsigned int aref0 = CR_AREF(chanlist[0]);
- unsigned int ssh = 0x00;
- unsigned int val;
- int i;
-
- /*
- * Configure analog input based on the first chanlist entry.
- * All entries are either unipolar or bipolar and single-ended
- * or differential.
- */
- devpriv->ai_ctrl = 0;
- if (comedi_range_is_unipolar(s, range0))
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_UNIP;
- if (aref0 == AREF_DIFF)
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_DIFF;
- outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
-
- /* gods know why this sequence! */
- outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
- outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
- outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
-
- /* insert channels for S&H */
- if (frontadd) {
- val = PCI9118_AI_CHANLIST_CHAN(chan0) |
- PCI9118_AI_CHANLIST_RANGE(range0);
- ssh = devpriv->softsshsample;
- for (i = 0; i < frontadd; i++) {
- outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
- ssh = devpriv->softsshhold;
- }
- }
-
- /* store chanlist */
- for (i = 0; i < n_chan; i++) {
- unsigned int chan = CR_CHAN(chanlist[i]);
- unsigned int range = CR_RANGE(chanlist[i]);
-
- val = PCI9118_AI_CHANLIST_CHAN(chan) |
- PCI9118_AI_CHANLIST_RANGE(range);
- outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
- }
-
- /* insert channels to fit onto 32bit DMA */
- if (backadd) {
- val = PCI9118_AI_CHANLIST_CHAN(chan0) |
- PCI9118_AI_CHANLIST_RANGE(range0);
- for (i = 0; i < backadd; i++)
- outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
- }
- /* close scan queue */
- outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
- /* udelay(100); important delay, or first sample will be crippled */
-}
-
-static void pci9118_ai_mode4_switch(struct comedi_device *dev,
- unsigned int next_buf)
-{
- struct pci9118_private *devpriv = dev->private;
- struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[next_buf];
-
- devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG |
- PCI9118_AI_CFG_AM;
- outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
- comedi_8254_load(dev->pacer, 0, dmabuf->hw >> 1,
- I8254_MODE0 | I8254_BINARY);
- devpriv->ai_cfg |= PCI9118_AI_CFG_START;
- outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
-}
-
-static unsigned int pci9118_ai_samples_ready(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int n_raw_samples)
-{
- struct pci9118_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int start_pos = devpriv->ai_add_front;
- unsigned int stop_pos = start_pos + cmd->chanlist_len;
- unsigned int span_len = stop_pos + devpriv->ai_add_back;
- unsigned int dma_pos = devpriv->ai_act_dmapos;
- unsigned int whole_spans, n_samples, x;
-
- if (span_len == cmd->chanlist_len)
- return n_raw_samples; /* use all samples */
-
- /*
- * Not all samples are to be used. Buffer contents consist of a
- * possibly non-whole number of spans and a region of each span
- * is to be used.
- *
- * Account for samples in whole number of spans.
- */
- whole_spans = n_raw_samples / span_len;
- n_samples = whole_spans * cmd->chanlist_len;
- n_raw_samples -= whole_spans * span_len;
-
- /*
- * Deal with remaining samples which could overlap up to two spans.
- */
- while (n_raw_samples) {
- if (dma_pos < start_pos) {
- /* Skip samples before start position. */
- x = start_pos - dma_pos;
- if (x > n_raw_samples)
- x = n_raw_samples;
- dma_pos += x;
- n_raw_samples -= x;
- if (!n_raw_samples)
- break;
- }
- if (dma_pos < stop_pos) {
- /* Include samples before stop position. */
- x = stop_pos - dma_pos;
- if (x > n_raw_samples)
- x = n_raw_samples;
- n_samples += x;
- dma_pos += x;
- n_raw_samples -= x;
- }
- /* Advance to next span. */
- start_pos += span_len;
- stop_pos += span_len;
- }
- return n_samples;
-}
-
-static void pci9118_ai_dma_xfer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned short *dma_buffer,
- unsigned int n_raw_samples)
-{
- struct pci9118_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int start_pos = devpriv->ai_add_front;
- unsigned int stop_pos = start_pos + cmd->chanlist_len;
- unsigned int span_len = stop_pos + devpriv->ai_add_back;
- unsigned int dma_pos = devpriv->ai_act_dmapos;
- unsigned int x;
-
- if (span_len == cmd->chanlist_len) {
- /* All samples are to be copied. */
- comedi_buf_write_samples(s, dma_buffer, n_raw_samples);
- dma_pos += n_raw_samples;
- } else {
- /*
- * Not all samples are to be copied. Buffer contents consist
- * of a possibly non-whole number of spans and a region of
- * each span is to be copied.
- */
- while (n_raw_samples) {
- if (dma_pos < start_pos) {
- /* Skip samples before start position. */
- x = start_pos - dma_pos;
- if (x > n_raw_samples)
- x = n_raw_samples;
- dma_pos += x;
- n_raw_samples -= x;
- if (!n_raw_samples)
- break;
- }
- if (dma_pos < stop_pos) {
- /* Copy samples before stop position. */
- x = stop_pos - dma_pos;
- if (x > n_raw_samples)
- x = n_raw_samples;
- comedi_buf_write_samples(s, dma_buffer, x);
- dma_pos += x;
- n_raw_samples -= x;
- }
- /* Advance to next span. */
- start_pos += span_len;
- stop_pos += span_len;
- }
- }
- /* Update position in span for next time. */
- devpriv->ai_act_dmapos = dma_pos % span_len;
-}
-
-static void pci9118_exttrg_enable(struct comedi_device *dev, bool enable)
-{
- struct pci9118_private *devpriv = dev->private;
-
- if (enable)
- devpriv->int_ctrl |= PCI9118_INT_CTRL_DTRG;
- else
- devpriv->int_ctrl &= ~PCI9118_INT_CTRL_DTRG;
- outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
-
- if (devpriv->int_ctrl)
- pci9118_amcc_int_ena(dev, true);
- else
- pci9118_amcc_int_ena(dev, false);
-}
-
-static void pci9118_calc_divisors(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *tim1, unsigned int *tim2,
- unsigned int flags, int chans,
- unsigned int *div1, unsigned int *div2,
- unsigned int chnsshfront)
-{
- struct comedi_8254 *pacer = dev->pacer;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- *div1 = *tim2 / pacer->osc_base; /* convert timer (burst) */
- *div2 = *tim1 / pacer->osc_base; /* scan timer */
- *div2 = *div2 / *div1; /* major timer is c1*c2 */
- if (*div2 < chans)
- *div2 = chans;
-
- *tim2 = *div1 * pacer->osc_base; /* real convert timer */
-
- if (cmd->convert_src == TRIG_NOW && !chnsshfront) {
- /* use BSSH signal */
- if (*div2 < (chans + 2))
- *div2 = chans + 2;
- }
-
- *tim1 = *div1 * *div2 * pacer->osc_base;
-}
-
-static void pci9118_start_pacer(struct comedi_device *dev, int mode)
-{
- if (mode == 1 || mode == 2 || mode == 4)
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
-}
-
-static int pci9118_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci9118_private *devpriv = dev->private;
-
- if (devpriv->usedma)
- pci9118_amcc_dma_ena(dev, false);
- pci9118_exttrg_enable(dev, false);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
- /* set default config (disable burst and triggers) */
- devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
- outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
- /* reset acquisition control */
- devpriv->ai_ctrl = 0;
- outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
- outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
- /* reset scan queue */
- outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
- outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
- pci9118_ai_reset_fifo(dev);
-
- devpriv->int_ctrl = 0;
- outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
- pci9118_amcc_int_ena(dev, false);
-
- devpriv->ai_do = 0;
- devpriv->usedma = 0;
-
- devpriv->ai_act_dmapos = 0;
- s->async->inttrig = NULL;
- devpriv->ai_neverending = 0;
- devpriv->dma_actbuf = 0;
-
- return 0;
-}
-
-static void pci9118_ai_munge(struct comedi_device *dev,
- struct comedi_subdevice *s, void *data,
- unsigned int num_bytes,
- unsigned int start_chan_index)
-{
- struct pci9118_private *devpriv = dev->private;
- unsigned short *array = data;
- unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
- unsigned int i;
- __be16 *barray = data;
-
- for (i = 0; i < num_samples; i++) {
- if (devpriv->usedma)
- array[i] = be16_to_cpu(barray[i]);
- if (s->maxdata == 0xffff)
- array[i] ^= 0x8000;
- else
- array[i] = (array[i] >> 4) & 0x0fff;
- }
-}
-
-static void pci9118_ai_get_onesample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci9118_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned short sampl;
-
- sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG);
-
- comedi_buf_write_samples(s, &sampl, 1);
-
- if (!devpriv->ai_neverending) {
- if (s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
- }
-}
-
-static void pci9118_ai_get_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci9118_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[devpriv->dma_actbuf];
- unsigned int n_all = comedi_bytes_to_samples(s, dmabuf->use_size);
- unsigned int n_valid;
- bool more_dma;
-
- /* determine whether more DMA buffers to do after this one */
- n_valid = pci9118_ai_samples_ready(dev, s, n_all);
- more_dma = n_valid < comedi_nsamples_left(s, n_valid + 1);
-
- /* switch DMA buffers and restart DMA if double buffering */
- if (more_dma && devpriv->dma_doublebuf) {
- devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
- pci9118_amcc_setup_dma(dev, devpriv->dma_actbuf);
- if (devpriv->ai_do == 4)
- pci9118_ai_mode4_switch(dev, devpriv->dma_actbuf);
- }
-
- if (n_all)
- pci9118_ai_dma_xfer(dev, s, dmabuf->virt, n_all);
-
- if (!devpriv->ai_neverending) {
- if (s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
- }
-
- if (s->async->events & COMEDI_CB_CANCEL_MASK)
- more_dma = false;
-
- /* restart DMA if not double buffering */
- if (more_dma && !devpriv->dma_doublebuf) {
- pci9118_amcc_setup_dma(dev, 0);
- if (devpriv->ai_do == 4)
- pci9118_ai_mode4_switch(dev, 0);
- }
-}
-
-static irqreturn_t pci9118_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct pci9118_private *devpriv = dev->private;
- unsigned int intsrc; /* IRQ reasons from card */
- unsigned int intcsr; /* INT register from AMCC chip */
- unsigned int adstat; /* STATUS register */
-
- if (!dev->attached)
- return IRQ_NONE;
-
- intsrc = inl(dev->iobase + PCI9118_INT_CTRL_REG) & 0xf;
- intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
-
- if (!intsrc && !(intcsr & ANY_S593X_INT))
- return IRQ_NONE;
-
- outl(intcsr | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
-
- if (intcsr & MASTER_ABORT_INT) {
- dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
- s->async->events |= COMEDI_CB_ERROR;
- goto interrupt_exit;
- }
-
- if (intcsr & TARGET_ABORT_INT) {
- dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
- s->async->events |= COMEDI_CB_ERROR;
- goto interrupt_exit;
- }
-
- adstat = inl(dev->iobase + PCI9118_AI_STATUS_REG);
- if ((adstat & PCI9118_AI_STATUS_NFULL) == 0) {
- dev_err(dev->class_dev,
- "A/D FIFO Full status (Fatal Error!)\n");
- s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
- goto interrupt_exit;
- }
- if (adstat & PCI9118_AI_STATUS_BOVER) {
- dev_err(dev->class_dev,
- "A/D Burst Mode Overrun Status (Fatal Error!)\n");
- s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
- goto interrupt_exit;
- }
- if (adstat & PCI9118_AI_STATUS_ADOS) {
- dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
- s->async->events |= COMEDI_CB_ERROR;
- goto interrupt_exit;
- }
- if (adstat & PCI9118_AI_STATUS_ADOR) {
- dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
- s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
- goto interrupt_exit;
- }
-
- if (!devpriv->ai_do)
- return IRQ_HANDLED;
-
- if (devpriv->ai12_startstop) {
- if ((adstat & PCI9118_AI_STATUS_DTH) &&
- (intsrc & PCI9118_INT_CTRL_DTRG)) {
- /* start/stop of measure */
- if (devpriv->ai12_startstop & START_AI_EXT) {
- /* deactivate EXT trigger */
- devpriv->ai12_startstop &= ~START_AI_EXT;
- if (!(devpriv->ai12_startstop & STOP_AI_EXT))
- pci9118_exttrg_enable(dev, false);
-
- /* start pacer */
- pci9118_start_pacer(dev, devpriv->ai_do);
- outl(devpriv->ai_ctrl,
- dev->iobase + PCI9118_AI_CTRL_REG);
- } else if (devpriv->ai12_startstop & STOP_AI_EXT) {
- /* deactivate EXT trigger */
- devpriv->ai12_startstop &= ~STOP_AI_EXT;
- pci9118_exttrg_enable(dev, false);
-
- /* on next interrupt measure will stop */
- devpriv->ai_neverending = 0;
- }
- }
- }
-
- if (devpriv->usedma)
- pci9118_ai_get_dma(dev, s);
- else
- pci9118_ai_get_onesample(dev, s);
-
-interrupt_exit:
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static void pci9118_ai_cmd_start(struct comedi_device *dev)
-{
- struct pci9118_private *devpriv = dev->private;
-
- outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
- outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
- if (devpriv->ai_do != 3) {
- pci9118_start_pacer(dev, devpriv->ai_do);
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_SOFTG;
- }
- outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
-}
-
-static int pci9118_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- s->async->inttrig = NULL;
- pci9118_ai_cmd_start(dev);
-
- return 1;
-}
-
-static int pci9118_ai_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci9118_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- struct pci9118_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
- struct pci9118_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
- unsigned int dmalen0 = dmabuf0->size;
- unsigned int dmalen1 = dmabuf1->size;
- unsigned int scan_bytes = devpriv->ai_n_realscanlen *
- comedi_bytes_per_sample(s);
-
- /* isn't output buff smaller that our DMA buff? */
- if (dmalen0 > s->async->prealloc_bufsz) {
- /* align to 32bit down */
- dmalen0 = s->async->prealloc_bufsz & ~3L;
- }
- if (dmalen1 > s->async->prealloc_bufsz) {
- /* align to 32bit down */
- dmalen1 = s->async->prealloc_bufsz & ~3L;
- }
-
- /* we want wake up every scan? */
- if (devpriv->ai_flags & CMDF_WAKE_EOS) {
- if (dmalen0 < scan_bytes) {
- /* uff, too short DMA buffer, disable EOS support! */
- devpriv->ai_flags &= (~CMDF_WAKE_EOS);
- dev_info(dev->class_dev,
- "WAR: DMA0 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
- dmalen0, scan_bytes);
- } else {
- /* short first DMA buffer to one scan */
- dmalen0 = scan_bytes;
- if (dmalen0 < 4) {
- dev_info(dev->class_dev,
- "ERR: DMA0 buf len bug? (%d<4)\n",
- dmalen0);
- dmalen0 = 4;
- }
- }
- }
- if (devpriv->ai_flags & CMDF_WAKE_EOS) {
- if (dmalen1 < scan_bytes) {
- /* uff, too short DMA buffer, disable EOS support! */
- devpriv->ai_flags &= (~CMDF_WAKE_EOS);
- dev_info(dev->class_dev,
- "WAR: DMA1 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
- dmalen1, scan_bytes);
- } else {
- /* short second DMA buffer to one scan */
- dmalen1 = scan_bytes;
- if (dmalen1 < 4) {
- dev_info(dev->class_dev,
- "ERR: DMA1 buf len bug? (%d<4)\n",
- dmalen1);
- dmalen1 = 4;
- }
- }
- }
-
- /* transfer without CMDF_WAKE_EOS */
- if (!(devpriv->ai_flags & CMDF_WAKE_EOS)) {
- unsigned int tmp;
-
- /* if it's possible then align DMA buffers to length of scan */
- tmp = dmalen0;
- dmalen0 = (dmalen0 / scan_bytes) * scan_bytes;
- dmalen0 &= ~3L;
- if (!dmalen0)
- dmalen0 = tmp; /* uff. very long scan? */
- tmp = dmalen1;
- dmalen1 = (dmalen1 / scan_bytes) * scan_bytes;
- dmalen1 &= ~3L;
- if (!dmalen1)
- dmalen1 = tmp; /* uff. very long scan? */
- /*
- * if measure isn't neverending then test, if it fits whole
- * into one or two DMA buffers
- */
- if (!devpriv->ai_neverending) {
- unsigned long long scanlen;
-
- scanlen = (unsigned long long)scan_bytes *
- cmd->stop_arg;
-
- /* fits whole measure into one DMA buffer? */
- if (dmalen0 > scanlen) {
- dmalen0 = scanlen;
- dmalen0 &= ~3L;
- } else {
- /* fits whole measure into two DMA buffer? */
- if (dmalen1 > (scanlen - dmalen0)) {
- dmalen1 = scanlen - dmalen0;
- dmalen1 &= ~3L;
- }
- }
- }
- }
-
- /* these DMA buffer size will be used */
- devpriv->dma_actbuf = 0;
- dmabuf0->use_size = dmalen0;
- dmabuf1->use_size = dmalen1;
-
- pci9118_amcc_dma_ena(dev, false);
- pci9118_amcc_setup_dma(dev, 0);
- /* init DMA transfer */
- outl(0x00000000 | AINT_WRITE_COMPL,
- devpriv->iobase_a + AMCC_OP_REG_INTCSR);
-/* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
- pci9118_amcc_dma_ena(dev, true);
- outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
- devpriv->iobase_a + AMCC_OP_REG_INTCSR);
- /* allow bus mastering */
-
- return 0;
-}
-
-static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pci9118_private *devpriv = dev->private;
- struct comedi_8254 *pacer = dev->pacer;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int addchans = 0;
- unsigned int scanlen;
-
- devpriv->ai12_startstop = 0;
- devpriv->ai_flags = cmd->flags;
- devpriv->ai_add_front = 0;
- devpriv->ai_add_back = 0;
-
- /* prepare for start/stop conditions */
- if (cmd->start_src == TRIG_EXT)
- devpriv->ai12_startstop |= START_AI_EXT;
- if (cmd->stop_src == TRIG_EXT) {
- devpriv->ai_neverending = 1;
- devpriv->ai12_startstop |= STOP_AI_EXT;
- }
- if (cmd->stop_src == TRIG_NONE)
- devpriv->ai_neverending = 1;
- if (cmd->stop_src == TRIG_COUNT)
- devpriv->ai_neverending = 0;
-
- /*
- * use additional sample at end of every scan
- * to satisty DMA 32 bit transfer?
- */
- devpriv->ai_add_front = 0;
- devpriv->ai_add_back = 0;
- if (devpriv->master) {
- devpriv->usedma = 1;
- if ((cmd->flags & CMDF_WAKE_EOS) &&
- (cmd->scan_end_arg == 1)) {
- if (cmd->convert_src == TRIG_NOW)
- devpriv->ai_add_back = 1;
- if (cmd->convert_src == TRIG_TIMER) {
- devpriv->usedma = 0;
- /*
- * use INT transfer if scanlist
- * have only one channel
- */
- }
- }
- if ((cmd->flags & CMDF_WAKE_EOS) &&
- (cmd->scan_end_arg & 1) &&
- (cmd->scan_end_arg > 1)) {
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- devpriv->usedma = 0;
- /*
- * XXX maybe can be corrected to use 16 bit DMA
- */
- } else { /*
- * well, we must insert one sample
- * to end of EOS to meet 32 bit transfer
- */
- devpriv->ai_add_back = 1;
- }
- }
- } else { /* interrupt transfer don't need any correction */
- devpriv->usedma = 0;
- }
-
- /*
- * we need software S&H signal?
- * It adds two samples before every scan as minimum
- */
- if (cmd->convert_src == TRIG_NOW && devpriv->softsshdelay) {
- devpriv->ai_add_front = 2;
- if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
- /* move it to front */
- devpriv->ai_add_front++;
- devpriv->ai_add_back = 0;
- }
- if (cmd->convert_arg < devpriv->ai_ns_min)
- cmd->convert_arg = devpriv->ai_ns_min;
- addchans = devpriv->softsshdelay / cmd->convert_arg;
- if (devpriv->softsshdelay % cmd->convert_arg)
- addchans++;
- if (addchans > (devpriv->ai_add_front - 1)) {
- /* uff, still short */
- devpriv->ai_add_front = addchans + 1;
- if (devpriv->usedma == 1)
- if ((devpriv->ai_add_front +
- cmd->chanlist_len +
- devpriv->ai_add_back) & 1)
- devpriv->ai_add_front++;
- /* round up to 32 bit */
- }
- }
- /* well, we now know what must be all added */
- scanlen = devpriv->ai_add_front + cmd->chanlist_len +
- devpriv->ai_add_back;
- /*
- * what we must take from card in real to have cmd->scan_end_arg
- * on output?
- */
- devpriv->ai_n_realscanlen = scanlen *
- (cmd->scan_end_arg / cmd->chanlist_len);
-
- if (scanlen > s->len_chanlist) {
- dev_err(dev->class_dev,
- "range/channel list is too long for actual configuration!\n");
- return -EINVAL;
- }
-
- /*
- * Configure analog input and load the chanlist.
- * The acquisition control bits are enabled later.
- */
- pci9118_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist,
- devpriv->ai_add_front, devpriv->ai_add_back);
-
- /* Determine acquisition mode and calculate timing */
- devpriv->ai_do = 0;
- if (cmd->scan_begin_src != TRIG_TIMER &&
- cmd->convert_src == TRIG_TIMER) {
- /* cascaded timers 1 and 2 are used for convert timing */
- if (cmd->scan_begin_src == TRIG_EXT)
- devpriv->ai_do = 4;
- else
- devpriv->ai_do = 1;
-
- comedi_8254_cascade_ns_to_timer(pacer, &cmd->convert_arg,
- devpriv->ai_flags &
- CMDF_ROUND_NEAREST);
- comedi_8254_update_divisors(pacer);
-
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
-
- if (!devpriv->usedma) {
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_INT;
- devpriv->int_ctrl |= PCI9118_INT_CTRL_TIMER;
- }
-
- if (cmd->scan_begin_src == TRIG_EXT) {
- struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[0];
-
- devpriv->ai_cfg |= PCI9118_AI_CFG_AM;
- outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
- comedi_8254_load(pacer, 0, dmabuf->hw >> 1,
- I8254_MODE0 | I8254_BINARY);
- devpriv->ai_cfg |= PCI9118_AI_CFG_START;
- }
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER &&
- cmd->convert_src != TRIG_EXT) {
- if (!devpriv->usedma) {
- dev_err(dev->class_dev,
- "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!\n");
- return -EIO;
- }
-
- /* double timed action */
- devpriv->ai_do = 2;
-
- pci9118_calc_divisors(dev, s,
- &cmd->scan_begin_arg, &cmd->convert_arg,
- devpriv->ai_flags,
- devpriv->ai_n_realscanlen,
- &pacer->divisor1,
- &pacer->divisor2,
- devpriv->ai_add_front);
-
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
- devpriv->ai_cfg |= PCI9118_AI_CFG_BM | PCI9118_AI_CFG_BS;
- if (cmd->convert_src == TRIG_NOW && !devpriv->softsshdelay)
- devpriv->ai_cfg |= PCI9118_AI_CFG_BSSH;
- outl(devpriv->ai_n_realscanlen,
- dev->iobase + PCI9118_AI_BURST_NUM_REG);
- }
-
- if (cmd->scan_begin_src == TRIG_FOLLOW &&
- cmd->convert_src == TRIG_EXT) {
- /* external trigger conversion */
- devpriv->ai_do = 3;
-
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_EXTM;
- }
-
- if (devpriv->ai_do == 0) {
- dev_err(dev->class_dev,
- "Unable to determine acquisition mode! BUG in (*do_cmdtest)?\n");
- return -EINVAL;
- }
-
- if (devpriv->usedma)
- devpriv->ai_ctrl |= PCI9118_AI_CTRL_DMA;
-
- /* set default config (disable burst and triggers) */
- devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
- outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
- udelay(1);
- pci9118_ai_reset_fifo(dev);
-
- /* clear A/D and INT status registers */
- inl(dev->iobase + PCI9118_AI_STATUS_REG);
- inl(dev->iobase + PCI9118_INT_CTRL_REG);
-
- devpriv->ai_act_dmapos = 0;
-
- if (devpriv->usedma) {
- pci9118_ai_setup_dma(dev, s);
-
- outl(0x02000000 | AINT_WRITE_COMPL,
- devpriv->iobase_a + AMCC_OP_REG_INTCSR);
- } else {
- pci9118_amcc_int_ena(dev, true);
- }
-
- /* start async command now or wait for internal trigger */
- if (cmd->start_src == TRIG_NOW)
- pci9118_ai_cmd_start(dev);
- else if (cmd->start_src == TRIG_INT)
- s->async->inttrig = pci9118_ai_inttrig;
-
- /* enable external trigger for command start/stop */
- if (cmd->start_src == TRIG_EXT || cmd->stop_src == TRIG_EXT)
- pci9118_exttrg_enable(dev, true);
-
- return 0;
-}
-
-static int pci9118_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct pci9118_private *devpriv = dev->private;
- int err = 0;
- unsigned int flags;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src,
- TRIG_NOW | TRIG_EXT | TRIG_INT);
-
- flags = TRIG_FOLLOW;
- if (devpriv->master)
- flags |= TRIG_TIMER | TRIG_EXT;
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, flags);
-
- flags = TRIG_TIMER | TRIG_EXT;
- if (devpriv->master)
- flags |= TRIG_NOW;
- err |= comedi_check_trigger_src(&cmd->convert_src, flags);
-
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src,
- TRIG_COUNT | TRIG_NONE | TRIG_EXT);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
- err |= -EINVAL;
-
- if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
- (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW))))
- err |= -EINVAL;
-
- if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
- (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT))))
- err |= -EINVAL;
-
- if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- case TRIG_EXT:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_INT:
- /* start_arg is the internal trigger (any value) */
- break;
- }
-
- if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if ((cmd->scan_begin_src == TRIG_TIMER) &&
- (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
- cmd->scan_begin_src = TRIG_FOLLOW;
- cmd->convert_arg = cmd->scan_begin_arg;
- cmd->scan_begin_arg = 0;
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- devpriv->ai_ns_min);
- }
-
- if (cmd->scan_begin_src == TRIG_EXT) {
- if (cmd->scan_begin_arg) {
- cmd->scan_begin_arg = 0;
- err |= -EINVAL;
- err |= comedi_check_trigger_arg_max(&cmd->scan_end_arg,
- 65535);
- }
- }
-
- if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- devpriv->ai_ns_min);
- }
-
- if (cmd->convert_src == TRIG_EXT)
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
-
- err |= comedi_check_trigger_arg_min(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if ((cmd->scan_end_arg % cmd->chanlist_len)) {
- cmd->scan_end_arg =
- cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
- err |= -EINVAL;
- }
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
- arg = cmd->convert_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-
- if (cmd->scan_begin_src == TRIG_TIMER &&
- cmd->convert_src == TRIG_NOW) {
- if (cmd->convert_arg == 0) {
- arg = devpriv->ai_ns_min *
- (cmd->scan_end_arg + 2);
- } else {
- arg = cmd->convert_arg * cmd->chanlist_len;
- }
- err |= comedi_check_trigger_arg_min(
- &cmd->scan_begin_arg, arg);
- }
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
-
- if (cmd->chanlist)
- err |= pci9118_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int pci9118_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inl(dev->iobase + PCI9118_AI_STATUS_REG);
- if (status & PCI9118_AI_STATUS_ADRDY)
- return 0;
- return -EBUSY;
-}
-
-static void pci9118_ai_start_conv(struct comedi_device *dev)
-{
- /* writing any value triggers an A/D conversion */
- outl(0, dev->iobase + PCI9118_SOFTTRG_REG);
-}
-
-static int pci9118_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pci9118_private *devpriv = dev->private;
- unsigned int val;
- int ret;
- int i;
-
- /*
- * Configure analog input based on the chanspec.
- * Acqusition is software controlled without interrupts.
- */
- pci9118_set_chanlist(dev, s, 1, &insn->chanspec, 0, 0);
-
- /* set default config (disable burst and triggers) */
- devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
- outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
-
- pci9118_ai_reset_fifo(dev);
-
- for (i = 0; i < insn->n; i++) {
- pci9118_ai_start_conv(dev);
-
- ret = comedi_timeout(dev, s, insn, pci9118_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inl(dev->iobase + PCI9118_AI_FIFO_REG);
- if (s->maxdata == 0xffff)
- data[i] = (val & 0xffff) ^ 0x8000;
- else
- data[i] = (val >> 4) & 0xfff;
- }
-
- return insn->n;
-}
-
-static int pci9118_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outl(val, dev->iobase + PCI9118_AO_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pci9118_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- /*
- * The digital inputs and outputs share the read register.
- * bits [7:4] are the digital outputs
- * bits [3:0] are the digital inputs
- */
- data[1] = inl(dev->iobase + PCI9118_DIO_REG) & 0xf;
-
- return insn->n;
-}
-
-static int pci9118_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- /*
- * The digital outputs are set with the same register that
- * the digital inputs and outputs are read from. But the
- * outputs are set with bits [3:0] so we can simply write
- * the s->state to set them.
- */
- if (comedi_dio_update_state(s, data))
- outl(s->state, dev->iobase + PCI9118_DIO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void pci9118_reset(struct comedi_device *dev)
-{
- /* reset analog input subsystem */
- outl(0, dev->iobase + PCI9118_INT_CTRL_REG);
- outl(0, dev->iobase + PCI9118_AI_CTRL_REG);
- outl(0, dev->iobase + PCI9118_AI_CFG_REG);
- pci9118_ai_reset_fifo(dev);
-
- /* clear any pending interrupts and status */
- inl(dev->iobase + PCI9118_INT_CTRL_REG);
- inl(dev->iobase + PCI9118_AI_STATUS_REG);
-
- /* reset DMA and scan queue */
- outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
- outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
- outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
-
- /* reset analog outputs to 0V */
- outl(2047, dev->iobase + PCI9118_AO_REG(0));
- outl(2047, dev->iobase + PCI9118_AO_REG(1));
-}
-
-static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct pci_dev *pcidev = NULL;
- int bus = it->options[0];
- int slot = it->options[1];
-
- for_each_pci_dev(pcidev) {
- if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
- continue;
- if (pcidev->device != 0x80d9)
- continue;
- if (bus || slot) {
- /* requested particular bus/slot */
- if (pcidev->bus->number != bus ||
- PCI_SLOT(pcidev->devfn) != slot)
- continue;
- }
- return pcidev;
- }
- dev_err(dev->class_dev,
- "no supported board found! (req. bus/slot : %d/%d)\n",
- bus, slot);
- return NULL;
-}
-
-static void pci9118_alloc_dma(struct comedi_device *dev)
-{
- struct pci9118_private *devpriv = dev->private;
- struct pci9118_dmabuf *dmabuf;
- int order;
- int i;
-
- for (i = 0; i < 2; i++) {
- dmabuf = &devpriv->dmabuf[i];
- for (order = 2; order >= 0; order--) {
- dmabuf->virt =
- dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order,
- &dmabuf->hw, GFP_KERNEL);
- if (dmabuf->virt)
- break;
- }
- if (!dmabuf->virt)
- break;
- dmabuf->size = PAGE_SIZE << order;
-
- if (i == 0)
- devpriv->master = 1;
- if (i == 1)
- devpriv->dma_doublebuf = 1;
- }
-}
-
-static void pci9118_free_dma(struct comedi_device *dev)
-{
- struct pci9118_private *devpriv = dev->private;
- struct pci9118_dmabuf *dmabuf;
- int i;
-
- if (!devpriv)
- return;
-
- for (i = 0; i < 2; i++) {
- dmabuf = &devpriv->dmabuf[i];
- if (dmabuf->virt) {
- dma_free_coherent(dev->hw_dev, dmabuf->size,
- dmabuf->virt, dmabuf->hw);
- }
- }
-}
-
-static int pci9118_common_attach(struct comedi_device *dev,
- int ext_mux, int softsshdelay)
-{
- const struct pci9118_boardinfo *board = dev->board_ptr;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct pci9118_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
- int i;
- u16 u16w;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- pci_set_master(pcidev);
-
- devpriv->iobase_a = pci_resource_start(pcidev, 0);
- dev->iobase = pci_resource_start(pcidev, 2);
-
- dev->pacer = comedi_8254_init(dev->iobase + PCI9118_TIMER_BASE,
- I8254_OSC_BASE_4MHZ, I8254_IO32, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- pci9118_reset(dev);
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, pci9118_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0) {
- dev->irq = pcidev->irq;
-
- pci9118_alloc_dma(dev);
- }
- }
-
- if (ext_mux > 0) {
- if (ext_mux > 256)
- ext_mux = 256; /* max 256 channels! */
- if (softsshdelay > 0)
- if (ext_mux > 128)
- ext_mux = 128;
- devpriv->usemux = 1;
- } else {
- devpriv->usemux = 0;
- }
-
- if (softsshdelay < 0) {
- /* select sample&hold signal polarity */
- devpriv->softsshdelay = -softsshdelay;
- devpriv->softsshsample = 0x80;
- devpriv->softsshhold = 0x00;
- } else {
- devpriv->softsshdelay = softsshdelay;
- devpriv->softsshsample = 0x00;
- devpriv->softsshhold = 0x80;
- }
-
- pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
- pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
- /* Enable parity check for parity error */
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
- s->n_chan = (devpriv->usemux) ? ext_mux : 16;
- s->maxdata = board->ai_is_16bit ? 0xffff : 0x0fff;
- s->range_table = board->is_hg ? &pci9118hg_ai_range
- : &pci9118_ai_range;
- s->insn_read = pci9118_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 255;
- s->do_cmdtest = pci9118_ai_cmdtest;
- s->do_cmd = pci9118_ai_cmd;
- s->cancel = pci9118_ai_cancel;
- s->munge = pci9118_ai_munge;
- }
-
- if (s->maxdata == 0xffff) {
- /*
- * 16-bit samples are from an ADS7805 A/D converter.
- * Minimum sampling rate is 10us.
- */
- devpriv->ai_ns_min = 10000;
- } else {
- /*
- * 12-bit samples are from an ADS7800 A/D converter.
- * Minimum sampling rate is 3us.
- */
- devpriv->ai_ns_min = 3000;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &range_bipolar10;
- s->insn_write = pci9118_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* the analog outputs were reset to 0V, make the readback match */
- for (i = 0; i < s->n_chan; i++)
- s->readback[i] = 2047;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci9118_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci9118_do_insn_bits;
-
- /* get the current state of the digital outputs */
- s->state = inl(dev->iobase + PCI9118_DIO_REG) >> 4;
-
- return 0;
-}
-
-static int pci9118_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct pci_dev *pcidev;
- int ext_mux, softsshdelay;
-
- ext_mux = it->options[2];
- softsshdelay = it->options[4];
-
- pcidev = pci9118_find_pci(dev, it);
- if (!pcidev)
- return -EIO;
- comedi_set_hw_dev(dev, &pcidev->dev);
-
- return pci9118_common_attach(dev, ext_mux, softsshdelay);
-}
-
-static int pci9118_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct pci9118_boardinfo *board = NULL;
-
- if (context < ARRAY_SIZE(pci9118_boards))
- board = &pci9118_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- /*
- * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
- * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
- */
- pci_dev_get(pcidev);
- /* no external mux, no sample-hold delay */
- return pci9118_common_attach(dev, 0, 0);
-}
-
-static void pci9118_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (dev->iobase)
- pci9118_reset(dev);
- comedi_pci_detach(dev);
- pci9118_free_dma(dev);
- pci_dev_put(pcidev);
-}
-
-static struct comedi_driver adl_pci9118_driver = {
- .driver_name = "adl_pci9118",
- .module = THIS_MODULE,
- .attach = pci9118_attach,
- .auto_attach = pci9118_auto_attach,
- .detach = pci9118_detach,
- .num_names = ARRAY_SIZE(pci9118_boards),
- .board_name = &pci9118_boards[0].name,
- .offset = sizeof(struct pci9118_boardinfo),
-};
-
-static int adl_pci9118_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adl_pci9118_driver,
- id->driver_data);
-}
-
-/* FIXME: All the supported board types have the same device ID! */
-static const struct pci_device_id adl_pci9118_pci_table[] = {
- { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118DG },
-/* { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HG }, */
-/* { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HR }, */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
-
-static struct pci_driver adl_pci9118_pci_driver = {
- .name = "adl_pci9118",
- .id_table = adl_pci9118_pci_table,
- .probe = adl_pci9118_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
deleted file mode 100644
index d719f76709ef..000000000000
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ /dev/null
@@ -1,243 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * adq12b.c
- * Driver for MicroAxial ADQ12-B data acquisition and control card
- * written by jeremy theler <thelerg@ib.cnea.gov.ar>
- * instituto balseiro
- * commission nacional de energia atomica
- * universidad nacional de cuyo
- * argentina
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: adq12b
- * Description: Driver for MicroAxial ADQ12-B data acquisition and control card
- * Devices: [MicroAxial] ADQ12-B (adq12b)
- * Author: jeremy theler <thelerg@ib.cnea.gov.ar>
- * Updated: Thu, 21 Feb 2008 02:56:27 -0300
- * Status: works
- *
- * Configuration options:
- * [0] - I/O base address (set with hardware jumpers)
- * address jumper JADR
- * 0x300 1 (factory default)
- * 0x320 2
- * 0x340 3
- * 0x360 4
- * 0x380 5
- * 0x3A0 6
- * [1] - Analog Input unipolar/bipolar selection
- * selection option JUB
- * bipolar 0 2-3 (factory default)
- * unipolar 1 1-2
- * [2] - Analog Input single-ended/differential selection
- * selection option JCHA JCHB
- * single-ended 0 1-2 1-2 (factory default)
- * differential 1 2-3 2-3
- *
- * Driver for the acquisition card ADQ12-B (without any add-on).
- *
- * - Analog input is subdevice 0 (16 channels single-ended or 8 differential)
- * - Digital input is subdevice 1 (5 channels)
- * - Digital output is subdevice 1 (8 channels)
- * - The PACER is not supported in this version
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedidev.h"
-
-/* address scheme (page 2.17 of the manual) */
-#define ADQ12B_CTREG 0x00
-#define ADQ12B_CTREG_MSKP BIT(7) /* enable pacer interrupt */
-#define ADQ12B_CTREG_GTP BIT(6) /* enable pacer */
-#define ADQ12B_CTREG_RANGE(x) ((x) << 4)
-#define ADQ12B_CTREG_CHAN(x) ((x) << 0)
-#define ADQ12B_STINR 0x00
-#define ADQ12B_STINR_OUT2 BIT(7) /* timer 2 output state */
-#define ADQ12B_STINR_OUTP BIT(6) /* pacer output state */
-#define ADQ12B_STINR_EOC BIT(5) /* A/D end-of-conversion */
-#define ADQ12B_STINR_IN_MASK (0x1f << 0)
-#define ADQ12B_OUTBR 0x04
-#define ADQ12B_ADLOW 0x08
-#define ADQ12B_ADHIG 0x09
-#define ADQ12B_TIMER_BASE 0x0c
-
-/* available ranges through the PGA gains */
-static const struct comedi_lrange range_adq12b_ai_bipolar = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- BIP_RANGE(0.5)
- }
-};
-
-static const struct comedi_lrange range_adq12b_ai_unipolar = {
- 4, {
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5)
- }
-};
-
-struct adq12b_private {
- unsigned int last_ctreg;
-};
-
-static int adq12b_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + ADQ12B_STINR);
- if (status & ADQ12B_STINR_EOC)
- return 0;
- return -EBUSY;
-}
-
-static int adq12b_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct adq12b_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- int ret;
- int i;
-
- /* change channel and range only if it is different from the previous */
- val = ADQ12B_CTREG_RANGE(range) | ADQ12B_CTREG_CHAN(chan);
- if (val != devpriv->last_ctreg) {
- outb(val, dev->iobase + ADQ12B_CTREG);
- devpriv->last_ctreg = val;
- usleep_range(50, 100); /* wait for the mux to settle */
- }
-
- val = inb(dev->iobase + ADQ12B_ADLOW); /* trigger A/D */
-
- for (i = 0; i < insn->n; i++) {
- ret = comedi_timeout(dev, s, insn, adq12b_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inb(dev->iobase + ADQ12B_ADHIG) << 8;
- val |= inb(dev->iobase + ADQ12B_ADLOW); /* retriggers A/D */
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int adq12b_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- /* only bits 0-4 have information about digital inputs */
- data[1] = (inb(dev->iobase + ADQ12B_STINR) & ADQ12B_STINR_IN_MASK);
-
- return insn->n;
-}
-
-static int adq12b_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
- unsigned int chan;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- for (chan = 0; chan < 8; chan++) {
- if ((mask >> chan) & 0x01) {
- val = (s->state >> chan) & 0x01;
- outb((val << 3) | chan,
- dev->iobase + ADQ12B_OUTBR);
- }
- }
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct adq12b_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- devpriv->last_ctreg = -1; /* force ctreg update */
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- if (it->options[2]) {
- s->subdev_flags = SDF_READABLE | SDF_DIFF;
- s->n_chan = 8;
- } else {
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 16;
- }
- s->maxdata = 0xfff;
- s->range_table = it->options[1] ? &range_adq12b_ai_unipolar
- : &range_adq12b_ai_bipolar;
- s->insn_read = adq12b_ai_insn_read;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 5;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = adq12b_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = adq12b_do_insn_bits;
-
- return 0;
-}
-
-static struct comedi_driver adq12b_driver = {
- .driver_name = "adq12b",
- .module = THIS_MODULE,
- .attach = adq12b_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(adq12b_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
deleted file mode 100644
index 090607760be6..000000000000
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ /dev/null
@@ -1,963 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * adv_pci1710.c
- * Comedi driver for Advantech PCI-1710 series boards
- * Author: Michal Dobes <dobes@tesnet.cz>
- *
- * Thanks to ZhenGang Shang <ZhenGang.Shang@Advantech.com.cn>
- * for testing and information.
- */
-
-/*
- * Driver: adv_pci1710
- * Description: Comedi driver for Advantech PCI-1710 series boards
- * Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG, PCI-1711,
- * PCI-1713, PCI-1731
- * Author: Michal Dobes <dobes@tesnet.cz>
- * Updated: Fri, 29 Oct 2015 17:19:35 -0700
- * Status: works
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * This driver supports AI, AO, DI and DO subdevices.
- * AI subdevice supports cmd and insn interface,
- * other subdevices support only insn interface.
- *
- * The PCI-1710 and PCI-1710HG have the same PCI device ID, so the
- * driver cannot distinguish between them, as would be normal for a
- * PCI driver.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "comedi_8254.h"
-#include "amcc_s5933.h"
-
-/*
- * PCI BAR2 Register map (dev->iobase)
- */
-#define PCI171X_AD_DATA_REG 0x00 /* R: A/D data */
-#define PCI171X_SOFTTRG_REG 0x00 /* W: soft trigger for A/D */
-#define PCI171X_RANGE_REG 0x02 /* W: A/D gain/range register */
-#define PCI171X_RANGE_DIFF BIT(5)
-#define PCI171X_RANGE_UNI BIT(4)
-#define PCI171X_RANGE_GAIN(x) (((x) & 0x7) << 0)
-#define PCI171X_MUX_REG 0x04 /* W: A/D multiplexor control */
-#define PCI171X_MUX_CHANH(x) (((x) & 0xff) << 8)
-#define PCI171X_MUX_CHANL(x) (((x) & 0xff) << 0)
-#define PCI171X_MUX_CHAN(x) (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x))
-#define PCI171X_STATUS_REG 0x06 /* R: status register */
-#define PCI171X_STATUS_IRQ BIT(11) /* 1=IRQ occurred */
-#define PCI171X_STATUS_FF BIT(10) /* 1=FIFO is full, fatal error */
-#define PCI171X_STATUS_FH BIT(9) /* 1=FIFO is half full */
-#define PCI171X_STATUS_FE BIT(8) /* 1=FIFO is empty */
-#define PCI171X_CTRL_REG 0x06 /* W: control register */
-#define PCI171X_CTRL_CNT0 BIT(6) /* 1=ext. clk, 0=int. 100kHz clk */
-#define PCI171X_CTRL_ONEFH BIT(5) /* 1=on FIFO half full, 0=on sample */
-#define PCI171X_CTRL_IRQEN BIT(4) /* 1=enable IRQ */
-#define PCI171X_CTRL_GATE BIT(3) /* 1=enable ext. trigger GATE (8254?) */
-#define PCI171X_CTRL_EXT BIT(2) /* 1=enable ext. trigger source */
-#define PCI171X_CTRL_PACER BIT(1) /* 1=enable int. 8254 trigger source */
-#define PCI171X_CTRL_SW BIT(0) /* 1=enable software trigger source */
-#define PCI171X_CLRINT_REG 0x08 /* W: clear interrupts request */
-#define PCI171X_CLRFIFO_REG 0x09 /* W: clear FIFO */
-#define PCI171X_DA_REG(x) (0x0a + ((x) * 2)) /* W: D/A register */
-#define PCI171X_DAREF_REG 0x0e /* W: D/A reference control */
-#define PCI171X_DAREF(c, r) (((r) & 0x3) << ((c) * 2))
-#define PCI171X_DAREF_MASK(c) PCI171X_DAREF((c), 0x3)
-#define PCI171X_DI_REG 0x10 /* R: digital inputs */
-#define PCI171X_DO_REG 0x10 /* W: digital outputs */
-#define PCI171X_TIMER_BASE 0x18 /* R/W: 8254 timer */
-
-static const struct comedi_lrange pci1710_ai_range = {
- 9, {
- BIP_RANGE(5), /* gain 1 (0x00) */
- BIP_RANGE(2.5), /* gain 2 (0x01) */
- BIP_RANGE(1.25), /* gain 4 (0x02) */
- BIP_RANGE(0.625), /* gain 8 (0x03) */
- BIP_RANGE(10), /* gain 0.5 (0x04) */
- UNI_RANGE(10), /* gain 1 (0x00 | UNI) */
- UNI_RANGE(5), /* gain 2 (0x01 | UNI) */
- UNI_RANGE(2.5), /* gain 4 (0x02 | UNI) */
- UNI_RANGE(1.25) /* gain 8 (0x03 | UNI) */
- }
-};
-
-static const struct comedi_lrange pci1710hg_ai_range = {
- 12, {
- BIP_RANGE(5), /* gain 1 (0x00) */
- BIP_RANGE(0.5), /* gain 10 (0x01) */
- BIP_RANGE(0.05), /* gain 100 (0x02) */
- BIP_RANGE(0.005), /* gain 1000 (0x03) */
- BIP_RANGE(10), /* gain 0.5 (0x04) */
- BIP_RANGE(1), /* gain 5 (0x05) */
- BIP_RANGE(0.1), /* gain 50 (0x06) */
- BIP_RANGE(0.01), /* gain 500 (0x07) */
- UNI_RANGE(10), /* gain 1 (0x00 | UNI) */
- UNI_RANGE(1), /* gain 10 (0x01 | UNI) */
- UNI_RANGE(0.1), /* gain 100 (0x02 | UNI) */
- UNI_RANGE(0.01) /* gain 1000 (0x03 | UNI) */
- }
-};
-
-static const struct comedi_lrange pci1711_ai_range = {
- 5, {
- BIP_RANGE(10), /* gain 1 (0x00) */
- BIP_RANGE(5), /* gain 2 (0x01) */
- BIP_RANGE(2.5), /* gain 4 (0x02) */
- BIP_RANGE(1.25), /* gain 8 (0x03) */
- BIP_RANGE(0.625) /* gain 16 (0x04) */
- }
-};
-
-static const struct comedi_lrange pci171x_ao_range = {
- 3, {
- UNI_RANGE(5), /* internal -5V ref */
- UNI_RANGE(10), /* internal -10V ref */
- RANGE_ext(0, 1) /* external -Vref (+/-10V max) */
- }
-};
-
-enum pci1710_boardid {
- BOARD_PCI1710,
- BOARD_PCI1710HG,
- BOARD_PCI1711,
- BOARD_PCI1713,
- BOARD_PCI1731,
-};
-
-struct boardtype {
- const char *name;
- const struct comedi_lrange *ai_range;
- unsigned int is_pci1711:1;
- unsigned int is_pci1713:1;
- unsigned int has_ao:1;
-};
-
-static const struct boardtype boardtypes[] = {
- [BOARD_PCI1710] = {
- .name = "pci1710",
- .ai_range = &pci1710_ai_range,
- .has_ao = 1,
- },
- [BOARD_PCI1710HG] = {
- .name = "pci1710hg",
- .ai_range = &pci1710hg_ai_range,
- .has_ao = 1,
- },
- [BOARD_PCI1711] = {
- .name = "pci1711",
- .ai_range = &pci1711_ai_range,
- .is_pci1711 = 1,
- .has_ao = 1,
- },
- [BOARD_PCI1713] = {
- .name = "pci1713",
- .ai_range = &pci1710_ai_range,
- .is_pci1713 = 1,
- },
- [BOARD_PCI1731] = {
- .name = "pci1731",
- .ai_range = &pci1711_ai_range,
- .is_pci1711 = 1,
- },
-};
-
-struct pci1710_private {
- unsigned int max_samples;
- unsigned int ctrl; /* control register value */
- unsigned int ctrl_ext; /* used to switch from TRIG_EXT to TRIG_xxx */
- unsigned int mux_scan; /* used to set the channel interval to scan */
- unsigned char ai_et;
- unsigned int act_chanlist[32]; /* list of scanned channel */
- unsigned char saved_seglen; /* len of the non-repeating chanlist */
- unsigned char da_ranges; /* copy of D/A outpit range register */
- unsigned char unipolar_gain; /* adjust for unipolar gain codes */
-};
-
-static int pci1710_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct pci1710_private *devpriv = dev->private;
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int last_aref = CR_AREF(cmd->chanlist[0]);
- unsigned int next_chan = (chan0 + 1) % s->n_chan;
- unsigned int chansegment[32];
- unsigned int seglen;
- int i;
-
- if (cmd->chanlist_len == 1) {
- devpriv->saved_seglen = cmd->chanlist_len;
- return 0;
- }
-
- /* first channel is always ok */
- chansegment[0] = cmd->chanlist[0];
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- if (cmd->chanlist[0] == cmd->chanlist[i])
- break; /* we detected a loop, stop */
-
- if (aref == AREF_DIFF && (chan & 1)) {
- dev_err(dev->class_dev,
- "Odd channel cannot be differential input!\n");
- return -EINVAL;
- }
-
- if (last_aref == AREF_DIFF)
- next_chan = (next_chan + 1) % s->n_chan;
- if (chan != next_chan) {
- dev_err(dev->class_dev,
- "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
- i, chan, next_chan, chan0);
- return -EINVAL;
- }
-
- /* next correct channel in list */
- chansegment[i] = cmd->chanlist[i];
- last_aref = aref;
- }
- seglen = i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- if (cmd->chanlist[i] != chansegment[i % seglen]) {
- dev_err(dev->class_dev,
- "bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
- i, CR_CHAN(chansegment[i]),
- CR_RANGE(chansegment[i]),
- CR_AREF(chansegment[i]),
- CR_CHAN(cmd->chanlist[i % seglen]),
- CR_RANGE(cmd->chanlist[i % seglen]),
- CR_AREF(chansegment[i % seglen]));
- return -EINVAL;
- }
- }
- devpriv->saved_seglen = seglen;
-
- return 0;
-}
-
-static void pci1710_ai_setup_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chanlist,
- unsigned int n_chan,
- unsigned int seglen)
-{
- struct pci1710_private *devpriv = dev->private;
- unsigned int first_chan = CR_CHAN(chanlist[0]);
- unsigned int last_chan = CR_CHAN(chanlist[seglen - 1]);
- unsigned int i;
-
- for (i = 0; i < seglen; i++) { /* store range list to card */
- unsigned int chan = CR_CHAN(chanlist[i]);
- unsigned int range = CR_RANGE(chanlist[i]);
- unsigned int aref = CR_AREF(chanlist[i]);
- unsigned int rangeval = 0;
-
- if (aref == AREF_DIFF)
- rangeval |= PCI171X_RANGE_DIFF;
- if (comedi_range_is_unipolar(s, range)) {
- rangeval |= PCI171X_RANGE_UNI;
- range -= devpriv->unipolar_gain;
- }
- rangeval |= PCI171X_RANGE_GAIN(range);
-
- /* select channel and set range */
- outw(PCI171X_MUX_CHAN(chan), dev->iobase + PCI171X_MUX_REG);
- outw(rangeval, dev->iobase + PCI171X_RANGE_REG);
-
- devpriv->act_chanlist[i] = chan;
- }
- for ( ; i < n_chan; i++) /* store remainder of channel list */
- devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
-
- /* select channel interval to scan */
- devpriv->mux_scan = PCI171X_MUX_CHANL(first_chan) |
- PCI171X_MUX_CHANH(last_chan);
- outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG);
-}
-
-static int pci1710_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + PCI171X_STATUS_REG);
- if ((status & PCI171X_STATUS_FE) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int pci1710_ai_read_sample(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int cur_chan,
- unsigned short *val)
-{
- const struct boardtype *board = dev->board_ptr;
- struct pci1710_private *devpriv = dev->private;
- unsigned short sample;
- unsigned int chan;
-
- sample = inw(dev->iobase + PCI171X_AD_DATA_REG);
- if (!board->is_pci1713) {
- /*
- * The upper 4 bits of the 16-bit sample are the channel number
- * that the sample was acquired from. Verify that this channel
- * number matches the expected channel number.
- */
- chan = sample >> 12;
- if (chan != devpriv->act_chanlist[cur_chan]) {
- dev_err(dev->class_dev,
- "A/D data dropout: received from channel %d, expected %d\n",
- chan, devpriv->act_chanlist[cur_chan]);
- return -ENODATA;
- }
- }
- *val = sample & s->maxdata;
- return 0;
-}
-
-static int pci1710_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pci1710_private *devpriv = dev->private;
- int ret = 0;
- int i;
-
- /* enable software trigger */
- devpriv->ctrl |= PCI171X_CTRL_SW;
- outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
-
- outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-
- pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1);
-
- for (i = 0; i < insn->n; i++) {
- unsigned short val;
-
- /* start conversion */
- outw(0, dev->iobase + PCI171X_SOFTTRG_REG);
-
- ret = comedi_timeout(dev, s, insn, pci1710_ai_eoc, 0);
- if (ret)
- break;
-
- ret = pci1710_ai_read_sample(dev, s, 0, &val);
- if (ret)
- break;
-
- data[i] = val;
- }
-
- /* disable software trigger */
- devpriv->ctrl &= ~PCI171X_CTRL_SW;
- outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
-
- outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-
- return ret ? ret : insn->n;
-}
-
-static int pci1710_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci1710_private *devpriv = dev->private;
-
- /* disable A/D triggers and interrupt sources */
- devpriv->ctrl &= PCI171X_CTRL_CNT0; /* preserve counter 0 clk src */
- outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
-
- /* disable pacer */
- comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
-
- /* clear A/D FIFO and any pending interrutps */
- outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-
- return 0;
-}
-
-static void pci1710_handle_every_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int status;
- unsigned short val;
- int ret;
-
- status = inw(dev->iobase + PCI171X_STATUS_REG);
- if (status & PCI171X_STATUS_FE) {
- dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status);
- s->async->events |= COMEDI_CB_ERROR;
- return;
- }
- if (status & PCI171X_STATUS_FF) {
- dev_dbg(dev->class_dev,
- "A/D FIFO Full status (Fatal Error!) (%4x)\n", status);
- s->async->events |= COMEDI_CB_ERROR;
- return;
- }
-
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-
- for (; !(inw(dev->iobase + PCI171X_STATUS_REG) & PCI171X_STATUS_FE);) {
- ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val);
- if (ret) {
- s->async->events |= COMEDI_CB_ERROR;
- break;
- }
-
- comedi_buf_write_samples(s, &val, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg) {
- s->async->events |= COMEDI_CB_EOA;
- break;
- }
- }
-
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-}
-
-static void pci1710_handle_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci1710_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int status;
- int i;
-
- status = inw(dev->iobase + PCI171X_STATUS_REG);
- if (!(status & PCI171X_STATUS_FH)) {
- dev_dbg(dev->class_dev, "A/D FIFO not half full!\n");
- async->events |= COMEDI_CB_ERROR;
- return;
- }
- if (status & PCI171X_STATUS_FF) {
- dev_dbg(dev->class_dev,
- "A/D FIFO Full status (Fatal Error!)\n");
- async->events |= COMEDI_CB_ERROR;
- return;
- }
-
- for (i = 0; i < devpriv->max_samples; i++) {
- unsigned short val;
- int ret;
-
- ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val);
- if (ret) {
- s->async->events |= COMEDI_CB_ERROR;
- break;
- }
-
- if (!comedi_buf_write_samples(s, &val, 1))
- break;
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- break;
- }
- }
-
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-}
-
-static irqreturn_t pci1710_irq_handler(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct pci1710_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- struct comedi_cmd *cmd;
-
- if (!dev->attached) /* is device attached? */
- return IRQ_NONE; /* no, exit */
-
- s = dev->read_subdev;
- cmd = &s->async->cmd;
-
- /* is this interrupt from our board? */
- if (!(inw(dev->iobase + PCI171X_STATUS_REG) & PCI171X_STATUS_IRQ))
- return IRQ_NONE; /* no, exit */
-
- if (devpriv->ai_et) { /* Switch from initial TRIG_EXT to TRIG_xxx. */
- devpriv->ai_et = 0;
- devpriv->ctrl &= PCI171X_CTRL_CNT0;
- devpriv->ctrl |= PCI171X_CTRL_SW; /* set software trigger */
- outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
- devpriv->ctrl = devpriv->ctrl_ext;
- outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
- /* no sample on this interrupt; reset the channel interval */
- outw(devpriv->mux_scan, dev->iobase + PCI171X_MUX_REG);
- outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- return IRQ_HANDLED;
- }
-
- if (cmd->flags & CMDF_WAKE_EOS)
- pci1710_handle_every_sample(dev, s);
- else
- pci1710_handle_fifo(dev, s);
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int pci1710_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pci1710_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- pci1710_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len,
- devpriv->saved_seglen);
-
- outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-
- devpriv->ctrl &= PCI171X_CTRL_CNT0;
- if ((cmd->flags & CMDF_WAKE_EOS) == 0)
- devpriv->ctrl |= PCI171X_CTRL_ONEFH;
-
- if (cmd->convert_src == TRIG_TIMER) {
- comedi_8254_update_divisors(dev->pacer);
-
- devpriv->ctrl |= PCI171X_CTRL_PACER | PCI171X_CTRL_IRQEN;
- if (cmd->start_src == TRIG_EXT) {
- devpriv->ctrl_ext = devpriv->ctrl;
- devpriv->ctrl &= ~(PCI171X_CTRL_PACER |
- PCI171X_CTRL_ONEFH |
- PCI171X_CTRL_GATE);
- devpriv->ctrl |= PCI171X_CTRL_EXT;
- devpriv->ai_et = 1;
- } else { /* TRIG_NOW */
- devpriv->ai_et = 0;
- }
- outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
-
- if (cmd->start_src == TRIG_NOW)
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- } else { /* TRIG_EXT */
- devpriv->ctrl |= PCI171X_CTRL_EXT | PCI171X_CTRL_IRQEN;
- outw(devpriv->ctrl, dev->iobase + PCI171X_CTRL_REG);
- }
-
- return 0;
-}
-
-static int pci1710_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* step 2a: make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* step 2b: and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER)
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
- else /* TRIG_FOLLOW */
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- unsigned int arg = cmd->convert_arg;
-
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list */
-
- err |= pci1710_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int pci1710_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pci1710_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- devpriv->da_ranges &= ~PCI171X_DAREF_MASK(chan);
- devpriv->da_ranges |= PCI171X_DAREF(chan, range);
- outw(devpriv->da_ranges, dev->iobase + PCI171X_DAREF_REG);
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outw(val, dev->iobase + PCI171X_DA_REG(chan));
- }
-
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pci1710_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inw(dev->iobase + PCI171X_DI_REG);
-
- return insn->n;
-}
-
-static int pci1710_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + PCI171X_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pci1710_counter_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pci1710_private *devpriv = dev->private;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_CLOCK_SRC:
- switch (data[1]) {
- case 0: /* internal */
- devpriv->ctrl_ext &= ~PCI171X_CTRL_CNT0;
- break;
- case 1: /* external */
- devpriv->ctrl_ext |= PCI171X_CTRL_CNT0;
- break;
- default:
- return -EINVAL;
- }
- outw(devpriv->ctrl_ext, dev->iobase + PCI171X_CTRL_REG);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- if (devpriv->ctrl_ext & PCI171X_CTRL_CNT0) {
- data[1] = 1;
- data[2] = 0;
- } else {
- data[1] = 0;
- data[2] = I8254_OSC_BASE_1MHZ;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static void pci1710_reset(struct comedi_device *dev)
-{
- const struct boardtype *board = dev->board_ptr;
-
- /*
- * Disable A/D triggers and interrupt sources, set counter 0
- * to use internal 1 MHz clock.
- */
- outw(0, dev->iobase + PCI171X_CTRL_REG);
-
- /* clear A/D FIFO and any pending interrutps */
- outb(0, dev->iobase + PCI171X_CLRFIFO_REG);
- outb(0, dev->iobase + PCI171X_CLRINT_REG);
-
- if (board->has_ao) {
- /* set DACs to 0..5V and outputs to 0V */
- outb(0, dev->iobase + PCI171X_DAREF_REG);
- outw(0, dev->iobase + PCI171X_DA_REG(0));
- outw(0, dev->iobase + PCI171X_DA_REG(1));
- }
-
- /* set digital outputs to 0 */
- outw(0, dev->iobase + PCI171X_DO_REG);
-}
-
-static int pci1710_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct boardtype *board = NULL;
- struct pci1710_private *devpriv;
- struct comedi_subdevice *s;
- int ret, subdev, n_subdevices;
- int i;
-
- if (context < ARRAY_SIZE(boardtypes))
- board = &boardtypes[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
-
- dev->pacer = comedi_8254_init(dev->iobase + PCI171X_TIMER_BASE,
- I8254_OSC_BASE_10MHZ, I8254_IO16, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- n_subdevices = 1; /* all boards have analog inputs */
- if (board->has_ao)
- n_subdevices++;
- if (!board->is_pci1713) {
- /*
- * All other boards have digital inputs and outputs as
- * well as a user counter.
- */
- n_subdevices += 3;
- }
-
- ret = comedi_alloc_subdevices(dev, n_subdevices);
- if (ret)
- return ret;
-
- pci1710_reset(dev);
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, pci1710_irq_handler,
- IRQF_SHARED, dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- subdev = 0;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- if (!board->is_pci1711)
- s->subdev_flags |= SDF_DIFF;
- s->n_chan = board->is_pci1713 ? 32 : 16;
- s->maxdata = 0x0fff;
- s->range_table = board->ai_range;
- s->insn_read = pci1710_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = pci1710_ai_cmdtest;
- s->do_cmd = pci1710_ai_cmd;
- s->cancel = pci1710_ai_cancel;
- }
-
- /* find the value needed to adjust for unipolar gain codes */
- for (i = 0; i < s->range_table->length; i++) {
- if (comedi_range_is_unipolar(s, i)) {
- devpriv->unipolar_gain = i;
- break;
- }
- }
-
- if (board->has_ao) {
- /* Analog Output subdevice */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &pci171x_ao_range;
- s->insn_write = pci1710_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- }
-
- if (!board->is_pci1713) {
- /* Digital Input subdevice */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci1710_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci1710_do_insn_bits;
-
- /* Counter subdevice (8254) */
- s = &dev->subdevices[subdev++];
- comedi_8254_subdevice_init(s, dev->pacer);
-
- dev->pacer->insn_config = pci1710_counter_insn_config;
-
- /* counters 1 and 2 are used internally for the pacer */
- comedi_8254_set_busy(dev->pacer, 1, true);
- comedi_8254_set_busy(dev->pacer, 2, true);
- }
-
- /* max_samples is half the FIFO size (2 bytes/sample) */
- devpriv->max_samples = (board->is_pci1711) ? 512 : 2048;
-
- return 0;
-}
-
-static struct comedi_driver adv_pci1710_driver = {
- .driver_name = "adv_pci1710",
- .module = THIS_MODULE,
- .auto_attach = pci1710_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int adv_pci1710_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adv_pci1710_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id adv_pci1710_pci_table[] = {
- {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050),
- .driver_data = BOARD_PCI1710,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0x0000),
- .driver_data = BOARD_PCI1710,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xb100),
- .driver_data = BOARD_PCI1710,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xb200),
- .driver_data = BOARD_PCI1710,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xc100),
- .driver_data = BOARD_PCI1710,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xc200),
- .driver_data = BOARD_PCI1710,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, 0x1000, 0xd100),
- .driver_data = BOARD_PCI1710,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0x0002),
- .driver_data = BOARD_PCI1710HG,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xb102),
- .driver_data = BOARD_PCI1710HG,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xb202),
- .driver_data = BOARD_PCI1710HG,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xc102),
- .driver_data = BOARD_PCI1710HG,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
- PCI_VENDOR_ID_ADVANTECH, 0xc202),
- .driver_data = BOARD_PCI1710HG,
- }, {
- PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, 0x1000, 0xd102),
- .driver_data = BOARD_PCI1710HG,
- },
- { PCI_VDEVICE(ADVANTECH, 0x1711), BOARD_PCI1711 },
- { PCI_VDEVICE(ADVANTECH, 0x1713), BOARD_PCI1713 },
- { PCI_VDEVICE(ADVANTECH, 0x1731), BOARD_PCI1731 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adv_pci1710_pci_table);
-
-static struct pci_driver adv_pci1710_pci_driver = {
- .name = "adv_pci1710",
- .id_table = adv_pci1710_pci_table,
- .probe = adv_pci1710_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi: Advantech PCI-1710 Series Multifunction DAS Cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci1720.c b/drivers/staging/comedi/drivers/adv_pci1720.c
deleted file mode 100644
index 2fcd7e8e7d85..000000000000
--- a/drivers/staging/comedi/drivers/adv_pci1720.c
+++ /dev/null
@@ -1,186 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * COMEDI driver for Advantech PCI-1720U
- * Copyright (c) 2015 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Separated from the adv_pci1710 driver written by:
- * Michal Dobes <dobes@tesnet.cz>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: adv_pci1720
- * Description: 4-channel Isolated D/A Output board
- * Devices: [Advantech] PCI-7120U (adv_pci1720)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Fri, 29 Oct 2015 17:19:35 -0700
- * Status: untested
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * The PCI-1720 has 4 isolated 12-bit analog output channels with multiple
- * output ranges. It also has a BoardID switch to allow differentiating
- * multiple boards in the system.
- *
- * The analog outputs can operate in two modes, immediate and synchronized.
- * This driver currently does not support the synchronized output mode.
- *
- * Jumpers JP1 to JP4 are used to set the current sink ranges for each
- * analog output channel. In order to use the current sink ranges, the
- * unipolar 5V range must be used. The voltage output and sink output for
- * each channel is available on the connector as separate pins.
- *
- * Jumper JP5 controls the "hot" reset state of the analog outputs.
- * Depending on its setting, the analog outputs will either keep the
- * last settings and output values or reset to the default state after
- * a "hot" reset. The default state for all channels is uniploar 5V range
- * and all the output values are 0V. To allow this feature to work, the
- * analog outputs are not "reset" when the driver attaches.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI BAR2 Register map (dev->iobase)
- */
-#define PCI1720_AO_LSB_REG(x) (0x00 + ((x) * 2))
-#define PCI1720_AO_MSB_REG(x) (0x01 + ((x) * 2))
-#define PCI1720_AO_RANGE_REG 0x08
-#define PCI1720_AO_RANGE(c, r) (((r) & 0x3) << ((c) * 2))
-#define PCI1720_AO_RANGE_MASK(c) PCI1720_AO_RANGE((c), 0x3)
-#define PCI1720_SYNC_REG 0x09
-#define PCI1720_SYNC_CTRL_REG 0x0f
-#define PCI1720_SYNC_CTRL_SC0 BIT(0)
-#define PCI1720_BOARDID_REG 0x14
-
-static const struct comedi_lrange pci1720_ao_range = {
- 4, {
- UNI_RANGE(5),
- UNI_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(10)
- }
-};
-
-static int pci1720_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- int i;
-
- /* set the channel range and polarity */
- val = inb(dev->iobase + PCI1720_AO_RANGE_REG);
- val &= ~PCI1720_AO_RANGE_MASK(chan);
- val |= PCI1720_AO_RANGE(chan, range);
- outb(val, dev->iobase + PCI1720_AO_RANGE_REG);
-
- val = s->readback[chan];
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- outb(val & 0xff, dev->iobase + PCI1720_AO_LSB_REG(chan));
- outb((val >> 8) & 0xff, dev->iobase + PCI1720_AO_MSB_REG(chan));
-
- /* conversion time is 2us (500 kHz throughput) */
- usleep_range(2, 100);
- }
-
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pci1720_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + PCI1720_BOARDID_REG);
-
- return insn->n;
-}
-
-static int pci1720_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0x0fff;
- s->range_table = &pci1720_ao_range;
- s->insn_write = pci1720_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital Input subdevice (BoardID SW1) */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci1720_di_insn_bits;
-
- /* disable synchronized output, channels update when written */
- outb(0, dev->iobase + PCI1720_SYNC_CTRL_REG);
-
- return 0;
-}
-
-static struct comedi_driver adv_pci1720_driver = {
- .driver_name = "adv_pci1720",
- .module = THIS_MODULE,
- .auto_attach = pci1720_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int adv_pci1720_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adv_pci1720_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id adv_pci1720_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adv_pci1720_pci_table);
-
-static struct pci_driver adv_pci1720_pci_driver = {
- .name = "adv_pci1720",
- .id_table = adv_pci1720_pci_table,
- .probe = adv_pci1720_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adv_pci1720_driver, adv_pci1720_pci_driver);
-
-MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_DESCRIPTION("Comedi driver for Advantech PCI-1720 Analog Output board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
deleted file mode 100644
index 23660a9fdb9c..000000000000
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ /dev/null
@@ -1,227 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * adv_pci1723.c
- * Comedi driver for the Advantech PCI-1723 card.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: adv_pci1723
- * Description: Advantech PCI-1723
- * Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Advantech] PCI-1723 (adv_pci1723)
- * Updated: Mon, 14 Apr 2008 15:12:56 +0100
- * Status: works
- *
- * Configuration Options: not applicable, uses comedi PCI auto config
- *
- * Subdevice 0 is 8-channel AO, 16-bit, range +/- 10 V.
- *
- * Subdevice 1 is 16-channel DIO. The channels are configurable as
- * input or output in 2 groups (0 to 7, 8 to 15). Configuring any
- * channel implicitly configures all channels in the same group.
- *
- * TODO:
- * 1. Add the two milliamp ranges to the AO subdevice (0 to 20 mA,
- * 4 to 20 mA).
- * 2. Read the initial ranges and values of the AO subdevice at
- * start-up instead of reinitializing them.
- * 3. Implement calibration.
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI Bar 2 I/O Register map (dev->iobase)
- */
-#define PCI1723_AO_REG(x) (0x00 + ((x) * 2))
-#define PCI1723_BOARD_ID_REG 0x10
-#define PCI1723_BOARD_ID_MASK (0xf << 0)
-#define PCI1723_SYNC_CTRL_REG 0x12
-#define PCI1723_SYNC_CTRL(x) (((x) & 0x1) << 0)
-#define PCI1723_SYNC_CTRL_ASYNC PCI1723_SYNC_CTRL(0)
-#define PCI1723_SYNC_CTRL_SYNC PCI1723_SYNC_CTRL(1)
-#define PCI1723_CTRL_REG 0x14
-#define PCI1723_CTRL_BUSY BIT(15)
-#define PCI1723_CTRL_INIT BIT(14)
-#define PCI1723_CTRL_SELF BIT(8)
-#define PCI1723_CTRL_IDX(x) (((x) & 0x3) << 6)
-#define PCI1723_CTRL_RANGE(x) (((x) & 0x3) << 4)
-#define PCI1723_CTRL_SEL(x) (((x) & 0x1) << 3)
-#define PCI1723_CTRL_GAIN PCI1723_CTRL_SEL(0)
-#define PCI1723_CTRL_OFFSET PCI1723_CTRL_SEL(1)
-#define PCI1723_CTRL_CHAN(x) (((x) & 0x7) << 0)
-#define PCI1723_CALIB_CTRL_REG 0x16
-#define PCI1723_CALIB_CTRL_CS BIT(2)
-#define PCI1723_CALIB_CTRL_DAT BIT(1)
-#define PCI1723_CALIB_CTRL_CLK BIT(0)
-#define PCI1723_CALIB_STROBE_REG 0x18
-#define PCI1723_DIO_CTRL_REG 0x1a
-#define PCI1723_DIO_CTRL_HDIO BIT(1)
-#define PCI1723_DIO_CTRL_LDIO BIT(0)
-#define PCI1723_DIO_DATA_REG 0x1c
-#define PCI1723_CALIB_DATA_REG 0x1e
-#define PCI1723_SYNC_STROBE_REG 0x20
-#define PCI1723_RESET_AO_STROBE_REG 0x22
-#define PCI1723_RESET_CALIB_STROBE_REG 0x24
-#define PCI1723_RANGE_STROBE_REG 0x26
-#define PCI1723_VREF_REG 0x28
-#define PCI1723_VREF(x) (((x) & 0x3) << 0)
-#define PCI1723_VREF_NEG10V PCI1723_VREF(0)
-#define PCI1723_VREF_0V PCI1723_VREF(1)
-#define PCI1723_VREF_POS10V PCI1723_VREF(3)
-
-static int pci1723_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- outw(val, dev->iobase + PCI1723_AO_REG(chan));
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int pci1723_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask = (chan < 8) ? 0x00ff : 0xff00;
- unsigned short mode = 0x0000; /* assume output */
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- if (!(s->io_bits & 0x00ff))
- mode |= PCI1723_DIO_CTRL_LDIO; /* low byte input */
- if (!(s->io_bits & 0xff00))
- mode |= PCI1723_DIO_CTRL_HDIO; /* high byte input */
- outw(mode, dev->iobase + PCI1723_DIO_CTRL_REG);
-
- return insn->n;
-}
-
-static int pci1723_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + PCI1723_DIO_DATA_REG);
-
- data[1] = inw(dev->iobase + PCI1723_DIO_DATA_REG);
-
- return insn->n;
-}
-
-static int pci1723_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- unsigned int val;
- int ret;
- int i;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = 8;
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar10;
- s->insn_write = pci1723_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* synchronously reset all analog outputs to 0V, +/-10V range */
- outw(PCI1723_SYNC_CTRL_SYNC, dev->iobase + PCI1723_SYNC_CTRL_REG);
- for (i = 0; i < s->n_chan; i++) {
- outw(PCI1723_CTRL_RANGE(0) | PCI1723_CTRL_CHAN(i),
- PCI1723_CTRL_REG);
- outw(0, dev->iobase + PCI1723_RANGE_STROBE_REG);
-
- outw(0x8000, dev->iobase + PCI1723_AO_REG(i));
- s->readback[i] = 0x8000;
- }
- outw(0, dev->iobase + PCI1723_SYNC_STROBE_REG);
-
- /* disable syncronous control */
- outw(PCI1723_SYNC_CTRL_ASYNC, dev->iobase + PCI1723_SYNC_CTRL_REG);
-
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = pci1723_dio_insn_config;
- s->insn_bits = pci1723_dio_insn_bits;
-
- /* get initial DIO direction and state */
- val = inw(dev->iobase + PCI1723_DIO_CTRL_REG);
- if (!(val & PCI1723_DIO_CTRL_LDIO))
- s->io_bits |= 0x00ff; /* low byte output */
- if (!(val & PCI1723_DIO_CTRL_HDIO))
- s->io_bits |= 0xff00; /* high byte output */
- s->state = inw(dev->iobase + PCI1723_DIO_DATA_REG);
-
- return 0;
-}
-
-static struct comedi_driver adv_pci1723_driver = {
- .driver_name = "adv_pci1723",
- .module = THIS_MODULE,
- .auto_attach = pci1723_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int adv_pci1723_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adv_pci1723_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id adv_pci1723_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adv_pci1723_pci_table);
-
-static struct pci_driver adv_pci1723_pci_driver = {
- .name = "adv_pci1723",
- .id_table = adv_pci1723_pci_table,
- .probe = adv_pci1723_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adv_pci1723_driver, adv_pci1723_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Advantech PCI-1723 Comedi driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c
deleted file mode 100644
index e8ab573c839f..000000000000
--- a/drivers/staging/comedi/drivers/adv_pci1724.c
+++ /dev/null
@@ -1,208 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * adv_pci1724.c
- * Comedi driver for the Advantech PCI-1724U card.
- *
- * Author: Frank Mori Hess <fmh6jj@gmail.com>
- * Copyright (C) 2013 GnuBIO Inc
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: adv_pci1724
- * Description: Advantech PCI-1724U
- * Devices: [Advantech] PCI-1724U (adv_pci1724)
- * Author: Frank Mori Hess <fmh6jj@gmail.com>
- * Updated: 2013-02-09
- * Status: works
- *
- * Configuration Options: not applicable, uses comedi PCI auto config
- *
- * Subdevice 0 is the analog output.
- * Subdevice 1 is the offset calibration for the analog output.
- * Subdevice 2 is the gain calibration for the analog output.
- *
- * The calibration offset and gains have quite a large effect on the
- * analog output, so it is possible to adjust the analog output to
- * have an output range significantly different from the board's
- * nominal output ranges. For a calibrated +/-10V range, the analog
- * output's offset will be set somewhere near mid-range (0x2000) and
- * its gain will be near maximum (0x3fff).
- *
- * There is really no difference between the board's documented 0-20mA
- * versus 4-20mA output ranges. To pick one or the other is simply a
- * matter of adjusting the offset and gain calibration until the board
- * outputs in the desired range.
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI bar 2 Register I/O map (dev->iobase)
- */
-#define PCI1724_DAC_CTRL_REG 0x00
-#define PCI1724_DAC_CTRL_GX(x) BIT(20 + ((x) / 8))
-#define PCI1724_DAC_CTRL_CX(x) (((x) % 8) << 16)
-#define PCI1724_DAC_CTRL_MODE(x) (((x) & 0x3) << 14)
-#define PCI1724_DAC_CTRL_MODE_GAIN PCI1724_DAC_CTRL_MODE(1)
-#define PCI1724_DAC_CTRL_MODE_OFFSET PCI1724_DAC_CTRL_MODE(2)
-#define PCI1724_DAC_CTRL_MODE_NORMAL PCI1724_DAC_CTRL_MODE(3)
-#define PCI1724_DAC_CTRL_MODE_MASK PCI1724_DAC_CTRL_MODE(3)
-#define PCI1724_DAC_CTRL_DATA(x) (((x) & 0x3fff) << 0)
-#define PCI1724_SYNC_CTRL_REG 0x04
-#define PCI1724_SYNC_CTRL_DACSTAT BIT(1)
-#define PCI1724_SYNC_CTRL_SYN BIT(0)
-#define PCI1724_EEPROM_CTRL_REG 0x08
-#define PCI1724_SYNC_TRIG_REG 0x0c /* any value works */
-#define PCI1724_BOARD_ID_REG 0x10
-#define PCI1724_BOARD_ID_MASK (0xf << 0)
-
-static const struct comedi_lrange adv_pci1724_ao_ranges = {
- 4, {
- BIP_RANGE(10),
- RANGE_mA(0, 20),
- RANGE_mA(4, 20),
- RANGE_unitless(0, 1)
- }
-};
-
-static int adv_pci1724_dac_idle(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inl(dev->iobase + PCI1724_SYNC_CTRL_REG);
- if ((status & PCI1724_SYNC_CTRL_DACSTAT) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int adv_pci1724_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long mode = (unsigned long)s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int ctrl;
- int ret;
- int i;
-
- ctrl = PCI1724_DAC_CTRL_GX(chan) | PCI1724_DAC_CTRL_CX(chan) | mode;
-
- /* turn off synchronous mode */
- outl(0, dev->iobase + PCI1724_SYNC_CTRL_REG);
-
- for (i = 0; i < insn->n; ++i) {
- unsigned int val = data[i];
-
- ret = comedi_timeout(dev, s, insn, adv_pci1724_dac_idle, 0);
- if (ret)
- return ret;
-
- outl(ctrl | PCI1724_DAC_CTRL_DATA(val),
- dev->iobase + PCI1724_DAC_CTRL_REG);
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int adv_pci1724_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- unsigned int board_id;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->iobase = pci_resource_start(pcidev, 2);
- board_id = inl(dev->iobase + PCI1724_BOARD_ID_REG);
- dev_info(dev->class_dev, "board id: %d\n",
- board_id & PCI1724_BOARD_ID_MASK);
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
- s->n_chan = 32;
- s->maxdata = 0x3fff;
- s->range_table = &adv_pci1724_ao_ranges;
- s->insn_write = adv_pci1724_insn_write;
- s->private = (void *)PCI1724_DAC_CTRL_MODE_NORMAL;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Offset Calibration subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 32;
- s->maxdata = 0x3fff;
- s->insn_write = adv_pci1724_insn_write;
- s->private = (void *)PCI1724_DAC_CTRL_MODE_OFFSET;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Gain Calibration subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 32;
- s->maxdata = 0x3fff;
- s->insn_write = adv_pci1724_insn_write;
- s->private = (void *)PCI1724_DAC_CTRL_MODE_GAIN;
-
- return comedi_alloc_subdev_readback(s);
-}
-
-static struct comedi_driver adv_pci1724_driver = {
- .driver_name = "adv_pci1724",
- .module = THIS_MODULE,
- .auto_attach = adv_pci1724_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int adv_pci1724_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &adv_pci1724_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id adv_pci1724_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1724) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adv_pci1724_pci_table);
-
-static struct pci_driver adv_pci1724_pci_driver = {
- .name = "adv_pci1724",
- .id_table = adv_pci1724_pci_table,
- .probe = adv_pci1724_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adv_pci1724_driver, adv_pci1724_pci_driver);
-
-MODULE_AUTHOR("Frank Mori Hess <fmh6jj@gmail.com>");
-MODULE_DESCRIPTION("Advantech PCI-1724U Comedi driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci1760.c b/drivers/staging/comedi/drivers/adv_pci1760.c
deleted file mode 100644
index 6de8ab97d346..000000000000
--- a/drivers/staging/comedi/drivers/adv_pci1760.c
+++ /dev/null
@@ -1,424 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * COMEDI driver for the Advantech PCI-1760
- * Copyright (C) 2015 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Based on the pci1760 support in the adv_pci_dio driver written by:
- * Michal Dobes <dobes@tesnet.cz>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: adv_pci1760
- * Description: Advantech PCI-1760 Relay & Isolated Digital Input Card
- * Devices: [Advantech] PCI-1760 (adv_pci1760)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Fri, 13 Nov 2015 12:34:00 -0700
- * Status: untested
- *
- * Configuration Options: not applicable, uses PCI auto config
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI-1760 Register Map
- *
- * Outgoing Mailbox Bytes
- * OMB3: Not used (must be 0)
- * OMB2: The command code to the PCI-1760
- * OMB1: The hi byte of the parameter for the command in OMB2
- * OMB0: The lo byte of the parameter for the command in OMB2
- *
- * Incoming Mailbox Bytes
- * IMB3: The Isolated Digital Input status (updated every 100us)
- * IMB2: The current command (matches OMB2 when command is successful)
- * IMB1: The hi byte of the feedback data for the command in OMB2
- * IMB0: The lo byte of the feedback data for the command in OMB2
- *
- * Interrupt Control/Status
- * INTCSR3: Not used (must be 0)
- * INTCSR2: The interrupt status (read only)
- * INTCSR1: Interrupt enable/disable
- * INTCSR0: Not used (must be 0)
- */
-#define PCI1760_OMB_REG(x) (0x0c + (x))
-#define PCI1760_IMB_REG(x) (0x1c + (x))
-#define PCI1760_INTCSR_REG(x) (0x38 + (x))
-#define PCI1760_INTCSR1_IRQ_ENA BIT(5)
-#define PCI1760_INTCSR2_OMB_IRQ BIT(0)
-#define PCI1760_INTCSR2_IMB_IRQ BIT(1)
-#define PCI1760_INTCSR2_IRQ_STATUS BIT(6)
-#define PCI1760_INTCSR2_IRQ_ASSERTED BIT(7)
-
-/* PCI-1760 command codes */
-#define PCI1760_CMD_CLR_IMB2 0x00 /* Clears IMB2 */
-#define PCI1760_CMD_SET_DO 0x01 /* Set output state */
-#define PCI1760_CMD_GET_DO 0x02 /* Read output status */
-#define PCI1760_CMD_GET_STATUS 0x03 /* Read current status */
-#define PCI1760_CMD_GET_FW_VER 0x0e /* Read firmware version */
-#define PCI1760_CMD_GET_HW_VER 0x0f /* Read hardware version */
-#define PCI1760_CMD_SET_PWM_HI(x) (0x10 + (x) * 2) /* Set "hi" period */
-#define PCI1760_CMD_SET_PWM_LO(x) (0x11 + (x) * 2) /* Set "lo" period */
-#define PCI1760_CMD_SET_PWM_CNT(x) (0x14 + (x)) /* Set burst count */
-#define PCI1760_CMD_ENA_PWM 0x1f /* Enable PWM outputs */
-#define PCI1760_CMD_ENA_FILT 0x20 /* Enable input filter */
-#define PCI1760_CMD_ENA_PAT_MATCH 0x21 /* Enable input pattern match */
-#define PCI1760_CMD_SET_PAT_MATCH 0x22 /* Set input pattern match */
-#define PCI1760_CMD_ENA_RISE_EDGE 0x23 /* Enable input rising edge */
-#define PCI1760_CMD_ENA_FALL_EDGE 0x24 /* Enable input falling edge */
-#define PCI1760_CMD_ENA_CNT 0x28 /* Enable counter */
-#define PCI1760_CMD_RST_CNT 0x29 /* Reset counter */
-#define PCI1760_CMD_ENA_CNT_OFLOW 0x2a /* Enable counter overflow */
-#define PCI1760_CMD_ENA_CNT_MATCH 0x2b /* Enable counter match */
-#define PCI1760_CMD_SET_CNT_EDGE 0x2c /* Set counter edge */
-#define PCI1760_CMD_GET_CNT 0x2f /* Reads counter value */
-#define PCI1760_CMD_SET_HI_SAMP(x) (0x30 + (x)) /* Set "hi" sample time */
-#define PCI1760_CMD_SET_LO_SAMP(x) (0x38 + (x)) /* Set "lo" sample time */
-#define PCI1760_CMD_SET_CNT(x) (0x40 + (x)) /* Set counter reset val */
-#define PCI1760_CMD_SET_CNT_MATCH(x) (0x48 + (x)) /* Set counter match val */
-#define PCI1760_CMD_GET_INT_FLAGS 0x60 /* Read interrupt flags */
-#define PCI1760_CMD_GET_INT_FLAGS_MATCH BIT(0)
-#define PCI1760_CMD_GET_INT_FLAGS_COS BIT(1)
-#define PCI1760_CMD_GET_INT_FLAGS_OFLOW BIT(2)
-#define PCI1760_CMD_GET_OS 0x61 /* Read edge change flags */
-#define PCI1760_CMD_GET_CNT_STATUS 0x62 /* Read counter oflow/match */
-
-#define PCI1760_CMD_TIMEOUT 250 /* 250 usec timeout */
-#define PCI1760_CMD_RETRIES 3 /* limit number of retries */
-
-#define PCI1760_PWM_TIMEBASE 100000 /* 1 unit = 100 usec */
-
-static int pci1760_send_cmd(struct comedi_device *dev,
- unsigned char cmd, unsigned short val)
-{
- unsigned long timeout;
-
- /* send the command and parameter */
- outb(val & 0xff, dev->iobase + PCI1760_OMB_REG(0));
- outb((val >> 8) & 0xff, dev->iobase + PCI1760_OMB_REG(1));
- outb(cmd, dev->iobase + PCI1760_OMB_REG(2));
- outb(0, dev->iobase + PCI1760_OMB_REG(3));
-
- /* datasheet says to allow up to 250 usec for the command to complete */
- timeout = jiffies + usecs_to_jiffies(PCI1760_CMD_TIMEOUT);
- do {
- if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) {
- /* command success; return the feedback data */
- return inb(dev->iobase + PCI1760_IMB_REG(0)) |
- (inb(dev->iobase + PCI1760_IMB_REG(1)) << 8);
- }
- cpu_relax();
- } while (time_before(jiffies, timeout));
-
- return -EBUSY;
-}
-
-static int pci1760_cmd(struct comedi_device *dev,
- unsigned char cmd, unsigned short val)
-{
- int repeats;
- int ret;
-
- /* send PCI1760_CMD_CLR_IMB2 between identical commands */
- if (inb(dev->iobase + PCI1760_IMB_REG(2)) == cmd) {
- ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0);
- if (ret < 0) {
- /* timeout? try it once more */
- ret = pci1760_send_cmd(dev, PCI1760_CMD_CLR_IMB2, 0);
- if (ret < 0)
- return -ETIMEDOUT;
- }
- }
-
- /* datasheet says to keep retrying the command */
- for (repeats = 0; repeats < PCI1760_CMD_RETRIES; repeats++) {
- ret = pci1760_send_cmd(dev, cmd, val);
- if (ret >= 0)
- return ret;
- }
-
- /* command failed! */
- return -ETIMEDOUT;
-}
-
-static int pci1760_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + PCI1760_IMB_REG(3));
-
- return insn->n;
-}
-
-static int pci1760_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- if (comedi_dio_update_state(s, data)) {
- ret = pci1760_cmd(dev, PCI1760_CMD_SET_DO, s->state);
- if (ret < 0)
- return ret;
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pci1760_pwm_ns_to_div(unsigned int flags, unsigned int ns)
-{
- unsigned int divisor;
-
- switch (flags) {
- case CMDF_ROUND_NEAREST:
- divisor = DIV_ROUND_CLOSEST(ns, PCI1760_PWM_TIMEBASE);
- break;
- case CMDF_ROUND_UP:
- divisor = DIV_ROUND_UP(ns, PCI1760_PWM_TIMEBASE);
- break;
- case CMDF_ROUND_DOWN:
- divisor = ns / PCI1760_PWM_TIMEBASE;
- break;
- default:
- return -EINVAL;
- }
-
- if (divisor < 1)
- divisor = 1;
- if (divisor > 0xffff)
- divisor = 0xffff;
-
- return divisor;
-}
-
-static int pci1760_pwm_enable(struct comedi_device *dev,
- unsigned int chan, bool enable)
-{
- int ret;
-
- ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS, PCI1760_CMD_ENA_PWM);
- if (ret < 0)
- return ret;
-
- if (enable)
- ret |= BIT(chan);
- else
- ret &= ~BIT(chan);
-
- return pci1760_cmd(dev, PCI1760_CMD_ENA_PWM, ret);
-}
-
-static int pci1760_pwm_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int hi_div;
- int lo_div;
- int ret;
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- ret = pci1760_pwm_enable(dev, chan, false);
- if (ret < 0)
- return ret;
-
- if (data[1] > 0xffff)
- return -EINVAL;
- ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_CNT(chan), data[1]);
- if (ret < 0)
- return ret;
-
- ret = pci1760_pwm_enable(dev, chan, true);
- if (ret < 0)
- return ret;
- break;
- case INSN_CONFIG_DISARM:
- ret = pci1760_pwm_enable(dev, chan, false);
- if (ret < 0)
- return ret;
- break;
- case INSN_CONFIG_PWM_OUTPUT:
- ret = pci1760_pwm_enable(dev, chan, false);
- if (ret < 0)
- return ret;
-
- hi_div = pci1760_pwm_ns_to_div(data[1], data[2]);
- lo_div = pci1760_pwm_ns_to_div(data[3], data[4]);
- if (hi_div < 0 || lo_div < 0)
- return -EINVAL;
- if ((hi_div * PCI1760_PWM_TIMEBASE) != data[2] ||
- (lo_div * PCI1760_PWM_TIMEBASE) != data[4]) {
- data[2] = hi_div * PCI1760_PWM_TIMEBASE;
- data[4] = lo_div * PCI1760_PWM_TIMEBASE;
- return -EAGAIN;
- }
- ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_HI(chan), hi_div);
- if (ret < 0)
- return ret;
- ret = pci1760_cmd(dev, PCI1760_CMD_SET_PWM_LO(chan), lo_div);
- if (ret < 0)
- return ret;
- break;
- case INSN_CONFIG_GET_PWM_OUTPUT:
- hi_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
- PCI1760_CMD_SET_PWM_HI(chan));
- lo_div = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
- PCI1760_CMD_SET_PWM_LO(chan));
- if (hi_div < 0 || lo_div < 0)
- return -ETIMEDOUT;
-
- data[1] = hi_div * PCI1760_PWM_TIMEBASE;
- data[2] = lo_div * PCI1760_PWM_TIMEBASE;
- break;
- case INSN_CONFIG_GET_PWM_STATUS:
- ret = pci1760_cmd(dev, PCI1760_CMD_GET_STATUS,
- PCI1760_CMD_ENA_PWM);
- if (ret < 0)
- return ret;
-
- data[1] = (ret & BIT(chan)) ? 1 : 0;
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static void pci1760_reset(struct comedi_device *dev)
-{
- int i;
-
- /* disable interrupts (intcsr2 is read-only) */
- outb(0, dev->iobase + PCI1760_INTCSR_REG(0));
- outb(0, dev->iobase + PCI1760_INTCSR_REG(1));
- outb(0, dev->iobase + PCI1760_INTCSR_REG(3));
-
- /* disable counters */
- pci1760_cmd(dev, PCI1760_CMD_ENA_CNT, 0);
-
- /* disable overflow interrupts */
- pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_OFLOW, 0);
-
- /* disable match */
- pci1760_cmd(dev, PCI1760_CMD_ENA_CNT_MATCH, 0);
-
- /* set match and counter reset values */
- for (i = 0; i < 8; i++) {
- pci1760_cmd(dev, PCI1760_CMD_SET_CNT_MATCH(i), 0x8000);
- pci1760_cmd(dev, PCI1760_CMD_SET_CNT(i), 0x0000);
- }
-
- /* reset counters to reset values */
- pci1760_cmd(dev, PCI1760_CMD_RST_CNT, 0xff);
-
- /* set counter count edges */
- pci1760_cmd(dev, PCI1760_CMD_SET_CNT_EDGE, 0);
-
- /* disable input filters */
- pci1760_cmd(dev, PCI1760_CMD_ENA_FILT, 0);
-
- /* disable pattern matching */
- pci1760_cmd(dev, PCI1760_CMD_ENA_PAT_MATCH, 0);
-
- /* set pattern match value */
- pci1760_cmd(dev, PCI1760_CMD_SET_PAT_MATCH, 0);
-}
-
-static int pci1760_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 0);
-
- pci1760_reset(dev);
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci1760_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci1760_do_insn_bits;
-
- /* get the current state of the outputs */
- ret = pci1760_cmd(dev, PCI1760_CMD_GET_DO, 0);
- if (ret < 0)
- return ret;
- s->state = ret;
-
- /* PWM subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_PWM;
- s->subdev_flags = SDF_PWM_COUNTER;
- s->n_chan = 2;
- s->insn_config = pci1760_pwm_insn_config;
-
- /* Counter subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_UNUSED;
-
- return 0;
-}
-
-static struct comedi_driver pci1760_driver = {
- .driver_name = "adv_pci1760",
- .module = THIS_MODULE,
- .auto_attach = pci1760_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int pci1760_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &pci1760_driver, id->driver_data);
-}
-
-static const struct pci_device_id pci1760_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, pci1760_pci_table);
-
-static struct pci_driver pci1760_pci_driver = {
- .name = "adv_pci1760",
- .id_table = pci1760_pci_table,
- .probe = pci1760_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(pci1760_driver, pci1760_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Advantech PCI-1760");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
deleted file mode 100644
index 54c7419c8ca6..000000000000
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ /dev/null
@@ -1,801 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * comedi/drivers/adv_pci_dio.c
- *
- * Author: Michal Dobes <dobes@tesnet.cz>
- *
- * Hardware driver for Advantech PCI DIO cards.
- */
-
-/*
- * Driver: adv_pci_dio
- * Description: Advantech Digital I/O Cards
- * Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
- * PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
- * PCI-1751, PCI-1752, PCI-1753, PCI-1753+PCI-1753E,
- * PCI-1754, PCI-1756, PCI-1761, PCI-1762
- * Author: Michal Dobes <dobes@tesnet.cz>
- * Updated: Fri, 25 Aug 2017 07:23:06 +0300
- * Status: untested
- *
- * Configuration Options: not applicable, uses PCI auto config
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedi_pci.h"
-
-#include "8255.h"
-#include "comedi_8254.h"
-
-/*
- * Register offset definitions
- */
-
-/* PCI-1730, PCI-1733, PCI-1736 interrupt control registers */
-#define PCI173X_INT_EN_REG 0x0008 /* R/W: enable/disable */
-#define PCI173X_INT_RF_REG 0x000c /* R/W: falling/rising edge */
-#define PCI173X_INT_FLAG_REG 0x0010 /* R: status */
-#define PCI173X_INT_CLR_REG 0x0010 /* W: clear */
-
-#define PCI173X_INT_IDI0 0x01 /* IDI0 edge occurred */
-#define PCI173X_INT_IDI1 0x02 /* IDI1 edge occurred */
-#define PCI173X_INT_DI0 0x04 /* DI0 edge occurred */
-#define PCI173X_INT_DI1 0x08 /* DI1 edge occurred */
-
-/* PCI-1739U, PCI-1750, PCI1751 interrupt control registers */
-#define PCI1750_INT_REG 0x20 /* R/W: status/control */
-
-/* PCI-1753, PCI-1753E interrupt control registers */
-#define PCI1753_INT_REG(x) (0x10 + (x)) /* R/W: control group 0 to 3 */
-#define PCI1753E_INT_REG(x) (0x30 + (x)) /* R/W: control group 0 to 3 */
-
-/* PCI-1754, PCI-1756 interrupt control registers */
-#define PCI1754_INT_REG(x) (0x08 + (x) * 2) /* R/W: control group 0 to 3 */
-
-/* PCI-1752, PCI-1756 special registers */
-#define PCI1752_CFC_REG 0x12 /* R/W: channel freeze function */
-
-/* PCI-1761 interrupt control registers */
-#define PCI1761_INT_EN_REG 0x03 /* R/W: enable/disable interrupts */
-#define PCI1761_INT_RF_REG 0x04 /* R/W: falling/rising edge */
-#define PCI1761_INT_CLR_REG 0x05 /* R/W: clear interrupts */
-
-/* PCI-1762 interrupt control registers */
-#define PCI1762_INT_REG 0x06 /* R/W: status/control */
-
-/* maximum number of subdevice descriptions in the boardinfo */
-#define PCI_DIO_MAX_DI_SUBDEVS 2 /* 2 x 8/16/32 input channels max */
-#define PCI_DIO_MAX_DO_SUBDEVS 2 /* 2 x 8/16/32 output channels max */
-#define PCI_DIO_MAX_DIO_SUBDEVG 2 /* 2 x any number of 8255 devices max */
-#define PCI_DIO_MAX_IRQ_SUBDEVS 4 /* 4 x 1 input IRQ channels max */
-
-enum pci_dio_boardid {
- TYPE_PCI1730,
- TYPE_PCI1733,
- TYPE_PCI1734,
- TYPE_PCI1735,
- TYPE_PCI1736,
- TYPE_PCI1739,
- TYPE_PCI1750,
- TYPE_PCI1751,
- TYPE_PCI1752,
- TYPE_PCI1753,
- TYPE_PCI1753E,
- TYPE_PCI1754,
- TYPE_PCI1756,
- TYPE_PCI1761,
- TYPE_PCI1762
-};
-
-struct diosubd_data {
- int chans; /* num of chans or 8255 devices */
- unsigned long addr; /* PCI address offset */
-};
-
-struct dio_irq_subd_data {
- unsigned short int_en; /* interrupt enable/status bit */
- unsigned long addr; /* PCI address offset */
-};
-
-struct dio_boardtype {
- const char *name; /* board name */
- int nsubdevs;
- struct diosubd_data sdi[PCI_DIO_MAX_DI_SUBDEVS];
- struct diosubd_data sdo[PCI_DIO_MAX_DO_SUBDEVS];
- struct diosubd_data sdio[PCI_DIO_MAX_DIO_SUBDEVG];
- struct dio_irq_subd_data sdirq[PCI_DIO_MAX_IRQ_SUBDEVS];
- unsigned long id_reg;
- unsigned long timer_regbase;
- unsigned int is_16bit:1;
-};
-
-static const struct dio_boardtype boardtypes[] = {
- [TYPE_PCI1730] = {
- .name = "pci1730",
- /* DI, IDI, DO, IDO, ID, IRQ_DI0, IRQ_DI1, IRQ_IDI0, IRQ_IDI1 */
- .nsubdevs = 9,
- .sdi[0] = { 16, 0x02, }, /* DI 0-15 */
- .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
- .sdo[0] = { 16, 0x02, }, /* DO 0-15 */
- .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
- .id_reg = 0x04,
- .sdirq[0] = { PCI173X_INT_DI0, 0x02, }, /* DI 0 */
- .sdirq[1] = { PCI173X_INT_DI1, 0x02, }, /* DI 1 */
- .sdirq[2] = { PCI173X_INT_IDI0, 0x00, }, /* ISO DI 0 */
- .sdirq[3] = { PCI173X_INT_IDI1, 0x00, }, /* ISO DI 1 */
- },
- [TYPE_PCI1733] = {
- .name = "pci1733",
- .nsubdevs = 2,
- .sdi[1] = { 32, 0x00, }, /* ISO DI 0-31 */
- .id_reg = 0x04,
- },
- [TYPE_PCI1734] = {
- .name = "pci1734",
- .nsubdevs = 2,
- .sdo[1] = { 32, 0x00, }, /* ISO DO 0-31 */
- .id_reg = 0x04,
- },
- [TYPE_PCI1735] = {
- .name = "pci1735",
- .nsubdevs = 4,
- .sdi[0] = { 32, 0x00, }, /* DI 0-31 */
- .sdo[0] = { 32, 0x00, }, /* DO 0-31 */
- .id_reg = 0x08,
- .timer_regbase = 0x04,
- },
- [TYPE_PCI1736] = {
- .name = "pci1736",
- .nsubdevs = 3,
- .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
- .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
- .id_reg = 0x04,
- },
- [TYPE_PCI1739] = {
- .name = "pci1739",
- .nsubdevs = 3,
- .sdio[0] = { 2, 0x00, }, /* 8255 DIO */
- .id_reg = 0x08,
- },
- [TYPE_PCI1750] = {
- .name = "pci1750",
- .nsubdevs = 2,
- .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
- .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
- },
- [TYPE_PCI1751] = {
- .name = "pci1751",
- .nsubdevs = 3,
- .sdio[0] = { 2, 0x00, }, /* 8255 DIO */
- .timer_regbase = 0x18,
- },
- [TYPE_PCI1752] = {
- .name = "pci1752",
- .nsubdevs = 3,
- .sdo[0] = { 32, 0x00, }, /* DO 0-31 */
- .sdo[1] = { 32, 0x04, }, /* DO 32-63 */
- .id_reg = 0x10,
- .is_16bit = 1,
- },
- [TYPE_PCI1753] = {
- .name = "pci1753",
- .nsubdevs = 4,
- .sdio[0] = { 4, 0x00, }, /* 8255 DIO */
- },
- [TYPE_PCI1753E] = {
- .name = "pci1753e",
- .nsubdevs = 8,
- .sdio[0] = { 4, 0x00, }, /* 8255 DIO */
- .sdio[1] = { 4, 0x20, }, /* 8255 DIO */
- },
- [TYPE_PCI1754] = {
- .name = "pci1754",
- .nsubdevs = 3,
- .sdi[0] = { 32, 0x00, }, /* DI 0-31 */
- .sdi[1] = { 32, 0x04, }, /* DI 32-63 */
- .id_reg = 0x10,
- .is_16bit = 1,
- },
- [TYPE_PCI1756] = {
- .name = "pci1756",
- .nsubdevs = 3,
- .sdi[1] = { 32, 0x00, }, /* DI 0-31 */
- .sdo[1] = { 32, 0x04, }, /* DO 0-31 */
- .id_reg = 0x10,
- .is_16bit = 1,
- },
- [TYPE_PCI1761] = {
- .name = "pci1761",
- .nsubdevs = 3,
- .sdi[1] = { 8, 0x01 }, /* ISO DI 0-7 */
- .sdo[1] = { 8, 0x00 }, /* RELAY DO 0-7 */
- .id_reg = 0x02,
- },
- [TYPE_PCI1762] = {
- .name = "pci1762",
- .nsubdevs = 3,
- .sdi[1] = { 16, 0x02, }, /* ISO DI 0-15 */
- .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
- .id_reg = 0x04,
- .is_16bit = 1,
- },
-};
-
-struct pci_dio_dev_private_data {
- int boardtype;
- int irq_subd;
- unsigned short int_ctrl;
- unsigned short int_rf;
-};
-
-struct pci_dio_sd_private_data {
- spinlock_t subd_slock; /* spin-lock for cmd_running */
- unsigned long port_offset;
- short int cmd_running;
-};
-
-static void process_irq(struct comedi_device *dev, unsigned int subdev,
- unsigned char irqflags)
-{
- struct comedi_subdevice *s = &dev->subdevices[subdev];
- struct pci_dio_sd_private_data *sd_priv = s->private;
- unsigned long reg = sd_priv->port_offset;
- struct comedi_async *async_p = s->async;
-
- if (async_p) {
- unsigned short val = inw(dev->iobase + reg);
-
- spin_lock(&sd_priv->subd_slock);
- if (sd_priv->cmd_running)
- comedi_buf_write_samples(s, &val, 1);
- spin_unlock(&sd_priv->subd_slock);
- comedi_handle_events(dev, s);
- }
-}
-
-static irqreturn_t pci_dio_interrupt(int irq, void *p_device)
-{
- struct comedi_device *dev = p_device;
- struct pci_dio_dev_private_data *dev_private = dev->private;
- const struct dio_boardtype *board = dev->board_ptr;
- unsigned long cpu_flags;
- unsigned char irqflags;
- int i;
-
- if (!dev->attached) {
- /* Ignore interrupt before device fully attached. */
- /* Might not even have allocated subdevices yet! */
- return IRQ_NONE;
- }
-
- /* Check if we are source of interrupt */
- spin_lock_irqsave(&dev->spinlock, cpu_flags);
- irqflags = inb(dev->iobase + PCI173X_INT_FLAG_REG);
- if (!(irqflags & 0x0F)) {
- spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
- return IRQ_NONE;
- }
-
- /* clear all current interrupt flags */
- outb(irqflags, dev->iobase + PCI173X_INT_CLR_REG);
- spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
-
- /* check irq subdevice triggers */
- for (i = 0; i < PCI_DIO_MAX_IRQ_SUBDEVS; i++) {
- if (irqflags & board->sdirq[i].int_en)
- process_irq(dev, dev_private->irq_subd + i, irqflags);
- }
-
- return IRQ_HANDLED;
-}
-
-static int pci_dio_asy_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- /*
- * For scan_begin_arg, the trigger number must be 0 and the only
- * allowed flags are CR_EDGE and CR_INVERT. CR_EDGE is ignored,
- * CR_INVERT sets the trigger to falling edge.
- */
- if (cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) {
- cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
- err |= -EINVAL;
- }
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int pci_dio_asy_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci_dio_dev_private_data *dev_private = dev->private;
- struct pci_dio_sd_private_data *sd_priv = s->private;
- const struct dio_boardtype *board = dev->board_ptr;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned long cpu_flags;
- unsigned short int_en;
-
- int_en = board->sdirq[s->index - dev_private->irq_subd].int_en;
-
- spin_lock_irqsave(&dev->spinlock, cpu_flags);
- if (cmd->scan_begin_arg & CR_INVERT)
- dev_private->int_rf |= int_en; /* falling edge */
- else
- dev_private->int_rf &= ~int_en; /* rising edge */
- outb(dev_private->int_rf, dev->iobase + PCI173X_INT_RF_REG);
- dev_private->int_ctrl |= int_en; /* enable interrupt source */
- outb(dev_private->int_ctrl, dev->iobase + PCI173X_INT_EN_REG);
- spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
-
- spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags);
- sd_priv->cmd_running = 1;
- spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags);
-
- return 0;
-}
-
-static int pci_dio_asy_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci_dio_dev_private_data *dev_private = dev->private;
- struct pci_dio_sd_private_data *sd_priv = s->private;
- const struct dio_boardtype *board = dev->board_ptr;
- unsigned long cpu_flags;
- unsigned short int_en;
-
- spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags);
- sd_priv->cmd_running = 0;
- spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags);
-
- int_en = board->sdirq[s->index - dev_private->irq_subd].int_en;
-
- spin_lock_irqsave(&dev->spinlock, cpu_flags);
- dev_private->int_ctrl &= ~int_en;
- outb(dev_private->int_ctrl, dev->iobase + PCI173X_INT_EN_REG);
- spin_unlock_irqrestore(&dev->spinlock, cpu_flags);
-
- return 0;
-}
-
-/* same as _insn_bits_di_ because the IRQ-pins are the DI-ports */
-static int pci_dio_insn_bits_dirq_b(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pci_dio_sd_private_data *sd_priv = s->private;
- unsigned long reg = (unsigned long)sd_priv->port_offset;
- unsigned long iobase = dev->iobase + reg;
-
- data[1] = inb(iobase);
-
- return insn->n;
-}
-
-static int pci_dio_insn_bits_di_b(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long reg = (unsigned long)s->private;
- unsigned long iobase = dev->iobase + reg;
-
- data[1] = inb(iobase);
- if (s->n_chan > 8)
- data[1] |= (inb(iobase + 1) << 8);
- if (s->n_chan > 16)
- data[1] |= (inb(iobase + 2) << 16);
- if (s->n_chan > 24)
- data[1] |= (inb(iobase + 3) << 24);
-
- return insn->n;
-}
-
-static int pci_dio_insn_bits_di_w(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long reg = (unsigned long)s->private;
- unsigned long iobase = dev->iobase + reg;
-
- data[1] = inw(iobase);
- if (s->n_chan > 16)
- data[1] |= (inw(iobase + 2) << 16);
-
- return insn->n;
-}
-
-static int pci_dio_insn_bits_do_b(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long reg = (unsigned long)s->private;
- unsigned long iobase = dev->iobase + reg;
-
- if (comedi_dio_update_state(s, data)) {
- outb(s->state & 0xff, iobase);
- if (s->n_chan > 8)
- outb((s->state >> 8) & 0xff, iobase + 1);
- if (s->n_chan > 16)
- outb((s->state >> 16) & 0xff, iobase + 2);
- if (s->n_chan > 24)
- outb((s->state >> 24) & 0xff, iobase + 3);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long reg = (unsigned long)s->private;
- unsigned long iobase = dev->iobase + reg;
-
- if (comedi_dio_update_state(s, data)) {
- outw(s->state & 0xffff, iobase);
- if (s->n_chan > 16)
- outw((s->state >> 16) & 0xffff, iobase + 2);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pci_dio_reset(struct comedi_device *dev, unsigned long cardtype)
-{
- struct pci_dio_dev_private_data *dev_private = dev->private;
- /* disable channel freeze function on the PCI-1752/1756 boards */
- if (cardtype == TYPE_PCI1752 || cardtype == TYPE_PCI1756)
- outw(0, dev->iobase + PCI1752_CFC_REG);
-
- /* disable and clear interrupts */
- switch (cardtype) {
- case TYPE_PCI1730:
- case TYPE_PCI1733:
- case TYPE_PCI1736:
- dev_private->int_ctrl = 0x00;
- outb(dev_private->int_ctrl, dev->iobase + PCI173X_INT_EN_REG);
- /* Reset all 4 Int Flags */
- outb(0x0f, dev->iobase + PCI173X_INT_CLR_REG);
- /* Rising Edge => IRQ . On all 4 Pins */
- dev_private->int_rf = 0x00;
- outb(dev_private->int_rf, dev->iobase + PCI173X_INT_RF_REG);
- break;
- case TYPE_PCI1739:
- case TYPE_PCI1750:
- case TYPE_PCI1751:
- outb(0x88, dev->iobase + PCI1750_INT_REG);
- break;
- case TYPE_PCI1753:
- case TYPE_PCI1753E:
- outb(0x88, dev->iobase + PCI1753_INT_REG(0));
- outb(0x80, dev->iobase + PCI1753_INT_REG(1));
- outb(0x80, dev->iobase + PCI1753_INT_REG(2));
- outb(0x80, dev->iobase + PCI1753_INT_REG(3));
- if (cardtype == TYPE_PCI1753E) {
- outb(0x88, dev->iobase + PCI1753E_INT_REG(0));
- outb(0x80, dev->iobase + PCI1753E_INT_REG(1));
- outb(0x80, dev->iobase + PCI1753E_INT_REG(2));
- outb(0x80, dev->iobase + PCI1753E_INT_REG(3));
- }
- break;
- case TYPE_PCI1754:
- case TYPE_PCI1756:
- outw(0x08, dev->iobase + PCI1754_INT_REG(0));
- outw(0x08, dev->iobase + PCI1754_INT_REG(1));
- if (cardtype == TYPE_PCI1754) {
- outw(0x08, dev->iobase + PCI1754_INT_REG(2));
- outw(0x08, dev->iobase + PCI1754_INT_REG(3));
- }
- break;
- case TYPE_PCI1761:
- /* disable interrupts */
- outb(0, dev->iobase + PCI1761_INT_EN_REG);
- /* clear interrupts */
- outb(0xff, dev->iobase + PCI1761_INT_CLR_REG);
- /* set rising edge trigger */
- outb(0, dev->iobase + PCI1761_INT_RF_REG);
- break;
- case TYPE_PCI1762:
- outw(0x0101, dev->iobase + PCI1762_INT_REG);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int pci_dio_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct dio_boardtype *board = NULL;
- struct comedi_subdevice *s;
- struct pci_dio_dev_private_data *dev_private;
- int ret, subdev, i, j;
-
- if (context < ARRAY_SIZE(boardtypes))
- board = &boardtypes[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- dev_private = comedi_alloc_devpriv(dev, sizeof(*dev_private));
- if (!dev_private)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- if (context == TYPE_PCI1736)
- dev->iobase = pci_resource_start(pcidev, 0);
- else
- dev->iobase = pci_resource_start(pcidev, 2);
-
- dev_private->boardtype = context;
- pci_dio_reset(dev, context);
-
- /* request IRQ if device has irq subdevices */
- if (board->sdirq[0].int_en && pcidev->irq) {
- ret = request_irq(pcidev->irq, pci_dio_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, board->nsubdevs);
- if (ret)
- return ret;
-
- subdev = 0;
- for (i = 0; i < PCI_DIO_MAX_DI_SUBDEVS; i++) {
- const struct diosubd_data *d = &board->sdi[i];
-
- if (d->chans) {
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = d->chans;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = board->is_16bit
- ? pci_dio_insn_bits_di_w
- : pci_dio_insn_bits_di_b;
- s->private = (void *)d->addr;
- }
- }
-
- for (i = 0; i < PCI_DIO_MAX_DO_SUBDEVS; i++) {
- const struct diosubd_data *d = &board->sdo[i];
-
- if (d->chans) {
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = d->chans;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = board->is_16bit
- ? pci_dio_insn_bits_do_w
- : pci_dio_insn_bits_do_b;
- s->private = (void *)d->addr;
-
- /* reset all outputs to 0 */
- if (board->is_16bit) {
- outw(0, dev->iobase + d->addr);
- if (s->n_chan > 16)
- outw(0, dev->iobase + d->addr + 2);
- } else {
- outb(0, dev->iobase + d->addr);
- if (s->n_chan > 8)
- outb(0, dev->iobase + d->addr + 1);
- if (s->n_chan > 16)
- outb(0, dev->iobase + d->addr + 2);
- if (s->n_chan > 24)
- outb(0, dev->iobase + d->addr + 3);
- }
- }
- }
-
- for (i = 0; i < PCI_DIO_MAX_DIO_SUBDEVG; i++) {
- const struct diosubd_data *d = &board->sdio[i];
-
- for (j = 0; j < d->chans; j++) {
- s = &dev->subdevices[subdev++];
- ret = subdev_8255_init(dev, s, NULL,
- d->addr + j * I8255_SIZE);
- if (ret)
- return ret;
- }
- }
-
- if (board->id_reg) {
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = board->is_16bit ? pci_dio_insn_bits_di_w
- : pci_dio_insn_bits_di_b;
- s->private = (void *)board->id_reg;
- }
-
- if (board->timer_regbase) {
- s = &dev->subdevices[subdev++];
-
- dev->pacer = comedi_8254_init(dev->iobase +
- board->timer_regbase,
- 0, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- comedi_8254_subdevice_init(s, dev->pacer);
- }
-
- dev_private->irq_subd = subdev; /* first interrupt subdevice index */
- for (i = 0; i < PCI_DIO_MAX_IRQ_SUBDEVS; ++i) {
- struct pci_dio_sd_private_data *sd_priv = NULL;
- const struct dio_irq_subd_data *d = &board->sdirq[i];
-
- if (d->int_en) {
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci_dio_insn_bits_dirq_b;
- sd_priv = comedi_alloc_spriv(s, sizeof(*sd_priv));
- if (!sd_priv)
- return -ENOMEM;
-
- spin_lock_init(&sd_priv->subd_slock);
- sd_priv->port_offset = d->addr;
- sd_priv->cmd_running = 0;
-
- if (dev->irq) {
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->len_chanlist = 1;
- s->do_cmdtest = pci_dio_asy_cmdtest;
- s->do_cmd = pci_dio_asy_cmd;
- s->cancel = pci_dio_asy_cancel;
- }
- }
- }
-
- return 0;
-}
-
-static void pci_dio_detach(struct comedi_device *dev)
-{
- struct pci_dio_dev_private_data *dev_private = dev->private;
- int boardtype = dev_private->boardtype;
-
- if (dev->iobase)
- pci_dio_reset(dev, boardtype);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver adv_pci_dio_driver = {
- .driver_name = "adv_pci_dio",
- .module = THIS_MODULE,
- .auto_attach = pci_dio_auto_attach,
- .detach = pci_dio_detach,
-};
-
-static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev,
- unsigned long cardtype)
-{
- /*
- * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion
- * board available. Need to enable PCI device and request the main
- * registers PCI BAR temporarily to perform the test.
- */
- if (cardtype != TYPE_PCI1753)
- return cardtype;
- if (pci_enable_device(pcidev) < 0)
- return cardtype;
- if (pci_request_region(pcidev, 2, "adv_pci_dio") == 0) {
- /*
- * This test is based on Advantech's "advdaq" driver source
- * (which declares its module licence as "GPL" although the
- * driver source does not include a "COPYING" file).
- */
- unsigned long reg = pci_resource_start(pcidev, 2) + 53;
-
- outb(0x05, reg);
- if ((inb(reg) & 0x07) == 0x02) {
- outb(0x02, reg);
- if ((inb(reg) & 0x07) == 0x05)
- cardtype = TYPE_PCI1753E;
- }
- pci_release_region(pcidev, 2);
- }
- pci_disable_device(pcidev);
- return cardtype;
-}
-
-static int adv_pci_dio_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- unsigned long cardtype;
-
- cardtype = pci_dio_override_cardtype(dev, id->driver_data);
- return comedi_pci_auto_config(dev, &adv_pci_dio_driver, cardtype);
-}
-
-static const struct pci_device_id adv_pci_dio_pci_table[] = {
- { PCI_VDEVICE(ADVANTECH, 0x1730), TYPE_PCI1730 },
- { PCI_VDEVICE(ADVANTECH, 0x1733), TYPE_PCI1733 },
- { PCI_VDEVICE(ADVANTECH, 0x1734), TYPE_PCI1734 },
- { PCI_VDEVICE(ADVANTECH, 0x1735), TYPE_PCI1735 },
- { PCI_VDEVICE(ADVANTECH, 0x1736), TYPE_PCI1736 },
- { PCI_VDEVICE(ADVANTECH, 0x1739), TYPE_PCI1739 },
- { PCI_VDEVICE(ADVANTECH, 0x1750), TYPE_PCI1750 },
- { PCI_VDEVICE(ADVANTECH, 0x1751), TYPE_PCI1751 },
- { PCI_VDEVICE(ADVANTECH, 0x1752), TYPE_PCI1752 },
- { PCI_VDEVICE(ADVANTECH, 0x1753), TYPE_PCI1753 },
- { PCI_VDEVICE(ADVANTECH, 0x1754), TYPE_PCI1754 },
- { PCI_VDEVICE(ADVANTECH, 0x1756), TYPE_PCI1756 },
- { PCI_VDEVICE(ADVANTECH, 0x1761), TYPE_PCI1761 },
- { PCI_VDEVICE(ADVANTECH, 0x1762), TYPE_PCI1762 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, adv_pci_dio_pci_table);
-
-static struct pci_driver adv_pci_dio_pci_driver = {
- .name = "adv_pci_dio",
- .id_table = adv_pci_dio_pci_table,
- .probe = adv_pci_dio_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Advantech Digital I/O Cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
deleted file mode 100644
index 4829115921a3..000000000000
--- a/drivers/staging/comedi/drivers/aio_aio12_8.c
+++ /dev/null
@@ -1,277 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * aio_aio12_8.c
- * Driver for Access I/O Products PC-104 AIO12-8 Analog I/O Board
- * Copyright (C) 2006 C&C Technologies, Inc.
- */
-
-/*
- * Driver: aio_aio12_8
- * Description: Access I/O Products PC-104 AIO12-8 Analog I/O Board
- * Author: Pablo Mejia <pablo.mejia@cctechnol.com>
- * Devices: [Access I/O] PC-104 AIO12-8 (aio_aio12_8),
- * [Access I/O] PC-104 AI12-8 (aio_ai12_8),
- * [Access I/O] PC-104 AO12-4 (aio_ao12_4)
- * Status: experimental
- *
- * Configuration Options:
- * [0] - I/O port base address
- *
- * Notes:
- * Only synchronous operations are supported.
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include "comedi_8254.h"
-#include "8255.h"
-
-/*
- * Register map
- */
-#define AIO12_8_STATUS_REG 0x00
-#define AIO12_8_STATUS_ADC_EOC BIT(7)
-#define AIO12_8_STATUS_PORT_C_COS BIT(6)
-#define AIO12_8_STATUS_IRQ_ENA BIT(2)
-#define AIO12_8_INTERRUPT_REG 0x01
-#define AIO12_8_INTERRUPT_ADC BIT(7)
-#define AIO12_8_INTERRUPT_COS BIT(6)
-#define AIO12_8_INTERRUPT_COUNTER1 BIT(5)
-#define AIO12_8_INTERRUPT_PORT_C3 BIT(4)
-#define AIO12_8_INTERRUPT_PORT_C0 BIT(3)
-#define AIO12_8_INTERRUPT_ENA BIT(2)
-#define AIO12_8_ADC_REG 0x02
-#define AIO12_8_ADC_MODE(x) (((x) & 0x3) << 6)
-#define AIO12_8_ADC_MODE_NORMAL AIO12_8_ADC_MODE(0)
-#define AIO12_8_ADC_MODE_INT_CLK AIO12_8_ADC_MODE(1)
-#define AIO12_8_ADC_MODE_STANDBY AIO12_8_ADC_MODE(2)
-#define AIO12_8_ADC_MODE_POWERDOWN AIO12_8_ADC_MODE(3)
-#define AIO12_8_ADC_ACQ(x) (((x) & 0x1) << 5)
-#define AIO12_8_ADC_ACQ_3USEC AIO12_8_ADC_ACQ(0)
-#define AIO12_8_ADC_ACQ_PROGRAM AIO12_8_ADC_ACQ(1)
-#define AIO12_8_ADC_RANGE(x) ((x) << 3)
-#define AIO12_8_ADC_CHAN(x) ((x) << 0)
-#define AIO12_8_DAC_REG(x) (0x04 + (x) * 2)
-#define AIO12_8_8254_BASE_REG 0x0c
-#define AIO12_8_8255_BASE_REG 0x10
-#define AIO12_8_DIO_CONTROL_REG 0x14
-#define AIO12_8_DIO_CONTROL_TST BIT(0)
-#define AIO12_8_ADC_TRIGGER_REG 0x15
-#define AIO12_8_ADC_TRIGGER_RANGE(x) ((x) << 3)
-#define AIO12_8_ADC_TRIGGER_CHAN(x) ((x) << 0)
-#define AIO12_8_TRIGGER_REG 0x16
-#define AIO12_8_TRIGGER_ADTRIG BIT(1)
-#define AIO12_8_TRIGGER_DACTRIG BIT(0)
-#define AIO12_8_COS_REG 0x17
-#define AIO12_8_DAC_ENABLE_REG 0x18
-#define AIO12_8_DAC_ENABLE_REF_ENA BIT(0)
-
-static const struct comedi_lrange aio_aio12_8_range = {
- 4, {
- UNI_RANGE(5),
- BIP_RANGE(5),
- UNI_RANGE(10),
- BIP_RANGE(10)
- }
-};
-
-struct aio12_8_boardtype {
- const char *name;
- unsigned int has_ai:1;
- unsigned int has_ao:1;
-};
-
-static const struct aio12_8_boardtype board_types[] = {
- {
- .name = "aio_aio12_8",
- .has_ai = 1,
- .has_ao = 1,
- }, {
- .name = "aio_ai12_8",
- .has_ai = 1,
- }, {
- .name = "aio_ao12_4",
- .has_ao = 1,
- },
-};
-
-static int aio_aio12_8_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + AIO12_8_STATUS_REG);
- if (status & AIO12_8_STATUS_ADC_EOC)
- return 0;
- return -EBUSY;
-}
-
-static int aio_aio12_8_ai_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- unsigned char control;
- int ret;
- int i;
-
- /*
- * Setup the control byte for internal 2MHz clock, 3uS conversion,
- * at the desired range of the requested channel.
- */
- control = AIO12_8_ADC_MODE_NORMAL | AIO12_8_ADC_ACQ_3USEC |
- AIO12_8_ADC_RANGE(range) | AIO12_8_ADC_CHAN(chan);
-
- /* Read status to clear EOC latch */
- inb(dev->iobase + AIO12_8_STATUS_REG);
-
- for (i = 0; i < insn->n; i++) {
- /* Setup and start conversion */
- outb(control, dev->iobase + AIO12_8_ADC_REG);
-
- /* Wait for conversion to complete */
- ret = comedi_timeout(dev, s, insn, aio_aio12_8_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inw(dev->iobase + AIO12_8_ADC_REG) & s->maxdata;
-
- /* munge bipolar 2's complement data to offset binary */
- if (comedi_range_is_bipolar(s, range))
- val = comedi_offset_munge(s, val);
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int aio_aio12_8_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- /* enable DACs */
- outb(AIO12_8_DAC_ENABLE_REF_ENA, dev->iobase + AIO12_8_DAC_ENABLE_REG);
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outw(val, dev->iobase + AIO12_8_DAC_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int aio_aio12_8_counter_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- switch (data[0]) {
- case INSN_CONFIG_GET_CLOCK_SRC:
- /*
- * Channels 0 and 2 have external clock sources.
- * Channel 1 has a fixed 1 MHz clock source.
- */
- data[0] = 0;
- data[1] = (chan == 1) ? I8254_OSC_BASE_1MHZ : 0;
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int aio_aio12_8_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct aio12_8_boardtype *board = dev->board_ptr;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 32);
- if (ret)
- return ret;
-
- dev->pacer = comedi_8254_init(dev->iobase + AIO12_8_8254_BASE_REG,
- 0, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- if (board->has_ai) {
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 8;
- s->maxdata = 0x0fff;
- s->range_table = &aio_aio12_8_range;
- s->insn_read = aio_aio12_8_ai_read;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = 4;
- s->maxdata = 0x0fff;
- s->range_table = &aio_aio12_8_range;
- s->insn_write = aio_aio12_8_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital I/O subdevice (8255) */
- s = &dev->subdevices[2];
- ret = subdev_8255_init(dev, s, NULL, AIO12_8_8255_BASE_REG);
- if (ret)
- return ret;
-
- /* Counter subdevice (8254) */
- s = &dev->subdevices[3];
- comedi_8254_subdevice_init(s, dev->pacer);
-
- dev->pacer->insn_config = aio_aio12_8_counter_insn_config;
-
- return 0;
-}
-
-static struct comedi_driver aio_aio12_8_driver = {
- .driver_name = "aio_aio12_8",
- .module = THIS_MODULE,
- .attach = aio_aio12_8_attach,
- .detach = comedi_legacy_detach,
- .board_name = &board_types[0].name,
- .num_names = ARRAY_SIZE(board_types),
- .offset = sizeof(struct aio12_8_boardtype),
-};
-module_comedi_driver(aio_aio12_8_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Access I/O AIO12-8 Analog I/O Board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
deleted file mode 100644
index fe3876235075..000000000000
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ /dev/null
@@ -1,235 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * aio_iiro_16.c
- * Comedi driver for Access I/O Products 104-IIRO-16 board
- * Copyright (C) 2006 C&C Technologies, Inc.
- */
-
-/*
- * Driver: aio_iiro_16
- * Description: Access I/O Products PC/104 Isolated Input/Relay Output Board
- * Author: Zachary Ware <zach.ware@cctechnol.com>
- * Devices: [Access I/O] 104-IIRO-16 (aio_iiro_16)
- * Status: experimental
- *
- * Configuration Options:
- * [0] - I/O port base address
- * [1] - IRQ (optional)
- *
- * The board supports interrupts on change of state of the digital inputs.
- * The sample data returned by the async command indicates which inputs
- * changed state and the current state of the inputs:
- *
- * Bit 23 - IRQ Enable (1) / Disable (0)
- * Bit 17 - Input 8-15 Changed State (1 = Changed, 0 = No Change)
- * Bit 16 - Input 0-7 Changed State (1 = Changed, 0 = No Change)
- * Bit 15 - Digital input 15
- * ...
- * Bit 0 - Digital input 0
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#define AIO_IIRO_16_RELAY_0_7 0x00
-#define AIO_IIRO_16_INPUT_0_7 0x01
-#define AIO_IIRO_16_IRQ 0x02
-#define AIO_IIRO_16_RELAY_8_15 0x04
-#define AIO_IIRO_16_INPUT_8_15 0x05
-#define AIO_IIRO_16_STATUS 0x07
-#define AIO_IIRO_16_STATUS_IRQE BIT(7)
-#define AIO_IIRO_16_STATUS_INPUT_8_15 BIT(1)
-#define AIO_IIRO_16_STATUS_INPUT_0_7 BIT(0)
-
-static unsigned int aio_iiro_16_read_inputs(struct comedi_device *dev)
-{
- unsigned int val;
-
- val = inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
- val |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
-
- return val;
-}
-
-static irqreturn_t aio_iiro_16_cos(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int status;
- unsigned int val;
-
- status = inb(dev->iobase + AIO_IIRO_16_STATUS);
- if (!(status & AIO_IIRO_16_STATUS_IRQE))
- return IRQ_NONE;
-
- val = aio_iiro_16_read_inputs(dev);
- val |= (status << 16);
-
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static void aio_iiro_enable_irq(struct comedi_device *dev, bool enable)
-{
- if (enable)
- inb(dev->iobase + AIO_IIRO_16_IRQ);
- else
- outb(0, dev->iobase + AIO_IIRO_16_IRQ);
-}
-
-static int aio_iiro_16_cos_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- aio_iiro_enable_irq(dev, false);
-
- return 0;
-}
-
-static int aio_iiro_16_cos_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- aio_iiro_enable_irq(dev, true);
-
- return 0;
-}
-
-static int aio_iiro_16_cos_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int aio_iiro_16_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
- outb((s->state >> 8) & 0xff,
- dev->iobase + AIO_IIRO_16_RELAY_8_15);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int aio_iiro_16_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = aio_iiro_16_read_inputs(dev);
-
- return insn->n;
-}
-
-static int aio_iiro_16_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x8);
- if (ret)
- return ret;
-
- aio_iiro_enable_irq(dev, false);
-
- /*
- * Digital input change of state interrupts are optionally supported
- * using IRQ 2-7, 10-12, 14, or 15.
- */
- if ((1 << it->options[1]) & 0xdcfc) {
- ret = request_irq(it->options[1], aio_iiro_16_cos, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = aio_iiro_16_do_insn_bits;
-
- /* get the initial state of the relays */
- s->state = inb(dev->iobase + AIO_IIRO_16_RELAY_0_7) |
- (inb(dev->iobase + AIO_IIRO_16_RELAY_8_15) << 8);
-
- /* Digital Input subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = aio_iiro_16_di_insn_bits;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL;
- s->len_chanlist = 1;
- s->do_cmdtest = aio_iiro_16_cos_cmdtest;
- s->do_cmd = aio_iiro_16_cos_cmd;
- s->cancel = aio_iiro_16_cos_cancel;
- }
-
- return 0;
-}
-
-static struct comedi_driver aio_iiro_16_driver = {
- .driver_name = "aio_iiro_16",
- .module = THIS_MODULE,
- .attach = aio_iiro_16_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(aio_iiro_16_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Access I/O Products 104-IIRO-16 board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h
deleted file mode 100644
index f738b91b2052..000000000000
--- a/drivers/staging/comedi/drivers/amcc_s5933.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Stuff for AMCC S5933 PCI Controller
- *
- * Author: Michal Dobes <dobes@tesnet.cz>
- *
- * Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
- * made by Andrea Cisternino <acister@pcape1.pi.infn.it>
- * and as result of espionage from MITE code made by David A. Schleef.
- * Thanks to AMCC for their on-line documentation and bus master DMA
- * example.
- */
-
-#ifndef _AMCC_S5933_H_
-#define _AMCC_S5933_H_
-
-/****************************************************************************/
-/* AMCC Operation Register Offsets - PCI */
-/****************************************************************************/
-
-#define AMCC_OP_REG_OMB1 0x00
-#define AMCC_OP_REG_OMB2 0x04
-#define AMCC_OP_REG_OMB3 0x08
-#define AMCC_OP_REG_OMB4 0x0c
-#define AMCC_OP_REG_IMB1 0x10
-#define AMCC_OP_REG_IMB2 0x14
-#define AMCC_OP_REG_IMB3 0x18
-#define AMCC_OP_REG_IMB4 0x1c
-#define AMCC_OP_REG_FIFO 0x20
-#define AMCC_OP_REG_MWAR 0x24
-#define AMCC_OP_REG_MWTC 0x28
-#define AMCC_OP_REG_MRAR 0x2c
-#define AMCC_OP_REG_MRTC 0x30
-#define AMCC_OP_REG_MBEF 0x34
-#define AMCC_OP_REG_INTCSR 0x38
-#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
-#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
-#define AMCC_OP_REG_MCSR 0x3c
-#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
-#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
-
-#define AMCC_FIFO_DEPTH_DWORD 8
-#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32))
-
-/****************************************************************************/
-/* AMCC - PCI Interrupt Control/Status Register */
-/****************************************************************************/
-#define INTCSR_OUTBOX_BYTE(x) ((x) & 0x3)
-#define INTCSR_OUTBOX_SELECT(x) (((x) & 0x3) << 2)
-#define INTCSR_OUTBOX_EMPTY_INT 0x10 /* enable outbox empty interrupt */
-#define INTCSR_INBOX_BYTE(x) (((x) & 0x3) << 8)
-#define INTCSR_INBOX_SELECT(x) (((x) & 0x3) << 10)
-#define INTCSR_INBOX_FULL_INT 0x1000 /* enable inbox full interrupt */
-/* read, or write clear inbox full interrupt */
-#define INTCSR_INBOX_INTR_STATUS 0x20000
-/* read only, interrupt asserted */
-#define INTCSR_INTR_ASSERTED 0x800000
-
-/****************************************************************************/
-/* AMCC - PCI non-volatile ram command register (byte 3 of AMCC_OP_REG_MCSR) */
-/****************************************************************************/
-#define MCSR_NV_LOAD_LOW_ADDR 0x0
-#define MCSR_NV_LOAD_HIGH_ADDR 0x20
-#define MCSR_NV_WRITE 0x40
-#define MCSR_NV_READ 0x60
-#define MCSR_NV_MASK 0x60
-#define MCSR_NV_ENABLE 0x80
-#define MCSR_NV_BUSY MCSR_NV_ENABLE
-
-/****************************************************************************/
-/* AMCC Operation Registers Size - PCI */
-/****************************************************************************/
-
-#define AMCC_OP_REG_SIZE 64 /* in bytes */
-
-/****************************************************************************/
-/* AMCC Operation Register Offsets - Add-on */
-/****************************************************************************/
-
-#define AMCC_OP_REG_AIMB1 0x00
-#define AMCC_OP_REG_AIMB2 0x04
-#define AMCC_OP_REG_AIMB3 0x08
-#define AMCC_OP_REG_AIMB4 0x0c
-#define AMCC_OP_REG_AOMB1 0x10
-#define AMCC_OP_REG_AOMB2 0x14
-#define AMCC_OP_REG_AOMB3 0x18
-#define AMCC_OP_REG_AOMB4 0x1c
-#define AMCC_OP_REG_AFIFO 0x20
-#define AMCC_OP_REG_AMWAR 0x24
-#define AMCC_OP_REG_APTA 0x28
-#define AMCC_OP_REG_APTD 0x2c
-#define AMCC_OP_REG_AMRAR 0x30
-#define AMCC_OP_REG_AMBEF 0x34
-#define AMCC_OP_REG_AINT 0x38
-#define AMCC_OP_REG_AGCSTS 0x3c
-#define AMCC_OP_REG_AMWTC 0x58
-#define AMCC_OP_REG_AMRTC 0x5c
-
-/****************************************************************************/
-/* AMCC - Add-on General Control/Status Register */
-/****************************************************************************/
-
-#define AGCSTS_CONTROL_MASK 0xfffff000
-#define AGCSTS_NV_ACC_MASK 0xe0000000
-#define AGCSTS_RESET_MASK 0x0e000000
-#define AGCSTS_NV_DA_MASK 0x00ff0000
-#define AGCSTS_BIST_MASK 0x0000f000
-#define AGCSTS_STATUS_MASK 0x000000ff
-#define AGCSTS_TCZERO_MASK 0x000000c0
-#define AGCSTS_FIFO_ST_MASK 0x0000003f
-
-#define AGCSTS_TC_ENABLE 0x10000000
-
-#define AGCSTS_RESET_MBFLAGS 0x08000000
-#define AGCSTS_RESET_P2A_FIFO 0x04000000
-#define AGCSTS_RESET_A2P_FIFO 0x02000000
-#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
-
-#define AGCSTS_A2P_TCOUNT 0x00000080
-#define AGCSTS_P2A_TCOUNT 0x00000040
-
-#define AGCSTS_FS_P2A_EMPTY 0x00000020
-#define AGCSTS_FS_P2A_HALF 0x00000010
-#define AGCSTS_FS_P2A_FULL 0x00000008
-
-#define AGCSTS_FS_A2P_EMPTY 0x00000004
-#define AGCSTS_FS_A2P_HALF 0x00000002
-#define AGCSTS_FS_A2P_FULL 0x00000001
-
-/****************************************************************************/
-/* AMCC - Add-on Interrupt Control/Status Register */
-/****************************************************************************/
-
-#define AINT_INT_MASK 0x00ff0000
-#define AINT_SEL_MASK 0x0000ffff
-#define AINT_IS_ENSEL_MASK 0x00001f1f
-
-#define AINT_INT_ASSERTED 0x00800000
-#define AINT_BM_ERROR 0x00200000
-#define AINT_BIST_INT 0x00100000
-
-#define AINT_RT_COMPLETE 0x00080000
-#define AINT_WT_COMPLETE 0x00040000
-
-#define AINT_OUT_MB_INT 0x00020000
-#define AINT_IN_MB_INT 0x00010000
-
-#define AINT_READ_COMPL 0x00008000
-#define AINT_WRITE_COMPL 0x00004000
-
-#define AINT_OMB_ENABLE 0x00001000
-#define AINT_OMB_SELECT 0x00000c00
-#define AINT_OMB_BYTE 0x00000300
-
-#define AINT_IMB_ENABLE 0x00000010
-#define AINT_IMB_SELECT 0x0000000c
-#define AINT_IMB_BYTE 0x00000003
-
-/* these are bits from various different registers, needs cleanup XXX */
-/* Enable Bus Mastering */
-#define EN_A2P_TRANSFERS 0x00000400
-/* FIFO Flag Reset */
-#define RESET_A2P_FLAGS 0x04000000L
-/* FIFO Relative Priority */
-#define A2P_HI_PRIORITY 0x00000100L
-/* Identify Interrupt Sources */
-#define ANY_S593X_INT 0x00800000L
-#define READ_TC_INT 0x00080000L
-#define WRITE_TC_INT 0x00040000L
-#define IN_MB_INT 0x00020000L
-#define MASTER_ABORT_INT 0x00100000L
-#define TARGET_ABORT_INT 0x00200000L
-#define BUS_MASTER_INT 0x00200000L
-
-#endif
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
deleted file mode 100644
index fa19c9e7c56b..000000000000
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ /dev/null
@@ -1,265 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/amplc_dio200.c
- *
- * Driver for Amplicon PC212E, PC214E, PC215E, PC218E, PC272E.
- *
- * Copyright (C) 2005-2013 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: amplc_dio200
- * Description: Amplicon 200 Series ISA Digital I/O
- * Author: Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
- * PC218E (pc218e), PC272E (pc272e)
- * Updated: Mon, 18 Mar 2013 14:40:41 +0000
- *
- * Status: works
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (optional, but commands won't work without it)
- *
- * Passing a zero for an option is the same as leaving it unspecified.
- *
- * SUBDEVICES
- *
- * PC212E PC214E PC215E
- * ------------- ------------- -------------
- * Subdevices 6 4 5
- * 0 PPI-X PPI-X PPI-X
- * 1 CTR-Y1 PPI-Y PPI-Y
- * 2 CTR-Y2 CTR-Z1* CTR-Z1
- * 3 CTR-Z1 INTERRUPT* CTR-Z2
- * 4 CTR-Z2 INTERRUPT
- * 5 INTERRUPT
- *
- * PC218E PC272E
- * ------------- -------------
- * Subdevices 7 4
- * 0 CTR-X1 PPI-X
- * 1 CTR-X2 PPI-Y
- * 2 CTR-Y1 PPI-Z
- * 3 CTR-Y2 INTERRUPT
- * 4 CTR-Z1
- * 5 CTR-Z2
- * 6 INTERRUPT
- *
- * Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
- * are configurable as inputs or outputs in four groups:
- *
- * Port A - channels 0 to 7
- * Port B - channels 8 to 15
- * Port CL - channels 16 to 19
- * Port CH - channels 20 to 23
- *
- * Only mode 0 of the 8255 chips is supported.
- *
- * Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
- * channel is configured individually with INSN_CONFIG instructions. The
- * specific type of configuration instruction is specified in data[0].
- * Some configuration instructions expect an additional parameter in
- * data[1]; others return a value in data[1]. The following configuration
- * instructions are supported:
- *
- * INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
- * BCD/binary setting specified in data[1].
- *
- * INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
- * counter channel into data[1].
- *
- * INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
- * specified in data[1] (this is a hardware-specific value). Not
- * supported on PC214E. For the other boards, valid clock sources are
- * 0 to 7 as follows:
- *
- * 0. CLK n, the counter channel's dedicated CLK input from the SK1
- * connector. (N.B. for other values, the counter channel's CLKn
- * pin on the SK1 connector is an output!)
- * 1. Internal 10 MHz clock.
- * 2. Internal 1 MHz clock.
- * 3. Internal 100 kHz clock.
- * 4. Internal 10 kHz clock.
- * 5. Internal 1 kHz clock.
- * 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
- * 7. Ext Clock, the counter chip's dedicated Ext Clock input from
- * the SK1 connector. This pin is shared by all three counter
- * channels on the chip.
- *
- * INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
- * clock source in data[1]. For internal clock sources, data[2] is set
- * to the period in ns.
- *
- * INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
- * specified in data[2] (this is a hardware-specific value). Not
- * supported on PC214E. For the other boards, valid gate sources are 0
- * to 7 as follows:
- *
- * 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
- * 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
- * 2. GAT n, the counter channel's dedicated GAT input from the SK1
- * connector. (N.B. for other values, the counter channel's GATn
- * pin on the SK1 connector is an output!)
- * 3. /OUT n-2, the inverted output of counter channel n-2 (see note
- * 2 below).
- * 4. Reserved.
- * 5. Reserved.
- * 6. Reserved.
- * 7. Reserved.
- *
- * INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
- * source in data[2].
- *
- * Clock and gate interconnection notes:
- *
- * 1. Clock source OUT n-1 is the output of the preceding channel on the
- * same counter subdevice if n > 0, or the output of channel 2 on the
- * preceding counter subdevice (see note 3) if n = 0.
- *
- * 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
- * same counter subdevice if n = 2, or the inverted output of channel n+1
- * on the preceding counter subdevice (see note 3) if n < 2.
- *
- * 3. The counter subdevices are connected in a ring, so the highest
- * counter subdevice precedes the lowest.
- *
- * The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
- * digital inputs come from the interrupt status register. The number of
- * channels matches the number of interrupt sources. The PC214E does not
- * have an interrupt status register; see notes on 'INTERRUPT SOURCES'
- * below.
- *
- * INTERRUPT SOURCES
- *
- * PC212E PC214E PC215E
- * ------------- ------------- -------------
- * Sources 6 1 6
- * 0 PPI-X-C0 JUMPER-J5 PPI-X-C0
- * 1 PPI-X-C3 PPI-X-C3
- * 2 CTR-Y1-OUT1 PPI-Y-C0
- * 3 CTR-Y2-OUT1 PPI-Y-C3
- * 4 CTR-Z1-OUT1 CTR-Z1-OUT1
- * 5 CTR-Z2-OUT1 CTR-Z2-OUT1
- *
- * PC218E PC272E
- * ------------- -------------
- * Sources 6 6
- * 0 CTR-X1-OUT1 PPI-X-C0
- * 1 CTR-X2-OUT1 PPI-X-C3
- * 2 CTR-Y1-OUT1 PPI-Y-C0
- * 3 CTR-Y2-OUT1 PPI-Y-C3
- * 4 CTR-Z1-OUT1 PPI-Z-C0
- * 5 CTR-Z2-OUT1 PPI-Z-C3
- *
- * When an interrupt source is enabled in the interrupt source enable
- * register, a rising edge on the source signal latches the corresponding
- * bit to 1 in the interrupt status register.
- *
- * When the interrupt status register value as a whole (actually, just the
- * 6 least significant bits) goes from zero to non-zero, the board will
- * generate an interrupt. No further interrupts will occur until the
- * interrupt status register is cleared to zero. To clear a bit to zero in
- * the interrupt status register, the corresponding interrupt source must
- * be disabled in the interrupt source enable register (there is no
- * separate interrupt clear register).
- *
- * The PC214E does not have an interrupt source enable register or an
- * interrupt status register; its 'INTERRUPT' subdevice has a single
- * channel and its interrupt source is selected by the position of jumper
- * J5.
- *
- * COMMANDS
- *
- * The driver supports a read streaming acquisition command on the
- * 'INTERRUPT' subdevice. The channel list selects the interrupt sources
- * to be enabled. All channels will be sampled together (convert_src ==
- * TRIG_NOW). The scan begins a short time after the hardware interrupt
- * occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
- * scan_begin_arg == 0). The value read from the interrupt status register
- * is packed into a short value, one bit per requested channel, in the
- * order they appear in the channel list.
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include "amplc_dio200.h"
-
-/*
- * Board descriptions.
- */
-static const struct dio200_board dio200_isa_boards[] = {
- {
- .name = "pc212e",
- .n_subdevs = 6,
- .sdtype = {
- sd_8255, sd_8254, sd_8254, sd_8254, sd_8254, sd_intr
- },
- .sdinfo = { 0x00, 0x08, 0x0c, 0x10, 0x14, 0x3f },
- .has_int_sce = true,
- .has_clk_gat_sce = true,
- }, {
- .name = "pc214e",
- .n_subdevs = 4,
- .sdtype = {
- sd_8255, sd_8255, sd_8254, sd_intr
- },
- .sdinfo = { 0x00, 0x08, 0x10, 0x01 },
- }, {
- .name = "pc215e",
- .n_subdevs = 5,
- .sdtype = {
- sd_8255, sd_8255, sd_8254, sd_8254, sd_intr
- },
- .sdinfo = { 0x00, 0x08, 0x10, 0x14, 0x3f },
- .has_int_sce = true,
- .has_clk_gat_sce = true,
- }, {
- .name = "pc218e",
- .n_subdevs = 7,
- .sdtype = {
- sd_8254, sd_8254, sd_8255, sd_8254, sd_8254, sd_intr
- },
- .sdinfo = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x3f },
- .has_int_sce = true,
- .has_clk_gat_sce = true,
- }, {
- .name = "pc272e",
- .n_subdevs = 4,
- .sdtype = {
- sd_8255, sd_8255, sd_8255, sd_intr
- },
- .sdinfo = { 0x00, 0x08, 0x10, 0x3f },
- .has_int_sce = true,
- },
-};
-
-static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x20);
- if (ret)
- return ret;
-
- return amplc_dio200_common_attach(dev, it->options[1], 0);
-}
-
-static struct comedi_driver amplc_dio200_driver = {
- .driver_name = "amplc_dio200",
- .module = THIS_MODULE,
- .attach = dio200_attach,
- .detach = comedi_legacy_detach,
- .board_name = &dio200_isa_boards[0].name,
- .offset = sizeof(struct dio200_board),
- .num_names = ARRAY_SIZE(dio200_isa_boards),
-};
-module_comedi_driver(amplc_dio200_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon 200 Series ISA DIO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h
deleted file mode 100644
index 745baaf940ee..000000000000
--- a/drivers/staging/comedi/drivers/amplc_dio200.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedi/drivers/amplc_dio.h
- *
- * Header for amplc_dio200.c, amplc_dio200_common.c and
- * amplc_dio200_pci.c.
- *
- * Copyright (C) 2005-2013 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef AMPLC_DIO200_H_INCLUDED
-#define AMPLC_DIO200_H_INCLUDED
-
-#include <linux/types.h>
-
-struct comedi_device;
-
-/*
- * Subdevice types.
- */
-enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
-
-#define DIO200_MAX_SUBDEVS 8
-#define DIO200_MAX_ISNS 6
-
-struct dio200_board {
- const char *name;
- unsigned char mainbar;
- unsigned short n_subdevs; /* number of subdevices */
- unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
- unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
- unsigned int has_int_sce:1; /* has interrupt enable/status reg */
- unsigned int has_clk_gat_sce:1; /* has clock/gate selection registers */
- unsigned int is_pcie:1; /* has enhanced features */
-};
-
-int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq,
- unsigned long req_irq_flags);
-
-/* Used by initialization of PCIe boards. */
-void amplc_dio200_set_enhance(struct comedi_device *dev, unsigned char val);
-
-#endif
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c
deleted file mode 100644
index a3454130d5f8..000000000000
--- a/drivers/staging/comedi/drivers/amplc_dio200_common.c
+++ /dev/null
@@ -1,858 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/amplc_dio200_common.c
- *
- * Common support code for "amplc_dio200" and "amplc_dio200_pci".
- *
- * Copyright (C) 2005-2013 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "amplc_dio200.h"
-#include "comedi_8254.h"
-#include "8255.h" /* only for register defines */
-
-/* 200 series registers */
-#define DIO200_IO_SIZE 0x20
-#define DIO200_PCIE_IO_SIZE 0x4000
-#define DIO200_CLK_SCE(x) (0x18 + (x)) /* Group X/Y/Z clock sel reg */
-#define DIO200_GAT_SCE(x) (0x1b + (x)) /* Group X/Y/Z gate sel reg */
-#define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
-/* Extra registers for new PCIe boards */
-#define DIO200_ENHANCE 0x20 /* 1 to enable enhanced features */
-#define DIO200_VERSION 0x24 /* Hardware version register */
-#define DIO200_TS_CONFIG 0x600 /* Timestamp timer config register */
-#define DIO200_TS_COUNT 0x602 /* Timestamp timer count register */
-
-/*
- * Functions for constructing value for DIO_200_?CLK_SCE and
- * DIO_200_?GAT_SCE registers:
- *
- * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
- * 'chan' is the channel: 0, 1 or 2.
- * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards.
- */
-static unsigned char clk_gat_sce(unsigned int which, unsigned int chan,
- unsigned int source)
-{
- return (which << 5) | (chan << 3) |
- ((source & 030) << 3) | (source & 007);
-}
-
-/*
- * Periods of the internal clock sources in nanoseconds.
- */
-static const unsigned int clock_period[32] = {
- [1] = 100, /* 10 MHz */
- [2] = 1000, /* 1 MHz */
- [3] = 10000, /* 100 kHz */
- [4] = 100000, /* 10 kHz */
- [5] = 1000000, /* 1 kHz */
- [11] = 50, /* 20 MHz (enhanced boards) */
- /* clock sources 12 and later reserved for enhanced boards */
-};
-
-/*
- * Timestamp timer configuration register (for new PCIe boards).
- */
-#define TS_CONFIG_RESET 0x100 /* Reset counter to zero. */
-#define TS_CONFIG_CLK_SRC_MASK 0x0FF /* Clock source. */
-#define TS_CONFIG_MAX_CLK_SRC 2 /* Maximum clock source value. */
-
-/*
- * Periods of the timestamp timer clock sources in nanoseconds.
- */
-static const unsigned int ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = {
- 1, /* 1 nanosecond (but with 20 ns granularity). */
- 1000, /* 1 microsecond. */
- 1000000, /* 1 millisecond. */
-};
-
-struct dio200_subdev_8255 {
- unsigned int ofs; /* DIO base offset */
-};
-
-struct dio200_subdev_intr {
- spinlock_t spinlock; /* protects the 'active' flag */
- unsigned int ofs;
- unsigned int valid_isns;
- unsigned int enabled_isns;
- unsigned int active:1;
-};
-
-static unsigned char dio200_read8(struct comedi_device *dev,
- unsigned int offset)
-{
- const struct dio200_board *board = dev->board_ptr;
-
- if (board->is_pcie)
- offset <<= 3;
-
- if (dev->mmio)
- return readb(dev->mmio + offset);
- return inb(dev->iobase + offset);
-}
-
-static void dio200_write8(struct comedi_device *dev,
- unsigned int offset, unsigned char val)
-{
- const struct dio200_board *board = dev->board_ptr;
-
- if (board->is_pcie)
- offset <<= 3;
-
- if (dev->mmio)
- writeb(val, dev->mmio + offset);
- else
- outb(val, dev->iobase + offset);
-}
-
-static unsigned int dio200_read32(struct comedi_device *dev,
- unsigned int offset)
-{
- const struct dio200_board *board = dev->board_ptr;
-
- if (board->is_pcie)
- offset <<= 3;
-
- if (dev->mmio)
- return readl(dev->mmio + offset);
- return inl(dev->iobase + offset);
-}
-
-static void dio200_write32(struct comedi_device *dev,
- unsigned int offset, unsigned int val)
-{
- const struct dio200_board *board = dev->board_ptr;
-
- if (board->is_pcie)
- offset <<= 3;
-
- if (dev->mmio)
- writel(val, dev->mmio + offset);
- else
- outl(val, dev->iobase + offset);
-}
-
-static unsigned int dio200_subdev_8254_offset(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct comedi_8254 *i8254 = s->private;
- unsigned int offset;
-
- /* get the offset that was passed to comedi_8254_*_init() */
- if (dev->mmio)
- offset = i8254->mmio - dev->mmio;
- else
- offset = i8254->iobase - dev->iobase;
-
- /* remove the shift that was added for PCIe boards */
- if (board->is_pcie)
- offset >>= 3;
-
- /* this offset now works for the dio200_{read,write} helpers */
- return offset;
-}
-
-static int dio200_subdev_intr_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct dio200_subdev_intr *subpriv = s->private;
-
- if (board->has_int_sce) {
- /* Just read the interrupt status register. */
- data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
- } else {
- /* No interrupt status register. */
- data[0] = 0;
- }
-
- return insn->n;
-}
-
-static void dio200_stop_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct dio200_subdev_intr *subpriv = s->private;
-
- subpriv->active = false;
- subpriv->enabled_isns = 0;
- if (board->has_int_sce)
- dio200_write8(dev, subpriv->ofs, 0);
-}
-
-static void dio200_start_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct dio200_subdev_intr *subpriv = s->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int n;
- unsigned int isn_bits;
-
- /* Determine interrupt sources to enable. */
- isn_bits = 0;
- if (cmd->chanlist) {
- for (n = 0; n < cmd->chanlist_len; n++)
- isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
- }
- isn_bits &= subpriv->valid_isns;
- /* Enable interrupt sources. */
- subpriv->enabled_isns = isn_bits;
- if (board->has_int_sce)
- dio200_write8(dev, subpriv->ofs, isn_bits);
-}
-
-static int dio200_inttrig_start_intr(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct dio200_subdev_intr *subpriv = s->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned long flags;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- s->async->inttrig = NULL;
- if (subpriv->active)
- dio200_start_intr(dev, s);
-
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 1;
-}
-
-static void dio200_read_scan_intr(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int triggered)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned short val;
- unsigned int n, ch;
-
- val = 0;
- for (n = 0; n < cmd->chanlist_len; n++) {
- ch = CR_CHAN(cmd->chanlist[n]);
- if (triggered & (1U << ch))
- val |= (1U << n);
- }
-
- comedi_buf_write_samples(s, &val, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
-}
-
-static int dio200_handle_read_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct dio200_subdev_intr *subpriv = s->private;
- unsigned int triggered;
- unsigned int intstat;
- unsigned int cur_enabled;
- unsigned long flags;
-
- triggered = 0;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- if (board->has_int_sce) {
- /*
- * Collect interrupt sources that have triggered and disable
- * them temporarily. Loop around until no extra interrupt
- * sources have triggered, at which point, the valid part of
- * the interrupt status register will read zero, clearing the
- * cause of the interrupt.
- *
- * Mask off interrupt sources already seen to avoid infinite
- * loop in case of misconfiguration.
- */
- cur_enabled = subpriv->enabled_isns;
- while ((intstat = (dio200_read8(dev, subpriv->ofs) &
- subpriv->valid_isns & ~triggered)) != 0) {
- triggered |= intstat;
- cur_enabled &= ~triggered;
- dio200_write8(dev, subpriv->ofs, cur_enabled);
- }
- } else {
- /*
- * No interrupt status register. Assume the single interrupt
- * source has triggered.
- */
- triggered = subpriv->enabled_isns;
- }
-
- if (triggered) {
- /*
- * Some interrupt sources have triggered and have been
- * temporarily disabled to clear the cause of the interrupt.
- *
- * Reenable them NOW to minimize the time they are disabled.
- */
- cur_enabled = subpriv->enabled_isns;
- if (board->has_int_sce)
- dio200_write8(dev, subpriv->ofs, cur_enabled);
-
- if (subpriv->active) {
- /*
- * The command is still active.
- *
- * Ignore interrupt sources that the command isn't
- * interested in (just in case there's a race
- * condition).
- */
- if (triggered & subpriv->enabled_isns) {
- /* Collect scan data. */
- dio200_read_scan_intr(dev, s, triggered);
- }
- }
- }
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- comedi_handle_events(dev, s);
-
- return (triggered != 0);
-}
-
-static int dio200_subdev_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dio200_subdev_intr *subpriv = s->private;
- unsigned long flags;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- if (subpriv->active)
- dio200_stop_intr(dev, s);
-
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 0;
-}
-
-static int dio200_subdev_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- /* if (err) return 4; */
-
- return 0;
-}
-
-static int dio200_subdev_intr_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- struct dio200_subdev_intr *subpriv = s->private;
- unsigned long flags;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
-
- subpriv->active = true;
-
- if (cmd->start_src == TRIG_INT)
- s->async->inttrig = dio200_inttrig_start_intr;
- else /* TRIG_NOW */
- dio200_start_intr(dev, s);
-
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 0;
-}
-
-static int dio200_subdev_intr_init(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int offset,
- unsigned int valid_isns)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct dio200_subdev_intr *subpriv;
-
- subpriv = comedi_alloc_spriv(s, sizeof(*subpriv));
- if (!subpriv)
- return -ENOMEM;
-
- subpriv->ofs = offset;
- subpriv->valid_isns = valid_isns;
- spin_lock_init(&subpriv->spinlock);
-
- if (board->has_int_sce)
- /* Disable interrupt sources. */
- dio200_write8(dev, subpriv->ofs, 0);
-
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ | SDF_PACKED;
- if (board->has_int_sce) {
- s->n_chan = DIO200_MAX_ISNS;
- s->len_chanlist = DIO200_MAX_ISNS;
- } else {
- /* No interrupt source register. Support single channel. */
- s->n_chan = 1;
- s->len_chanlist = 1;
- }
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = dio200_subdev_intr_insn_bits;
- s->do_cmdtest = dio200_subdev_intr_cmdtest;
- s->do_cmd = dio200_subdev_intr_cmd;
- s->cancel = dio200_subdev_intr_cancel;
-
- return 0;
-}
-
-static irqreturn_t dio200_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- int handled;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- handled = dio200_handle_read_intr(dev, s);
-
- return IRQ_RETVAL(handled);
-}
-
-static void dio200_subdev_8254_set_gate_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chan,
- unsigned int src)
-{
- unsigned int offset = dio200_subdev_8254_offset(dev, s);
-
- dio200_write8(dev, DIO200_GAT_SCE(offset >> 3),
- clk_gat_sce((offset >> 2) & 1, chan, src));
-}
-
-static void dio200_subdev_8254_set_clock_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chan,
- unsigned int src)
-{
- unsigned int offset = dio200_subdev_8254_offset(dev, s);
-
- dio200_write8(dev, DIO200_CLK_SCE(offset >> 3),
- clk_gat_sce((offset >> 2) & 1, chan, src));
-}
-
-static int dio200_subdev_8254_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct comedi_8254 *i8254 = s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int max_src = board->is_pcie ? 31 : 7;
- unsigned int src;
-
- if (!board->has_clk_gat_sce)
- return -EINVAL;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_GATE_SRC:
- src = data[2];
- if (src > max_src)
- return -EINVAL;
-
- dio200_subdev_8254_set_gate_src(dev, s, chan, src);
- i8254->gate_src[chan] = src;
- break;
- case INSN_CONFIG_GET_GATE_SRC:
- data[2] = i8254->gate_src[chan];
- break;
- case INSN_CONFIG_SET_CLOCK_SRC:
- src = data[1];
- if (src > max_src)
- return -EINVAL;
-
- dio200_subdev_8254_set_clock_src(dev, s, chan, src);
- i8254->clock_src[chan] = src;
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- data[1] = i8254->clock_src[chan];
- data[2] = clock_period[i8254->clock_src[chan]];
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int dio200_subdev_8254_init(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int offset)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct comedi_8254 *i8254;
- unsigned int regshift;
- int chan;
-
- /*
- * PCIe boards need the offset shifted in order to get the
- * correct base address of the timer.
- */
- if (board->is_pcie) {
- offset <<= 3;
- regshift = 3;
- } else {
- regshift = 0;
- }
-
- if (dev->mmio) {
- i8254 = comedi_8254_mm_init(dev->mmio + offset,
- 0, I8254_IO8, regshift);
- } else {
- i8254 = comedi_8254_init(dev->iobase + offset,
- 0, I8254_IO8, regshift);
- }
- if (!i8254)
- return -ENOMEM;
-
- comedi_8254_subdevice_init(s, i8254);
-
- i8254->insn_config = dio200_subdev_8254_config;
-
- /*
- * There could be multiple timers so this driver does not
- * use dev->pacer to save the i8254 pointer. Instead,
- * comedi_8254_subdevice_init() saved the i8254 pointer in
- * s->private. Mark the subdevice as having private data
- * to be automatically freed when the device is detached.
- */
- comedi_set_spriv_auto_free(s);
-
- /* Initialize channels. */
- if (board->has_clk_gat_sce) {
- for (chan = 0; chan < 3; chan++) {
- /* Gate source 0 is VCC (logic 1). */
- dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
- /* Clock source 0 is the dedicated clock input. */
- dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
- }
- }
-
- return 0;
-}
-
-static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dio200_subdev_8255 *subpriv = s->private;
- int config;
-
- config = I8255_CTRL_CW;
- /* 1 in io_bits indicates output, 1 in config indicates input */
- if (!(s->io_bits & 0x0000ff))
- config |= I8255_CTRL_A_IO;
- if (!(s->io_bits & 0x00ff00))
- config |= I8255_CTRL_B_IO;
- if (!(s->io_bits & 0x0f0000))
- config |= I8255_CTRL_C_LO_IO;
- if (!(s->io_bits & 0xf00000))
- config |= I8255_CTRL_C_HI_IO;
- dio200_write8(dev, subpriv->ofs + I8255_CTRL_REG, config);
-}
-
-static int dio200_subdev_8255_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dio200_subdev_8255 *subpriv = s->private;
- unsigned int mask;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0xff) {
- dio200_write8(dev, subpriv->ofs + I8255_DATA_A_REG,
- s->state & 0xff);
- }
- if (mask & 0xff00) {
- dio200_write8(dev, subpriv->ofs + I8255_DATA_B_REG,
- (s->state >> 8) & 0xff);
- }
- if (mask & 0xff0000) {
- dio200_write8(dev, subpriv->ofs + I8255_DATA_C_REG,
- (s->state >> 16) & 0xff);
- }
- }
-
- val = dio200_read8(dev, subpriv->ofs + I8255_DATA_A_REG);
- val |= dio200_read8(dev, subpriv->ofs + I8255_DATA_B_REG) << 8;
- val |= dio200_read8(dev, subpriv->ofs + I8255_DATA_C_REG) << 16;
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int dio200_subdev_8255_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x0000ff;
- else if (chan < 16)
- mask = 0x00ff00;
- else if (chan < 20)
- mask = 0x0f0000;
- else
- mask = 0xf00000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- dio200_subdev_8255_set_dir(dev, s);
-
- return insn->n;
-}
-
-static int dio200_subdev_8255_init(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int offset)
-{
- struct dio200_subdev_8255 *subpriv;
-
- subpriv = comedi_alloc_spriv(s, sizeof(*subpriv));
- if (!subpriv)
- return -ENOMEM;
-
- subpriv->ofs = offset;
-
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = dio200_subdev_8255_bits;
- s->insn_config = dio200_subdev_8255_config;
- dio200_subdev_8255_set_dir(dev, s);
- return 0;
-}
-
-static int dio200_subdev_timer_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int n;
-
- for (n = 0; n < insn->n; n++)
- data[n] = dio200_read32(dev, DIO200_TS_COUNT);
- return n;
-}
-
-static void dio200_subdev_timer_reset(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int clock;
-
- clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
- dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET);
- dio200_write32(dev, DIO200_TS_CONFIG, clock);
-}
-
-static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *src,
- unsigned int *period)
-{
- unsigned int clk;
-
- clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
- *src = clk;
- *period = (clk < ARRAY_SIZE(ts_clock_period)) ?
- ts_clock_period[clk] : 0;
-}
-
-static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int src)
-{
- if (src > TS_CONFIG_MAX_CLK_SRC)
- return -EINVAL;
- dio200_write32(dev, DIO200_TS_CONFIG, src);
- return 0;
-}
-
-static int dio200_subdev_timer_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret = 0;
-
- switch (data[0]) {
- case INSN_CONFIG_RESET:
- dio200_subdev_timer_reset(dev, s);
- break;
- case INSN_CONFIG_SET_CLOCK_SRC:
- ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]);
- if (ret < 0)
- ret = -EINVAL;
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret < 0 ? ret : insn->n;
-}
-
-void amplc_dio200_set_enhance(struct comedi_device *dev, unsigned char val)
-{
- dio200_write8(dev, DIO200_ENHANCE, val);
-}
-EXPORT_SYMBOL_GPL(amplc_dio200_set_enhance);
-
-int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq,
- unsigned long req_irq_flags)
-{
- const struct dio200_board *board = dev->board_ptr;
- struct comedi_subdevice *s;
- unsigned int n;
- int ret;
-
- ret = comedi_alloc_subdevices(dev, board->n_subdevs);
- if (ret)
- return ret;
-
- for (n = 0; n < dev->n_subdevices; n++) {
- s = &dev->subdevices[n];
- switch (board->sdtype[n]) {
- case sd_8254:
- /* counter subdevice (8254) */
- ret = dio200_subdev_8254_init(dev, s,
- board->sdinfo[n]);
- if (ret < 0)
- return ret;
- break;
- case sd_8255:
- /* digital i/o subdevice (8255) */
- ret = dio200_subdev_8255_init(dev, s,
- board->sdinfo[n]);
- if (ret < 0)
- return ret;
- break;
- case sd_intr:
- /* 'INTERRUPT' subdevice */
- if (irq && !dev->read_subdev) {
- ret = dio200_subdev_intr_init(dev, s,
- DIO200_INT_SCE,
- board->sdinfo[n]);
- if (ret < 0)
- return ret;
- dev->read_subdev = s;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- break;
- case sd_timer:
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
- s->n_chan = 1;
- s->maxdata = 0xffffffff;
- s->insn_read = dio200_subdev_timer_read;
- s->insn_config = dio200_subdev_timer_config;
- break;
- default:
- s->type = COMEDI_SUBD_UNUSED;
- break;
- }
- }
-
- if (irq && dev->read_subdev) {
- if (request_irq(irq, dio200_interrupt, req_irq_flags,
- dev->board_name, dev) >= 0) {
- dev->irq = irq;
- } else {
- dev_warn(dev->class_dev,
- "warning! irq %u unavailable!\n", irq);
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(amplc_dio200_common_attach);
-
-static int __init amplc_dio200_common_init(void)
-{
- return 0;
-}
-module_init(amplc_dio200_common_init);
-
-static void __exit amplc_dio200_common_exit(void)
-{
-}
-module_exit(amplc_dio200_common_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi helper for amplc_dio200 and amplc_dio200_pci");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c
deleted file mode 100644
index 1bd7a42c8464..000000000000
--- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c
+++ /dev/null
@@ -1,415 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* comedi/drivers/amplc_dio200_pci.c
- *
- * Driver for Amplicon PCI215, PCI272, PCIe215, PCIe236, PCIe296.
- *
- * Copyright (C) 2005-2013 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: amplc_dio200_pci
- * Description: Amplicon 200 Series PCI Digital I/O
- * Author: Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Amplicon] PCI215 (amplc_dio200_pci), PCIe215, PCIe236,
- * PCI272, PCIe296
- * Updated: Mon, 18 Mar 2013 15:03:50 +0000
- * Status: works
- *
- * Configuration options:
- * none
- *
- * Manual configuration of PCI(e) cards is not supported; they are configured
- * automatically.
- *
- * SUBDEVICES
- *
- * PCI215 PCIe215 PCIe236
- * ------------- ------------- -------------
- * Subdevices 5 8 8
- * 0 PPI-X PPI-X PPI-X
- * 1 PPI-Y UNUSED UNUSED
- * 2 CTR-Z1 PPI-Y UNUSED
- * 3 CTR-Z2 UNUSED UNUSED
- * 4 INTERRUPT CTR-Z1 CTR-Z1
- * 5 CTR-Z2 CTR-Z2
- * 6 TIMER TIMER
- * 7 INTERRUPT INTERRUPT
- *
- *
- * PCI272 PCIe296
- * ------------- -------------
- * Subdevices 4 8
- * 0 PPI-X PPI-X1
- * 1 PPI-Y PPI-X2
- * 2 PPI-Z PPI-Y1
- * 3 INTERRUPT PPI-Y2
- * 4 CTR-Z1
- * 5 CTR-Z2
- * 6 TIMER
- * 7 INTERRUPT
- *
- * Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
- * are configurable as inputs or outputs in four groups:
- *
- * Port A - channels 0 to 7
- * Port B - channels 8 to 15
- * Port CL - channels 16 to 19
- * Port CH - channels 20 to 23
- *
- * Only mode 0 of the 8255 chips is supported.
- *
- * Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
- * channel is configured individually with INSN_CONFIG instructions. The
- * specific type of configuration instruction is specified in data[0].
- * Some configuration instructions expect an additional parameter in
- * data[1]; others return a value in data[1]. The following configuration
- * instructions are supported:
- *
- * INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
- * BCD/binary setting specified in data[1].
- *
- * INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
- * counter channel into data[1].
- *
- * INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
- * specified in data[1] (this is a hardware-specific value). Not
- * supported on PC214E. For the other boards, valid clock sources are
- * 0 to 7 as follows:
- *
- * 0. CLK n, the counter channel's dedicated CLK input from the SK1
- * connector. (N.B. for other values, the counter channel's CLKn
- * pin on the SK1 connector is an output!)
- * 1. Internal 10 MHz clock.
- * 2. Internal 1 MHz clock.
- * 3. Internal 100 kHz clock.
- * 4. Internal 10 kHz clock.
- * 5. Internal 1 kHz clock.
- * 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
- * 7. Ext Clock, the counter chip's dedicated Ext Clock input from
- * the SK1 connector. This pin is shared by all three counter
- * channels on the chip.
- *
- * For the PCIe boards, clock sources in the range 0 to 31 are allowed
- * and the following additional clock sources are defined:
- *
- * 8. HIGH logic level.
- * 9. LOW logic level.
- * 10. "Pattern present" signal.
- * 11. Internal 20 MHz clock.
- *
- * INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
- * clock source in data[1]. For internal clock sources, data[2] is set
- * to the period in ns.
- *
- * INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
- * specified in data[2] (this is a hardware-specific value). Not
- * supported on PC214E. For the other boards, valid gate sources are 0
- * to 7 as follows:
- *
- * 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
- * 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
- * 2. GAT n, the counter channel's dedicated GAT input from the SK1
- * connector. (N.B. for other values, the counter channel's GATn
- * pin on the SK1 connector is an output!)
- * 3. /OUT n-2, the inverted output of counter channel n-2 (see note
- * 2 below).
- * 4. Reserved.
- * 5. Reserved.
- * 6. Reserved.
- * 7. Reserved.
- *
- * For the PCIe boards, gate sources in the range 0 to 31 are allowed;
- * the following additional clock sources and clock sources 6 and 7 are
- * (re)defined:
- *
- * 6. /GAT n, negated version of the counter channel's dedicated
- * GAT input (negated version of gate source 2).
- * 7. OUT n-2, the non-inverted output of counter channel n-2
- * (negated version of gate source 3).
- * 8. "Pattern present" signal, HIGH while pattern present.
- * 9. "Pattern occurred" latched signal, latches HIGH when pattern
- * occurs.
- * 10. "Pattern gone away" latched signal, latches LOW when pattern
- * goes away after it occurred.
- * 11. Negated "pattern present" signal, LOW while pattern present
- * (negated version of gate source 8).
- * 12. Negated "pattern occurred" latched signal, latches LOW when
- * pattern occurs (negated version of gate source 9).
- * 13. Negated "pattern gone away" latched signal, latches LOW when
- * pattern goes away after it occurred (negated version of gate
- * source 10).
- *
- * INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
- * source in data[2].
- *
- * Clock and gate interconnection notes:
- *
- * 1. Clock source OUT n-1 is the output of the preceding channel on the
- * same counter subdevice if n > 0, or the output of channel 2 on the
- * preceding counter subdevice (see note 3) if n = 0.
- *
- * 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
- * same counter subdevice if n = 2, or the inverted output of channel n+1
- * on the preceding counter subdevice (see note 3) if n < 2.
- *
- * 3. The counter subdevices are connected in a ring, so the highest
- * counter subdevice precedes the lowest.
- *
- * The 'TIMER' subdevice is a free-running 32-bit timer subdevice.
- *
- * The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
- * digital inputs come from the interrupt status register. The number of
- * channels matches the number of interrupt sources. The PC214E does not
- * have an interrupt status register; see notes on 'INTERRUPT SOURCES'
- * below.
- *
- * INTERRUPT SOURCES
- *
- * PCI215 PCIe215 PCIe236
- * ------------- ------------- -------------
- * Sources 6 6 6
- * 0 PPI-X-C0 PPI-X-C0 PPI-X-C0
- * 1 PPI-X-C3 PPI-X-C3 PPI-X-C3
- * 2 PPI-Y-C0 PPI-Y-C0 unused
- * 3 PPI-Y-C3 PPI-Y-C3 unused
- * 4 CTR-Z1-OUT1 CTR-Z1-OUT1 CTR-Z1-OUT1
- * 5 CTR-Z2-OUT1 CTR-Z2-OUT1 CTR-Z2-OUT1
- *
- * PCI272 PCIe296
- * ------------- -------------
- * Sources 6 6
- * 0 PPI-X-C0 PPI-X1-C0
- * 1 PPI-X-C3 PPI-X1-C3
- * 2 PPI-Y-C0 PPI-Y1-C0
- * 3 PPI-Y-C3 PPI-Y1-C3
- * 4 PPI-Z-C0 CTR-Z1-OUT1
- * 5 PPI-Z-C3 CTR-Z2-OUT1
- *
- * When an interrupt source is enabled in the interrupt source enable
- * register, a rising edge on the source signal latches the corresponding
- * bit to 1 in the interrupt status register.
- *
- * When the interrupt status register value as a whole (actually, just the
- * 6 least significant bits) goes from zero to non-zero, the board will
- * generate an interrupt. The interrupt will remain asserted until the
- * interrupt status register is cleared to zero. To clear a bit to zero in
- * the interrupt status register, the corresponding interrupt source must
- * be disabled in the interrupt source enable register (there is no
- * separate interrupt clear register).
- *
- * COMMANDS
- *
- * The driver supports a read streaming acquisition command on the
- * 'INTERRUPT' subdevice. The channel list selects the interrupt sources
- * to be enabled. All channels will be sampled together (convert_src ==
- * TRIG_NOW). The scan begins a short time after the hardware interrupt
- * occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
- * scan_begin_arg == 0). The value read from the interrupt status register
- * is packed into a short value, one bit per requested channel, in the
- * order they appear in the channel list.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "amplc_dio200.h"
-
-/*
- * Board descriptions.
- */
-
-enum dio200_pci_model {
- pci215_model,
- pci272_model,
- pcie215_model,
- pcie236_model,
- pcie296_model
-};
-
-static const struct dio200_board dio200_pci_boards[] = {
- [pci215_model] = {
- .name = "pci215",
- .mainbar = 2,
- .n_subdevs = 5,
- .sdtype = {
- sd_8255, sd_8255, sd_8254, sd_8254, sd_intr
- },
- .sdinfo = { 0x00, 0x08, 0x10, 0x14, 0x3f },
- .has_int_sce = true,
- .has_clk_gat_sce = true,
- },
- [pci272_model] = {
- .name = "pci272",
- .mainbar = 2,
- .n_subdevs = 4,
- .sdtype = {
- sd_8255, sd_8255, sd_8255, sd_intr
- },
- .sdinfo = { 0x00, 0x08, 0x10, 0x3f },
- .has_int_sce = true,
- },
- [pcie215_model] = {
- .name = "pcie215",
- .mainbar = 1,
- .n_subdevs = 8,
- .sdtype = {
- sd_8255, sd_none, sd_8255, sd_none,
- sd_8254, sd_8254, sd_timer, sd_intr
- },
- .sdinfo = {
- 0x00, 0x00, 0x08, 0x00, 0x10, 0x14, 0x00, 0x3f
- },
- .has_int_sce = true,
- .has_clk_gat_sce = true,
- .is_pcie = true,
- },
- [pcie236_model] = {
- .name = "pcie236",
- .mainbar = 1,
- .n_subdevs = 8,
- .sdtype = {
- sd_8255, sd_none, sd_none, sd_none,
- sd_8254, sd_8254, sd_timer, sd_intr
- },
- .sdinfo = {
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x3f
- },
- .has_int_sce = true,
- .has_clk_gat_sce = true,
- .is_pcie = true,
- },
- [pcie296_model] = {
- .name = "pcie296",
- .mainbar = 1,
- .n_subdevs = 8,
- .sdtype = {
- sd_8255, sd_8255, sd_8255, sd_8255,
- sd_8254, sd_8254, sd_timer, sd_intr
- },
- .sdinfo = {
- 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x00, 0x3f
- },
- .has_int_sce = true,
- .has_clk_gat_sce = true,
- .is_pcie = true,
- },
-};
-
-/*
- * This function does some special set-up for the PCIe boards
- * PCIe215, PCIe236, PCIe296.
- */
-static int dio200_pcie_board_setup(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- void __iomem *brbase;
-
- /*
- * The board uses Altera Cyclone IV with PCI-Express hard IP.
- * The FPGA configuration has the PCI-Express Avalon-MM Bridge
- * Control registers in PCI BAR 0, offset 0, and the length of
- * these registers is 0x4000.
- *
- * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
- * Enable" register at offset 0x50 to allow generation of PCIe
- * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
- */
- if (pci_resource_len(pcidev, 0) < 0x4000) {
- dev_err(dev->class_dev, "error! bad PCI region!\n");
- return -EINVAL;
- }
- brbase = pci_ioremap_bar(pcidev, 0);
- if (!brbase) {
- dev_err(dev->class_dev, "error! failed to map registers!\n");
- return -ENOMEM;
- }
- writel(0x80, brbase + 0x50);
- iounmap(brbase);
- /* Enable "enhanced" features of board. */
- amplc_dio200_set_enhance(dev, 1);
- return 0;
-}
-
-static int dio200_pci_auto_attach(struct comedi_device *dev,
- unsigned long context_model)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- const struct dio200_board *board = NULL;
- unsigned int bar;
- int ret;
-
- if (context_model < ARRAY_SIZE(dio200_pci_boards))
- board = &dio200_pci_boards[context_model];
- if (!board)
- return -EINVAL;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- dev_info(dev->class_dev, "%s: attach pci %s (%s)\n",
- dev->driver->driver_name, pci_name(pci_dev), dev->board_name);
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- bar = board->mainbar;
- if (pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) {
- dev->mmio = pci_ioremap_bar(pci_dev, bar);
- if (!dev->mmio) {
- dev_err(dev->class_dev,
- "error! cannot remap registers\n");
- return -ENOMEM;
- }
- } else {
- dev->iobase = pci_resource_start(pci_dev, bar);
- }
-
- if (board->is_pcie) {
- ret = dio200_pcie_board_setup(dev);
- if (ret < 0)
- return ret;
- }
-
- return amplc_dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED);
-}
-
-static struct comedi_driver dio200_pci_comedi_driver = {
- .driver_name = "amplc_dio200_pci",
- .module = THIS_MODULE,
- .auto_attach = dio200_pci_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static const struct pci_device_id dio200_pci_table[] = {
- { PCI_VDEVICE(AMPLICON, 0x000b), pci215_model },
- { PCI_VDEVICE(AMPLICON, 0x000a), pci272_model },
- { PCI_VDEVICE(AMPLICON, 0x0011), pcie236_model },
- { PCI_VDEVICE(AMPLICON, 0x0012), pcie215_model },
- { PCI_VDEVICE(AMPLICON, 0x0014), pcie296_model },
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, dio200_pci_table);
-
-static int dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &dio200_pci_comedi_driver,
- id->driver_data);
-}
-
-static struct pci_driver dio200_pci_pci_driver = {
- .name = "amplc_dio200_pci",
- .id_table = dio200_pci_table,
- .probe = dio200_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(dio200_pci_comedi_driver, dio200_pci_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon 200 Series PCI(e) DIO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
deleted file mode 100644
index c377af1d5246..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/amplc_pc236.c
- * Driver for Amplicon PC36AT DIO boards.
- *
- * Copyright (C) 2002 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-/*
- * Driver: amplc_pc236
- * Description: Amplicon PC36AT
- * Author: Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Amplicon] PC36AT (pc36at)
- * Updated: Fri, 25 Jul 2014 15:32:40 +0000
- * Status: works
- *
- * Configuration options - PC36AT:
- * [0] - I/O port base address
- * [1] - IRQ (optional)
- *
- * The PC36AT board has a single 8255 appearing as subdevice 0.
- *
- * Subdevice 1 pretends to be a digital input device, but it always returns
- * 0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
- * a rising edge on port C bit 3 acts as an external trigger, which can be
- * used to wake up tasks. This is like the comedi_parport device, but the
- * only way to physically disable the interrupt on the PC36AT is to remove
- * the IRQ jumper. If no interrupt is connected, then subdevice 1 is
- * unused.
- */
-
-#include <linux/module.h>
-
-#include "../comedidev.h"
-
-#include "amplc_pc236.h"
-
-static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct pc236_private *devpriv;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x4);
- if (ret)
- return ret;
-
- return amplc_pc236_common_attach(dev, dev->iobase, it->options[1], 0);
-}
-
-static const struct pc236_board pc236_boards[] = {
- {
- .name = "pc36at",
- },
-};
-
-static struct comedi_driver amplc_pc236_driver = {
- .driver_name = "amplc_pc236",
- .module = THIS_MODULE,
- .attach = pc236_attach,
- .detach = comedi_legacy_detach,
- .board_name = &pc236_boards[0].name,
- .offset = sizeof(struct pc236_board),
- .num_names = ARRAY_SIZE(pc236_boards),
-};
-
-module_comedi_driver(amplc_pc236_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon PC36AT DIO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.h b/drivers/staging/comedi/drivers/amplc_pc236.h
deleted file mode 100644
index 7e72729f7492..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pc236.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedi/drivers/amplc_pc236.h
- * Header for "amplc_pc236", "amplc_pci236" and "amplc_pc236_common".
- *
- * Copyright (C) 2002-2014 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef AMPLC_PC236_H_INCLUDED
-#define AMPLC_PC236_H_INCLUDED
-
-#include <linux/types.h>
-
-struct comedi_device;
-
-struct pc236_board {
- const char *name;
- void (*intr_update_cb)(struct comedi_device *dev, bool enable);
- bool (*intr_chk_clr_cb)(struct comedi_device *dev);
-};
-
-struct pc236_private {
- unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
- bool enable_irq;
-};
-
-int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
- unsigned int irq, unsigned long req_irq_flags);
-
-#endif
diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c
deleted file mode 100644
index 981d281e87a1..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pc236_common.c
+++ /dev/null
@@ -1,193 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/amplc_pc236_common.c
- * Common support code for "amplc_pc236" and "amplc_pci236".
- *
- * Copyright (C) 2002-2014 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "amplc_pc236.h"
-#include "8255.h"
-
-static void pc236_intr_update(struct comedi_device *dev, bool enable)
-{
- const struct pc236_board *board = dev->board_ptr;
- struct pc236_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->enable_irq = enable;
- if (board->intr_update_cb)
- board->intr_update_cb(dev, enable);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-/*
- * This function is called when an interrupt occurs to check whether
- * the interrupt has been marked as enabled and was generated by the
- * board. If so, the function prepares the hardware for the next
- * interrupt.
- * Returns false if the interrupt should be ignored.
- */
-static bool pc236_intr_check(struct comedi_device *dev)
-{
- const struct pc236_board *board = dev->board_ptr;
- struct pc236_private *devpriv = dev->private;
- bool retval = false;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- if (devpriv->enable_irq) {
- if (board->intr_chk_clr_cb)
- retval = board->intr_chk_clr_cb(dev);
- else
- retval = true;
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return retval;
-}
-
-static int pc236_intr_insn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = 0;
- return insn->n;
-}
-
-static int pc236_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check it arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- pc236_intr_update(dev, true);
-
- return 0;
-}
-
-static int pc236_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- pc236_intr_update(dev, false);
-
- return 0;
-}
-
-static irqreturn_t pc236_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- bool handled;
-
- handled = pc236_intr_check(dev);
- if (dev->attached && handled) {
- unsigned short val = 0;
-
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
- }
- return IRQ_RETVAL(handled);
-}
-
-int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
- unsigned int irq, unsigned long req_irq_flags)
-{
- struct comedi_subdevice *s;
- int ret;
-
- dev->iobase = iobase;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* digital i/o subdevice (8255) */
- ret = subdev_8255_init(dev, s, NULL, 0x00);
- if (ret)
- return ret;
-
- s = &dev->subdevices[1];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_UNUSED;
- pc236_intr_update(dev, false);
- if (irq) {
- if (request_irq(irq, pc236_interrupt, req_irq_flags,
- dev->board_name, dev) >= 0) {
- dev->irq = irq;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pc236_intr_insn;
- s->len_chanlist = 1;
- s->do_cmdtest = pc236_intr_cmdtest;
- s->do_cmd = pc236_intr_cmd;
- s->cancel = pc236_intr_cancel;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(amplc_pc236_common_attach);
-
-static int __init amplc_pc236_common_init(void)
-{
- return 0;
-}
-module_init(amplc_pc236_common_init);
-
-static void __exit amplc_pc236_common_exit(void)
-{
-}
-module_exit(amplc_pc236_common_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi helper for amplc_pc236 and amplc_pci236");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
deleted file mode 100644
index 68da6098ee84..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Driver for Amplicon PC263 relay board.
- *
- * Copyright (C) 2002 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: amplc_pc263
- * Description: Amplicon PC263
- * Author: Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Amplicon] PC263 (pc263)
- * Updated: Fri, 12 Apr 2013 15:19:36 +0100
- * Status: works
- *
- * Configuration options:
- * [0] - I/O port base address
- *
- * The board appears as one subdevice, with 16 digital outputs, each
- * connected to a reed-relay. Relay contacts are closed when output is 1.
- * The state of the outputs can be read.
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-/* PC263 registers */
-#define PC263_DO_0_7_REG 0x00
-#define PC263_DO_8_15_REG 0x01
-
-struct pc263_board {
- const char *name;
-};
-
-static const struct pc263_board pc263_boards[] = {
- {
- .name = "pc263",
- },
-};
-
-static int pc263_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- outb(s->state & 0xff, dev->iobase + PC263_DO_0_7_REG);
- outb((s->state >> 8) & 0xff, dev->iobase + PC263_DO_8_15_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x2);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pc263_do_insn_bits;
-
- /* read initial relay state */
- s->state = inb(dev->iobase + PC263_DO_0_7_REG) |
- (inb(dev->iobase + PC263_DO_8_15_REG) << 8);
-
- return 0;
-}
-
-static struct comedi_driver amplc_pc263_driver = {
- .driver_name = "amplc_pc263",
- .module = THIS_MODULE,
- .attach = pc263_attach,
- .detach = comedi_legacy_detach,
- .board_name = &pc263_boards[0].name,
- .offset = sizeof(struct pc263_board),
- .num_names = ARRAY_SIZE(pc263_boards),
-};
-
-module_comedi_driver(amplc_pc263_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon PC263 relay board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
deleted file mode 100644
index bcf6d61af863..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/amplc_pci224.c
- * Driver for Amplicon PCI224 and PCI234 AO boards.
- *
- * Copyright (C) 2005 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: amplc_pci224
- * Description: Amplicon PCI224, PCI234
- * Author: Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Amplicon] PCI224 (amplc_pci224), PCI234
- * Updated: Thu, 31 Jul 2014 11:08:03 +0000
- * Status: works, but see caveats
- *
- * Supports:
- *
- * - ao_insn read/write
- * - ao_do_cmd mode with the following sources:
- *
- * - start_src TRIG_INT TRIG_EXT
- * - scan_begin_src TRIG_TIMER TRIG_EXT
- * - convert_src TRIG_NOW
- * - scan_end_src TRIG_COUNT
- * - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE
- *
- * The channel list must contain at least one channel with no repeated
- * channels. The scan end count must equal the number of channels in
- * the channel list.
- *
- * There is only one external trigger source so only one of start_src,
- * scan_begin_src or stop_src may use TRIG_EXT.
- *
- * Configuration options:
- * none
- *
- * Manual configuration of PCI cards is not supported; they are configured
- * automatically.
- *
- * Output range selection - PCI224:
- *
- * Output ranges on PCI224 are partly software-selectable and partly
- * hardware-selectable according to jumper LK1. All channels are set
- * to the same range:
- *
- * - LK1 position 1-2 (factory default) corresponds to the following
- * comedi ranges:
- *
- * 0: [-10V,+10V]; 1: [-5V,+5V]; 2: [-2.5V,+2.5V], 3: [-1.25V,+1.25V],
- * 4: [0,+10V], 5: [0,+5V], 6: [0,+2.5V], 7: [0,+1.25V]
- *
- * - LK1 position 2-3 corresponds to the following Comedi ranges, using
- * an external voltage reference:
- *
- * 0: [-Vext,+Vext],
- * 1: [0,+Vext]
- *
- * Output range selection - PCI234:
- *
- * Output ranges on PCI234 are hardware-selectable according to jumper
- * LK1 which affects all channels, and jumpers LK2, LK3, LK4 and LK5
- * which affect channels 0, 1, 2 and 3 individually. LK1 chooses between
- * an internal 5V reference and an external voltage reference (Vext).
- * LK2/3/4/5 choose (per channel) to double the reference or not according
- * to the following table:
- *
- * LK1 position LK2/3/4/5 pos Comedi range
- * ------------- ------------- --------------
- * 2-3 (factory) 1-2 (factory) 0: [-10V,+10V]
- * 2-3 (factory) 2-3 1: [-5V,+5V]
- * 1-2 1-2 (factory) 2: [-2*Vext,+2*Vext]
- * 1-2 2-3 3: [-Vext,+Vext]
- *
- * Caveats:
- *
- * 1) All channels on the PCI224 share the same range. Any change to the
- * range as a result of insn_write or a streaming command will affect
- * the output voltages of all channels, including those not specified
- * by the instruction or command.
- *
- * 2) For the analog output command, the first scan may be triggered
- * falsely at the start of acquisition. This occurs when the DAC scan
- * trigger source is switched from 'none' to 'timer' (scan_begin_src =
- * TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
- * of acquisition and the trigger source is at logic level 1 at the
- * time of the switch. This is very likely for TRIG_TIMER. For
- * TRIG_EXT, it depends on the state of the external line and whether
- * the CR_INVERT flag has been set. The remaining scans are triggered
- * correctly.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include "../comedi_pci.h"
-
-#include "comedi_8254.h"
-
-/*
- * PCI224/234 i/o space 1 (PCIBAR2) registers.
- */
-#define PCI224_Z2_BASE 0x14 /* 82C54 counter/timer */
-#define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
-#define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
-#define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
- /* /Interrupt status */
-
-/*
- * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
- */
-#define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
-#define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
-#define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
-#define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
-#define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
-
-/*
- * DACCON values.
- */
-/* (r/w) Scan trigger. */
-#define PCI224_DACCON_TRIG(x) (((x) & 0x7) << 0)
-#define PCI224_DACCON_TRIG_MASK PCI224_DACCON_TRIG(7)
-#define PCI224_DACCON_TRIG_NONE PCI224_DACCON_TRIG(0) /* none */
-#define PCI224_DACCON_TRIG_SW PCI224_DACCON_TRIG(1) /* soft trig */
-#define PCI224_DACCON_TRIG_EXTP PCI224_DACCON_TRIG(2) /* ext + edge */
-#define PCI224_DACCON_TRIG_EXTN PCI224_DACCON_TRIG(3) /* ext - edge */
-#define PCI224_DACCON_TRIG_Z2CT0 PCI224_DACCON_TRIG(4) /* Z2 CT0 out */
-#define PCI224_DACCON_TRIG_Z2CT1 PCI224_DACCON_TRIG(5) /* Z2 CT1 out */
-#define PCI224_DACCON_TRIG_Z2CT2 PCI224_DACCON_TRIG(6) /* Z2 CT2 out */
-/* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
-#define PCI224_DACCON_POLAR(x) (((x) & 0x1) << 3)
-#define PCI224_DACCON_POLAR_MASK PCI224_DACCON_POLAR(1)
-#define PCI224_DACCON_POLAR_UNI PCI224_DACCON_POLAR(0) /* [0,+V] */
-#define PCI224_DACCON_POLAR_BI PCI224_DACCON_POLAR(1) /* [-V,+V] */
-/* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
-#define PCI224_DACCON_VREF(x) (((x) & 0x3) << 4)
-#define PCI224_DACCON_VREF_MASK PCI224_DACCON_VREF(3)
-#define PCI224_DACCON_VREF_1_25 PCI224_DACCON_VREF(0) /* 1.25V */
-#define PCI224_DACCON_VREF_2_5 PCI224_DACCON_VREF(1) /* 2.5V */
-#define PCI224_DACCON_VREF_5 PCI224_DACCON_VREF(2) /* 5V */
-#define PCI224_DACCON_VREF_10 PCI224_DACCON_VREF(3) /* 10V */
-/* (r/w) Wraparound mode enable (to play back stored waveform). */
-#define PCI224_DACCON_FIFOWRAP BIT(7)
-/* (r/w) FIFO enable. It MUST be set! */
-#define PCI224_DACCON_FIFOENAB BIT(8)
-/* (r/w) FIFO interrupt trigger level (most values are not very useful). */
-#define PCI224_DACCON_FIFOINTR(x) (((x) & 0x7) << 9)
-#define PCI224_DACCON_FIFOINTR_MASK PCI224_DACCON_FIFOINTR(7)
-#define PCI224_DACCON_FIFOINTR_EMPTY PCI224_DACCON_FIFOINTR(0) /* empty */
-#define PCI224_DACCON_FIFOINTR_NEMPTY PCI224_DACCON_FIFOINTR(1) /* !empty */
-#define PCI224_DACCON_FIFOINTR_NHALF PCI224_DACCON_FIFOINTR(2) /* !half */
-#define PCI224_DACCON_FIFOINTR_HALF PCI224_DACCON_FIFOINTR(3) /* half */
-#define PCI224_DACCON_FIFOINTR_NFULL PCI224_DACCON_FIFOINTR(4) /* !full */
-#define PCI224_DACCON_FIFOINTR_FULL PCI224_DACCON_FIFOINTR(5) /* full */
-/* (r-o) FIFO fill level. */
-#define PCI224_DACCON_FIFOFL(x) (((x) & 0x7) << 12)
-#define PCI224_DACCON_FIFOFL_MASK PCI224_DACCON_FIFOFL(7)
-#define PCI224_DACCON_FIFOFL_EMPTY PCI224_DACCON_FIFOFL(1) /* 0 */
-#define PCI224_DACCON_FIFOFL_ONETOHALF PCI224_DACCON_FIFOFL(0) /* 1-2048 */
-#define PCI224_DACCON_FIFOFL_HALFTOFULL PCI224_DACCON_FIFOFL(4) /* 2049-4095 */
-#define PCI224_DACCON_FIFOFL_FULL PCI224_DACCON_FIFOFL(6) /* 4096 */
-/* (r-o) DAC busy flag. */
-#define PCI224_DACCON_BUSY BIT(15)
-/* (w-o) FIFO reset. */
-#define PCI224_DACCON_FIFORESET BIT(12)
-/* (w-o) Global reset (not sure what it does). */
-#define PCI224_DACCON_GLOBALRESET BIT(13)
-
-/*
- * DAC FIFO size.
- */
-#define PCI224_FIFO_SIZE 4096
-
-/*
- * DAC FIFO guaranteed minimum room available, depending on reported fill level.
- * The maximum room available depends on the reported fill level and how much
- * has been written!
- */
-#define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
-#define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
-#define PCI224_FIFO_ROOM_HALFTOFULL 1
-#define PCI224_FIFO_ROOM_FULL 0
-
-/*
- * Counter/timer clock input configuration sources.
- */
-#define CLK_CLK 0 /* reserved (channel-specific clock) */
-#define CLK_10MHZ 1 /* internal 10 MHz clock */
-#define CLK_1MHZ 2 /* internal 1 MHz clock */
-#define CLK_100KHZ 3 /* internal 100 kHz clock */
-#define CLK_10KHZ 4 /* internal 10 kHz clock */
-#define CLK_1KHZ 5 /* internal 1 kHz clock */
-#define CLK_OUTNM1 6 /* output of channel-1 modulo total */
-#define CLK_EXT 7 /* external clock */
-
-static unsigned int pci224_clk_config(unsigned int chan, unsigned int src)
-{
- return ((chan & 3) << 3) | (src & 7);
-}
-
-/*
- * Counter/timer gate input configuration sources.
- */
-#define GAT_VCC 0 /* VCC (i.e. enabled) */
-#define GAT_GND 1 /* GND (i.e. disabled) */
-#define GAT_EXT 2 /* reserved (external gate input) */
-#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
-
-static unsigned int pci224_gat_config(unsigned int chan, unsigned int src)
-{
- return ((chan & 3) << 3) | (src & 7);
-}
-
-/*
- * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
- *
- * Channel's Channel's
- * clock input gate input
- * Channel CLK_OUTNM1 GAT_NOUTNM2
- * ------- ---------- -----------
- * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
- * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
- * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
- */
-
-/*
- * Interrupt enable/status bits
- */
-#define PCI224_INTR_EXT 0x01 /* rising edge on external input */
-#define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
-#define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
-
-#define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
-#define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
-
-/*
- * Handy macros.
- */
-
-/* Combine old and new bits. */
-#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
-
-/* Current CPU. XXX should this be hard_smp_processor_id()? */
-#define THISCPU smp_processor_id()
-
-/* State bits for use with atomic bit operations. */
-#define AO_CMD_STARTED 0
-
-/*
- * Range tables.
- */
-
-/*
- * The ranges for PCI224.
- *
- * These are partly hardware-selectable by jumper LK1 and partly
- * software-selectable.
- *
- * All channels share the same hardware range.
- */
-static const struct comedi_lrange range_pci224 = {
- 10, {
- /* jumper LK1 in position 1-2 (factory default) */
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- /* jumper LK1 in position 2-3 */
- RANGE_ext(-1, 1), /* bipolar [-Vext,+Vext] */
- RANGE_ext(0, 1), /* unipolar [0,+Vext] */
- }
-};
-
-static const unsigned short hwrange_pci224[10] = {
- /* jumper LK1 in position 1-2 (factory default) */
- PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
- PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
- PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
- PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
- PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
- PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
- PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
- PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
- /* jumper LK1 in position 2-3 */
- PCI224_DACCON_POLAR_BI,
- PCI224_DACCON_POLAR_UNI,
-};
-
-/* Used to check all channels set to the same range on PCI224. */
-static const unsigned char range_check_pci224[10] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
-};
-
-/*
- * The ranges for PCI234.
- *
- * These are all hardware-selectable by jumper LK1 affecting all channels,
- * and jumpers LK2, LK3, LK4 and LK5 affecting channels 0, 1, 2 and 3
- * individually.
- */
-static const struct comedi_lrange range_pci234 = {
- 4, {
- /* LK1: 1-2 (fact def), LK2/3/4/5: 2-3 (fac def) */
- BIP_RANGE(10),
- /* LK1: 1-2 (fact def), LK2/3/4/5: 1-2 */
- BIP_RANGE(5),
- /* LK1: 2-3, LK2/3/4/5: 2-3 (fac def) */
- RANGE_ext(-2, 2), /* bipolar [-2*Vext,+2*Vext] */
- /* LK1: 2-3, LK2/3/4/5: 1-2 */
- RANGE_ext(-1, 1), /* bipolar [-Vext,+Vext] */
- }
-};
-
-/* N.B. PCI234 ignores the polarity bit, but software uses it. */
-static const unsigned short hwrange_pci234[4] = {
- PCI224_DACCON_POLAR_BI,
- PCI224_DACCON_POLAR_BI,
- PCI224_DACCON_POLAR_BI,
- PCI224_DACCON_POLAR_BI,
-};
-
-/* Used to check all channels use same LK1 setting on PCI234. */
-static const unsigned char range_check_pci234[4] = {
- 0, 0, 1, 1,
-};
-
-/*
- * Board descriptions.
- */
-
-enum pci224_model { pci224_model, pci234_model };
-
-struct pci224_board {
- const char *name;
- unsigned int ao_chans;
- unsigned int ao_bits;
- const struct comedi_lrange *ao_range;
- const unsigned short *ao_hwrange;
- const unsigned char *ao_range_check;
-};
-
-static const struct pci224_board pci224_boards[] = {
- [pci224_model] = {
- .name = "pci224",
- .ao_chans = 16,
- .ao_bits = 12,
- .ao_range = &range_pci224,
- .ao_hwrange = &hwrange_pci224[0],
- .ao_range_check = &range_check_pci224[0],
- },
- [pci234_model] = {
- .name = "pci234",
- .ao_chans = 4,
- .ao_bits = 16,
- .ao_range = &range_pci234,
- .ao_hwrange = &hwrange_pci234[0],
- .ao_range_check = &range_check_pci234[0],
- },
-};
-
-struct pci224_private {
- unsigned long iobase1;
- unsigned long state;
- spinlock_t ao_spinlock; /* spinlock for AO command handling */
- unsigned short *ao_scan_vals;
- unsigned char *ao_scan_order;
- int intr_cpuid;
- short intr_running;
- unsigned short daccon;
- unsigned short ao_enab; /* max 16 channels so 'short' will do */
- unsigned char intsce;
-};
-
-/*
- * Called from the 'insn_write' function to perform a single write.
- */
-static void
-pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
- unsigned int data)
-{
- const struct pci224_board *board = dev->board_ptr;
- struct pci224_private *devpriv = dev->private;
- unsigned short mangled;
-
- /* Enable the channel. */
- outw(1 << chan, dev->iobase + PCI224_DACCEN);
- /* Set range and reset FIFO. */
- devpriv->daccon = COMBINE(devpriv->daccon, board->ao_hwrange[range],
- PCI224_DACCON_POLAR_MASK |
- PCI224_DACCON_VREF_MASK);
- outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
- dev->iobase + PCI224_DACCON);
- /*
- * Mangle the data. The hardware expects:
- * - bipolar: 16-bit 2's complement
- * - unipolar: 16-bit unsigned
- */
- mangled = (unsigned short)data << (16 - board->ao_bits);
- if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
- PCI224_DACCON_POLAR_BI) {
- mangled ^= 0x8000;
- }
- /* Write mangled data to the FIFO. */
- outw(mangled, dev->iobase + PCI224_DACDATA);
- /* Trigger the conversion. */
- inw(dev->iobase + PCI224_SOFTTRIG);
-}
-
-static int pci224_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- pci224_ao_set_data(dev, chan, range, val);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-/*
- * Kills a command running on the AO subdevice.
- */
-static void pci224_ao_stop(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci224_private *devpriv = dev->private;
- unsigned long flags;
-
- if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
- return;
-
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
- /* Kill the interrupts. */
- devpriv->intsce = 0;
- outb(0, devpriv->iobase1 + PCI224_INT_SCE);
- /*
- * Interrupt routine may or may not be running. We may or may not
- * have been called from the interrupt routine (directly or
- * indirectly via a comedi_events() callback routine). It's highly
- * unlikely that we've been called from some other interrupt routine
- * but who knows what strange things coders get up to!
- *
- * If the interrupt routine is currently running, wait for it to
- * finish, unless we appear to have been called via the interrupt
- * routine.
- */
- while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
- }
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
- /* Reconfigure DAC for insn_write usage. */
- outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
- devpriv->daccon =
- COMBINE(devpriv->daccon,
- PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
- PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
- outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
- dev->iobase + PCI224_DACCON);
-}
-
-/*
- * Handles start of acquisition for the AO subdevice.
- */
-static void pci224_ao_start(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci224_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned long flags;
-
- set_bit(AO_CMD_STARTED, &devpriv->state);
-
- /* Enable interrupts. */
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
- if (cmd->stop_src == TRIG_EXT)
- devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
- else
- devpriv->intsce = PCI224_INTR_DAC;
-
- outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
-}
-
-/*
- * Handles interrupts from the DAC FIFO.
- */
-static void pci224_ao_handle_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci224_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int num_scans = comedi_nscans_left(s, 0);
- unsigned int room;
- unsigned short dacstat;
- unsigned int i, n;
-
- /* Determine how much room is in the FIFO (in samples). */
- dacstat = inw(dev->iobase + PCI224_DACCON);
- switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
- case PCI224_DACCON_FIFOFL_EMPTY:
- room = PCI224_FIFO_ROOM_EMPTY;
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg) {
- /* FIFO empty at end of counted acquisition. */
- s->async->events |= COMEDI_CB_EOA;
- comedi_handle_events(dev, s);
- return;
- }
- break;
- case PCI224_DACCON_FIFOFL_ONETOHALF:
- room = PCI224_FIFO_ROOM_ONETOHALF;
- break;
- case PCI224_DACCON_FIFOFL_HALFTOFULL:
- room = PCI224_FIFO_ROOM_HALFTOFULL;
- break;
- default:
- room = PCI224_FIFO_ROOM_FULL;
- break;
- }
- if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
- /* FIFO is less than half-full. */
- if (num_scans == 0) {
- /* Nothing left to put in the FIFO. */
- dev_err(dev->class_dev, "AO buffer underrun\n");
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
- }
- /* Determine how many new scans can be put in the FIFO. */
- room /= cmd->chanlist_len;
-
- /* Determine how many scans to process. */
- if (num_scans > room)
- num_scans = room;
-
- /* Process scans. */
- for (n = 0; n < num_scans; n++) {
- comedi_buf_read_samples(s, &devpriv->ao_scan_vals[0],
- cmd->chanlist_len);
- for (i = 0; i < cmd->chanlist_len; i++) {
- outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
- dev->iobase + PCI224_DACDATA);
- }
- }
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg) {
- /*
- * Change FIFO interrupt trigger level to wait
- * until FIFO is empty.
- */
- devpriv->daccon = COMBINE(devpriv->daccon,
- PCI224_DACCON_FIFOINTR_EMPTY,
- PCI224_DACCON_FIFOINTR_MASK);
- outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
- }
- if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
- PCI224_DACCON_TRIG_NONE) {
- unsigned short trig;
-
- /*
- * This is the initial DAC FIFO interrupt at the
- * start of the acquisition. The DAC's scan trigger
- * has been set to 'none' up until now.
- *
- * Now that data has been written to the FIFO, the
- * DAC's scan trigger source can be set to the
- * correct value.
- *
- * BUG: The first scan will be triggered immediately
- * if the scan trigger source is at logic level 1.
- */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- trig = PCI224_DACCON_TRIG_Z2CT0;
- } else {
- /* cmd->scan_begin_src == TRIG_EXT */
- if (cmd->scan_begin_arg & CR_INVERT)
- trig = PCI224_DACCON_TRIG_EXTN;
- else
- trig = PCI224_DACCON_TRIG_EXTP;
- }
- devpriv->daccon =
- COMBINE(devpriv->daccon, trig, PCI224_DACCON_TRIG_MASK);
- outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
- }
-
- comedi_handle_events(dev, s);
-}
-
-static int pci224_ao_inttrig_start(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- s->async->inttrig = NULL;
- pci224_ao_start(dev, s);
-
- return 1;
-}
-
-static int pci224_ao_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct pci224_board *board = dev->board_ptr;
- unsigned int range_check_0;
- unsigned int chan_mask = 0;
- int i;
-
- range_check_0 = board->ao_range_check[CR_RANGE(cmd->chanlist[0])];
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (chan_mask & (1 << chan)) {
- dev_dbg(dev->class_dev,
- "%s: entries in chanlist must contain no duplicate channels\n",
- __func__);
- return -EINVAL;
- }
- chan_mask |= 1 << chan;
-
- if (board->ao_range_check[CR_RANGE(cmd->chanlist[i])] !=
- range_check_0) {
- dev_dbg(dev->class_dev,
- "%s: entries in chanlist have incompatible ranges\n",
- __func__);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-#define MAX_SCAN_PERIOD 0xFFFFFFFFU
-#define MIN_SCAN_PERIOD 2500
-#define CONVERT_PERIOD 625
-
-/*
- * 'do_cmdtest' function for AO subdevice.
- */
-static int
-pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_EXT | TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src,
- TRIG_COUNT | TRIG_EXT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- /*
- * There's only one external trigger signal (which makes these
- * tests easier). Only one thing can use it.
- */
- arg = 0;
- if (cmd->start_src & TRIG_EXT)
- arg++;
- if (cmd->scan_begin_src & TRIG_EXT)
- arg++;
- if (cmd->stop_src & TRIG_EXT)
- arg++;
- if (arg > 1)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_INT:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- /* Force to external trigger 0. */
- if (cmd->start_arg & ~CR_FLAGS_MASK) {
- cmd->start_arg =
- COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK);
- err |= -EINVAL;
- }
- /* The only flag allowed is CR_EDGE, which is ignored. */
- if (cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) {
- cmd->start_arg = COMBINE(cmd->start_arg, 0,
- CR_FLAGS_MASK & ~CR_EDGE);
- err |= -EINVAL;
- }
- break;
- }
-
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- MAX_SCAN_PERIOD);
-
- arg = cmd->chanlist_len * CONVERT_PERIOD;
- if (arg < MIN_SCAN_PERIOD)
- arg = MIN_SCAN_PERIOD;
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
- break;
- case TRIG_EXT:
- /* Force to external trigger 0. */
- if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
- cmd->scan_begin_arg =
- COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK);
- err |= -EINVAL;
- }
- /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
- if (cmd->scan_begin_arg & CR_FLAGS_MASK &
- ~(CR_EDGE | CR_INVERT)) {
- cmd->scan_begin_arg =
- COMBINE(cmd->scan_begin_arg, 0,
- CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
- err |= -EINVAL;
- }
- break;
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- switch (cmd->stop_src) {
- case TRIG_COUNT:
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- break;
- case TRIG_EXT:
- /* Force to external trigger 0. */
- if (cmd->stop_arg & ~CR_FLAGS_MASK) {
- cmd->stop_arg =
- COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK);
- err |= -EINVAL;
- }
- /* The only flag allowed is CR_EDGE, which is ignored. */
- if (cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) {
- cmd->stop_arg =
- COMBINE(cmd->stop_arg, 0, CR_FLAGS_MASK & ~CR_EDGE);
- }
- break;
- case TRIG_NONE:
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
- break;
- }
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments. */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- /* Use two timers. */
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= pci224_ao_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static void pci224_ao_start_pacer(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci224_private *devpriv = dev->private;
-
- /*
- * The output of timer Z2-0 will be used as the scan trigger
- * source.
- */
- /* Make sure Z2-0 is gated on. */
- outb(pci224_gat_config(0, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
- /* Cascading with Z2-2. */
- /* Make sure Z2-2 is gated on. */
- outb(pci224_gat_config(2, GAT_VCC), devpriv->iobase1 + PCI224_ZGAT_SCE);
- /* Z2-2 needs 10 MHz clock. */
- outb(pci224_clk_config(2, CLK_10MHZ),
- devpriv->iobase1 + PCI224_ZCLK_SCE);
- /* Z2-0 is clocked from Z2-2's output. */
- outb(pci224_clk_config(0, CLK_OUTNM1),
- devpriv->iobase1 + PCI224_ZCLK_SCE);
-
- comedi_8254_pacer_enable(dev->pacer, 2, 0, false);
-}
-
-static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- const struct pci224_board *board = dev->board_ptr;
- struct pci224_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int range;
- unsigned int i, j;
- unsigned int ch;
- unsigned int rank;
- unsigned long flags;
-
- /* Cannot handle null/empty chanlist. */
- if (!cmd->chanlist || cmd->chanlist_len == 0)
- return -EINVAL;
-
- /* Determine which channels are enabled and their load order. */
- devpriv->ao_enab = 0;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- ch = CR_CHAN(cmd->chanlist[i]);
- devpriv->ao_enab |= 1U << ch;
- rank = 0;
- for (j = 0; j < cmd->chanlist_len; j++) {
- if (CR_CHAN(cmd->chanlist[j]) < ch)
- rank++;
- }
- devpriv->ao_scan_order[rank] = i;
- }
-
- /* Set enabled channels. */
- outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
-
- /* Determine range and polarity. All channels the same. */
- range = CR_RANGE(cmd->chanlist[0]);
-
- /*
- * Set DAC range and polarity.
- * Set DAC scan trigger source to 'none'.
- * Set DAC FIFO interrupt trigger level to 'not half full'.
- * Reset DAC FIFO.
- *
- * N.B. DAC FIFO interrupts are currently disabled.
- */
- devpriv->daccon =
- COMBINE(devpriv->daccon,
- board->ao_hwrange[range] | PCI224_DACCON_TRIG_NONE |
- PCI224_DACCON_FIFOINTR_NHALF,
- PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
- PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
- outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
- dev->iobase + PCI224_DACCON);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- comedi_8254_update_divisors(dev->pacer);
- pci224_ao_start_pacer(dev, s);
- }
-
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
- if (cmd->start_src == TRIG_INT) {
- s->async->inttrig = pci224_ao_inttrig_start;
- } else { /* TRIG_EXT */
- /* Enable external interrupt trigger to start acquisition. */
- devpriv->intsce |= PCI224_INTR_EXT;
- outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
- }
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
-
- return 0;
-}
-
-/*
- * 'cancel' function for AO subdevice.
- */
-static int pci224_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- pci224_ao_stop(dev, s);
- return 0;
-}
-
-/*
- * 'munge' data for AO command.
- */
-static void
-pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
- void *data, unsigned int num_bytes, unsigned int chan_index)
-{
- const struct pci224_board *board = dev->board_ptr;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned short *array = data;
- unsigned int length = num_bytes / sizeof(*array);
- unsigned int offset;
- unsigned int shift;
- unsigned int i;
-
- /* The hardware expects 16-bit numbers. */
- shift = 16 - board->ao_bits;
- /* Channels will be all bipolar or all unipolar. */
- if ((board->ao_hwrange[CR_RANGE(cmd->chanlist[0])] &
- PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
- /* Unipolar */
- offset = 0;
- } else {
- /* Bipolar */
- offset = 32768;
- }
- /* Munge the data. */
- for (i = 0; i < length; i++)
- array[i] = (array[i] << shift) - offset;
-}
-
-/*
- * Interrupt handler.
- */
-static irqreturn_t pci224_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct pci224_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- struct comedi_cmd *cmd;
- unsigned char intstat, valid_intstat;
- unsigned char curenab;
- int retval = 0;
- unsigned long flags;
-
- intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
- if (intstat) {
- retval = 1;
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
- valid_intstat = devpriv->intsce & intstat;
- /* Temporarily disable interrupt sources. */
- curenab = devpriv->intsce & ~intstat;
- outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
- devpriv->intr_running = 1;
- devpriv->intr_cpuid = THISCPU;
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
- if (valid_intstat) {
- cmd = &s->async->cmd;
- if (valid_intstat & PCI224_INTR_EXT) {
- devpriv->intsce &= ~PCI224_INTR_EXT;
- if (cmd->start_src == TRIG_EXT)
- pci224_ao_start(dev, s);
- else if (cmd->stop_src == TRIG_EXT)
- pci224_ao_stop(dev, s);
- }
- if (valid_intstat & PCI224_INTR_DAC)
- pci224_ao_handle_fifo(dev, s);
- }
- /* Reenable interrupt sources. */
- spin_lock_irqsave(&devpriv->ao_spinlock, flags);
- if (curenab != devpriv->intsce) {
- outb(devpriv->intsce,
- devpriv->iobase1 + PCI224_INT_SCE);
- }
- devpriv->intr_running = 0;
- spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
- }
- return IRQ_RETVAL(retval);
-}
-
-static int
-pci224_auto_attach(struct comedi_device *dev, unsigned long context_model)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- const struct pci224_board *board = NULL;
- struct pci224_private *devpriv;
- struct comedi_subdevice *s;
- unsigned int irq;
- int ret;
-
- if (context_model < ARRAY_SIZE(pci224_boards))
- board = &pci224_boards[context_model];
- if (!board || !board->name) {
- dev_err(dev->class_dev,
- "amplc_pci224: BUG! cannot determine board type!\n");
- return -EINVAL;
- }
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- dev_info(dev->class_dev, "amplc_pci224: attach pci %s - %s\n",
- pci_name(pci_dev), dev->board_name);
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- spin_lock_init(&devpriv->ao_spinlock);
-
- devpriv->iobase1 = pci_resource_start(pci_dev, 2);
- dev->iobase = pci_resource_start(pci_dev, 3);
- irq = pci_dev->irq;
-
- /* Allocate buffer to hold values for AO channel scan. */
- devpriv->ao_scan_vals = kmalloc_array(board->ao_chans,
- sizeof(devpriv->ao_scan_vals[0]),
- GFP_KERNEL);
- if (!devpriv->ao_scan_vals)
- return -ENOMEM;
-
- /* Allocate buffer to hold AO channel scan order. */
- devpriv->ao_scan_order =
- kmalloc_array(board->ao_chans,
- sizeof(devpriv->ao_scan_order[0]),
- GFP_KERNEL);
- if (!devpriv->ao_scan_order)
- return -ENOMEM;
-
- /* Disable interrupt sources. */
- devpriv->intsce = 0;
- outb(0, devpriv->iobase1 + PCI224_INT_SCE);
-
- /* Initialize the DAC hardware. */
- outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
- outw(0, dev->iobase + PCI224_DACCEN);
- outw(0, dev->iobase + PCI224_FIFOSIZ);
- devpriv->daccon = PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
- PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY;
- outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
- dev->iobase + PCI224_DACCON);
-
- dev->pacer = comedi_8254_init(devpriv->iobase1 + PCI224_Z2_BASE,
- I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* Analog output subdevice. */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
- s->n_chan = board->ao_chans;
- s->maxdata = (1 << board->ao_bits) - 1;
- s->range_table = board->ao_range;
- s->insn_write = pci224_ao_insn_write;
- s->len_chanlist = s->n_chan;
- dev->write_subdev = s;
- s->do_cmd = pci224_ao_cmd;
- s->do_cmdtest = pci224_ao_cmdtest;
- s->cancel = pci224_ao_cancel;
- s->munge = pci224_ao_munge;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- if (irq) {
- ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "error! unable to allocate irq %u\n", irq);
- return ret;
- }
- dev->irq = irq;
- }
-
- return 0;
-}
-
-static void pci224_detach(struct comedi_device *dev)
-{
- struct pci224_private *devpriv = dev->private;
-
- comedi_pci_detach(dev);
- if (devpriv) {
- kfree(devpriv->ao_scan_vals);
- kfree(devpriv->ao_scan_order);
- }
-}
-
-static struct comedi_driver amplc_pci224_driver = {
- .driver_name = "amplc_pci224",
- .module = THIS_MODULE,
- .detach = pci224_detach,
- .auto_attach = pci224_auto_attach,
- .board_name = &pci224_boards[0].name,
- .offset = sizeof(struct pci224_board),
- .num_names = ARRAY_SIZE(pci224_boards),
-};
-
-static int amplc_pci224_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &amplc_pci224_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id amplc_pci224_pci_table[] = {
- { PCI_VDEVICE(AMPLICON, 0x0007), pci224_model },
- { PCI_VDEVICE(AMPLICON, 0x0008), pci234_model },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table);
-
-static struct pci_driver amplc_pci224_pci_driver = {
- .name = "amplc_pci224",
- .id_table = amplc_pci224_pci_table,
- .probe = amplc_pci224_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon PCI224 and PCI234 AO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
deleted file mode 100644
index 8911dc2bd2c6..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ /dev/null
@@ -1,2575 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/amplc_pci230.c
- * Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
- *
- * Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: amplc_pci230
- * Description: Amplicon PCI230, PCI260 Multifunction I/O boards
- * Author: Allan Willcox <allanwillcox@ozemail.com.au>,
- * Steve D Sharples <steve.sharples@nottingham.ac.uk>,
- * Ian Abbott <abbotti@mev.co.uk>
- * Updated: Mon, 01 Sep 2014 10:09:16 +0000
- * Devices: [Amplicon] PCI230 (amplc_pci230), PCI230+, PCI260, PCI260+
- * Status: works
- *
- * Configuration options:
- * none
- *
- * Manual configuration of PCI cards is not supported; they are configured
- * automatically.
- *
- * The PCI230+ and PCI260+ have the same PCI device IDs as the PCI230 and
- * PCI260, but can be distinguished by the size of the PCI regions. A
- * card will be configured as a "+" model if detected as such.
- *
- * Subdevices:
- *
- * PCI230(+) PCI260(+)
- * --------- ---------
- * Subdevices 3 1
- * 0 AI AI
- * 1 AO
- * 2 DIO
- *
- * AI Subdevice:
- *
- * The AI subdevice has 16 single-ended channels or 8 differential
- * channels.
- *
- * The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
- * PCI260+ cards have 16-bit resolution.
- *
- * For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
- * inputs 14 and 15 for channel 7). If the card is physically a PCI230
- * or PCI260 then it actually uses a "pseudo-differential" mode where the
- * inputs are sampled a few microseconds apart. The PCI230+ and PCI260+
- * use true differential sampling. Another difference is that if the
- * card is physically a PCI230 or PCI260, the inverting input is 2N,
- * whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a
- * PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
- * PCI260+) and differential mode is used, the differential inputs need
- * to be physically swapped on the connector.
- *
- * The following input ranges are supported:
- *
- * 0 => [-10, +10] V
- * 1 => [-5, +5] V
- * 2 => [-2.5, +2.5] V
- * 3 => [-1.25, +1.25] V
- * 4 => [0, 10] V
- * 5 => [0, 5] V
- * 6 => [0, 2.5] V
- *
- * AI Commands:
- *
- * +=========+==============+===========+============+==========+
- * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
- * +=========+==============+===========+============+==========+
- * |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
- * |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT|
- * | | |TRIG_INT | | |
- * | |--------------|-----------| | |
- * | | TRIG_TIMER(1)|TRIG_TIMER | | |
- * | | TRIG_EXT(2) | | | |
- * | | TRIG_INT | | | |
- * +---------+--------------+-----------+------------+----------+
- *
- * Note 1: If AI command and AO command are used simultaneously, only
- * one may have scan_begin_src == TRIG_TIMER.
- *
- * Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
- * DIO channel 16 (pin 49) which will need to be configured as
- * a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input
- * (pin 17) is used instead. For PCI230, scan_begin_src ==
- * TRIG_EXT is not supported. The trigger is a rising edge
- * on the input.
- *
- * Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
- * (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The
- * convert_arg value is interpreted as follows:
- *
- * convert_arg == (CR_EDGE | 0) => rising edge
- * convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
- * convert_arg == 0 => falling edge (backwards compatibility)
- * convert_arg == 1 => rising edge (backwards compatibility)
- *
- * All entries in the channel list must use the same analogue reference.
- * If the analogue reference is not AREF_DIFF (not differential) each
- * pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
- * input range. The input ranges used in the sequence must be all
- * bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel
- * sequence must consist of 1 or more identical subsequences. Within the
- * subsequence, channels must be in ascending order with no repeated
- * channels. For example, the following sequences are valid: 0 1 2 3
- * (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
- * subsequence), 1 1 1 1 (repeated valid subsequence). The following
- * sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
- * (incompletely repeated subsequence). Some versions of the PCI230+ and
- * PCI260+ have a bug that requires a subsequence longer than one entry
- * long to include channel 0.
- *
- * AO Subdevice:
- *
- * The AO subdevice has 2 channels with 12-bit resolution.
- * The following output ranges are supported:
- * 0 => [0, 10] V
- * 1 => [-10, +10] V
- *
- * AO Commands:
- *
- * +=========+==============+===========+============+==========+
- * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
- * +=========+==============+===========+============+==========+
- * |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE |
- * | | TRIG_EXT(2) | | |TRIG_COUNT|
- * | | TRIG_INT | | | |
- * +---------+--------------+-----------+------------+----------+
- *
- * Note 1: If AI command and AO command are used simultaneously, only
- * one may have scan_begin_src == TRIG_TIMER.
- *
- * Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
- * configured as a PCI230+ and is only supported on later
- * versions of the card. As a card configured as a PCI230+ is
- * not guaranteed to support external triggering, please consider
- * this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK
- * input (PCI230+ pin 25). Triggering will be on the rising edge
- * unless the CR_INVERT flag is set in scan_begin_arg.
- *
- * The channels in the channel sequence must be in ascending order with
- * no repeats. All entries in the channel sequence must use the same
- * output range.
- *
- * DIO Subdevice:
- *
- * The DIO subdevice is a 8255 chip providing 24 DIO channels. The DIO
- * channels are configurable as inputs or outputs in four groups:
- *
- * Port A - channels 0 to 7
- * Port B - channels 8 to 15
- * Port CL - channels 16 to 19
- * Port CH - channels 20 to 23
- *
- * Only mode 0 of the 8255 chip is supported.
- *
- * Bit 0 of port C (DIO channel 16) is also used as an external scan
- * trigger input for AI commands on PCI230 and PCI230+, so would need to
- * be configured as an input to use it for that purpose.
- */
-
-/*
- * Extra triggered scan functionality, interrupt bug-fix added by Steve
- * Sharples. Support for PCI230+/260+, more triggered scan functionality,
- * and workarounds for (or detection of) various hardware problems added
- * by Ian Abbott.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "comedi_8254.h"
-#include "8255.h"
-
-/*
- * PCI230 PCI configuration register information
- */
-#define PCI_DEVICE_ID_PCI230 0x0000
-#define PCI_DEVICE_ID_PCI260 0x0006
-
-/*
- * PCI230 i/o space 1 registers.
- */
-#define PCI230_PPI_X_BASE 0x00 /* User PPI (82C55) base */
-#define PCI230_PPI_X_A 0x00 /* User PPI (82C55) port A */
-#define PCI230_PPI_X_B 0x01 /* User PPI (82C55) port B */
-#define PCI230_PPI_X_C 0x02 /* User PPI (82C55) port C */
-#define PCI230_PPI_X_CMD 0x03 /* User PPI (82C55) control word */
-#define PCI230_Z2_CT_BASE 0x14 /* 82C54 counter/timer base */
-#define PCI230_ZCLK_SCE 0x1A /* Group Z Clock Configuration */
-#define PCI230_ZGAT_SCE 0x1D /* Group Z Gate Configuration */
-#define PCI230_INT_SCE 0x1E /* Interrupt source mask (w) */
-#define PCI230_INT_STAT 0x1E /* Interrupt status (r) */
-
-/*
- * PCI230 i/o space 2 registers.
- */
-#define PCI230_DACCON 0x00 /* DAC control */
-#define PCI230_DACOUT1 0x02 /* DAC channel 0 (w) */
-#define PCI230_DACOUT2 0x04 /* DAC channel 1 (w) (not FIFO mode) */
-#define PCI230_ADCDATA 0x08 /* ADC data (r) */
-#define PCI230_ADCSWTRIG 0x08 /* ADC software trigger (w) */
-#define PCI230_ADCCON 0x0A /* ADC control */
-#define PCI230_ADCEN 0x0C /* ADC channel enable bits */
-#define PCI230_ADCG 0x0E /* ADC gain control bits */
-/* PCI230+ i/o space 2 additional registers. */
-#define PCI230P_ADCTRIG 0x10 /* ADC start acquisition trigger */
-#define PCI230P_ADCTH 0x12 /* ADC analog trigger threshold */
-#define PCI230P_ADCFFTH 0x14 /* ADC FIFO interrupt threshold */
-#define PCI230P_ADCFFLEV 0x16 /* ADC FIFO level (r) */
-#define PCI230P_ADCPTSC 0x18 /* ADC pre-trigger sample count (r) */
-#define PCI230P_ADCHYST 0x1A /* ADC analog trigger hysteresys */
-#define PCI230P_EXTFUNC 0x1C /* Extended functions */
-#define PCI230P_HWVER 0x1E /* Hardware version (r) */
-/* PCI230+ hardware version 2 onwards. */
-#define PCI230P2_DACDATA 0x02 /* DAC data (FIFO mode) (w) */
-#define PCI230P2_DACSWTRIG 0x02 /* DAC soft trigger (FIFO mode) (r) */
-#define PCI230P2_DACEN 0x06 /* DAC channel enable (FIFO mode) */
-
-/*
- * DACCON read-write values.
- */
-#define PCI230_DAC_OR(x) (((x) & 0x1) << 0)
-#define PCI230_DAC_OR_UNI PCI230_DAC_OR(0) /* Output unipolar */
-#define PCI230_DAC_OR_BIP PCI230_DAC_OR(1) /* Output bipolar */
-#define PCI230_DAC_OR_MASK PCI230_DAC_OR(1)
-/*
- * The following applies only if DAC FIFO support is enabled in the EXTFUNC
- * register (and only for PCI230+ hardware version 2 onwards).
- */
-#define PCI230P2_DAC_FIFO_EN BIT(8) /* FIFO enable */
-/*
- * The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards).
- */
-#define PCI230P2_DAC_TRIG(x) (((x) & 0x7) << 2)
-#define PCI230P2_DAC_TRIG_NONE PCI230P2_DAC_TRIG(0) /* none */
-#define PCI230P2_DAC_TRIG_SW PCI230P2_DAC_TRIG(1) /* soft trig */
-#define PCI230P2_DAC_TRIG_EXTP PCI230P2_DAC_TRIG(2) /* ext + edge */
-#define PCI230P2_DAC_TRIG_EXTN PCI230P2_DAC_TRIG(3) /* ext - edge */
-#define PCI230P2_DAC_TRIG_Z2CT0 PCI230P2_DAC_TRIG(4) /* Z2 CT0 out */
-#define PCI230P2_DAC_TRIG_Z2CT1 PCI230P2_DAC_TRIG(5) /* Z2 CT1 out */
-#define PCI230P2_DAC_TRIG_Z2CT2 PCI230P2_DAC_TRIG(6) /* Z2 CT2 out */
-#define PCI230P2_DAC_TRIG_MASK PCI230P2_DAC_TRIG(7)
-#define PCI230P2_DAC_FIFO_WRAP BIT(7) /* FIFO wraparound mode */
-#define PCI230P2_DAC_INT_FIFO(x) (((x) & 7) << 9)
-#define PCI230P2_DAC_INT_FIFO_EMPTY PCI230P2_DAC_INT_FIFO(0) /* empty */
-#define PCI230P2_DAC_INT_FIFO_NEMPTY PCI230P2_DAC_INT_FIFO(1) /* !empty */
-#define PCI230P2_DAC_INT_FIFO_NHALF PCI230P2_DAC_INT_FIFO(2) /* !half */
-#define PCI230P2_DAC_INT_FIFO_HALF PCI230P2_DAC_INT_FIFO(3) /* half */
-#define PCI230P2_DAC_INT_FIFO_NFULL PCI230P2_DAC_INT_FIFO(4) /* !full */
-#define PCI230P2_DAC_INT_FIFO_FULL PCI230P2_DAC_INT_FIFO(5) /* full */
-#define PCI230P2_DAC_INT_FIFO_MASK PCI230P2_DAC_INT_FIFO(7)
-
-/*
- * DACCON read-only values.
- */
-#define PCI230_DAC_BUSY BIT(1) /* DAC busy. */
-/*
- * The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards).
- */
-#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED BIT(5) /* Underrun error */
-#define PCI230P2_DAC_FIFO_EMPTY BIT(13) /* FIFO empty */
-#define PCI230P2_DAC_FIFO_FULL BIT(14) /* FIFO full */
-#define PCI230P2_DAC_FIFO_HALF BIT(15) /* FIFO half full */
-
-/*
- * DACCON write-only, transient values.
- */
-/*
- * The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards).
- */
-#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR BIT(5) /* Clear underrun */
-#define PCI230P2_DAC_FIFO_RESET BIT(12) /* FIFO reset */
-
-/*
- * PCI230+ hardware version 2 DAC FIFO levels.
- */
-#define PCI230P2_DAC_FIFOLEVEL_HALF 512
-#define PCI230P2_DAC_FIFOLEVEL_FULL 1024
-/* Free space in DAC FIFO. */
-#define PCI230P2_DAC_FIFOROOM_EMPTY PCI230P2_DAC_FIFOLEVEL_FULL
-#define PCI230P2_DAC_FIFOROOM_ONETOHALF \
- (PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF)
-#define PCI230P2_DAC_FIFOROOM_HALFTOFULL 1
-#define PCI230P2_DAC_FIFOROOM_FULL 0
-
-/*
- * ADCCON read/write values.
- */
-#define PCI230_ADC_TRIG(x) (((x) & 0x7) << 0)
-#define PCI230_ADC_TRIG_NONE PCI230_ADC_TRIG(0) /* none */
-#define PCI230_ADC_TRIG_SW PCI230_ADC_TRIG(1) /* soft trig */
-#define PCI230_ADC_TRIG_EXTP PCI230_ADC_TRIG(2) /* ext + edge */
-#define PCI230_ADC_TRIG_EXTN PCI230_ADC_TRIG(3) /* ext - edge */
-#define PCI230_ADC_TRIG_Z2CT0 PCI230_ADC_TRIG(4) /* Z2 CT0 out*/
-#define PCI230_ADC_TRIG_Z2CT1 PCI230_ADC_TRIG(5) /* Z2 CT1 out */
-#define PCI230_ADC_TRIG_Z2CT2 PCI230_ADC_TRIG(6) /* Z2 CT2 out */
-#define PCI230_ADC_TRIG_MASK PCI230_ADC_TRIG(7)
-#define PCI230_ADC_IR(x) (((x) & 0x1) << 3)
-#define PCI230_ADC_IR_UNI PCI230_ADC_IR(0) /* Input unipolar */
-#define PCI230_ADC_IR_BIP PCI230_ADC_IR(1) /* Input bipolar */
-#define PCI230_ADC_IR_MASK PCI230_ADC_IR(1)
-#define PCI230_ADC_IM(x) (((x) & 0x1) << 4)
-#define PCI230_ADC_IM_SE PCI230_ADC_IM(0) /* single ended */
-#define PCI230_ADC_IM_DIF PCI230_ADC_IM(1) /* differential */
-#define PCI230_ADC_IM_MASK PCI230_ADC_IM(1)
-#define PCI230_ADC_FIFO_EN BIT(8) /* FIFO enable */
-#define PCI230_ADC_INT_FIFO(x) (((x) & 0x7) << 9)
-#define PCI230_ADC_INT_FIFO_EMPTY PCI230_ADC_INT_FIFO(0) /* empty */
-#define PCI230_ADC_INT_FIFO_NEMPTY PCI230_ADC_INT_FIFO(1) /* !empty */
-#define PCI230_ADC_INT_FIFO_NHALF PCI230_ADC_INT_FIFO(2) /* !half */
-#define PCI230_ADC_INT_FIFO_HALF PCI230_ADC_INT_FIFO(3) /* half */
-#define PCI230_ADC_INT_FIFO_NFULL PCI230_ADC_INT_FIFO(4) /* !full */
-#define PCI230_ADC_INT_FIFO_FULL PCI230_ADC_INT_FIFO(5) /* full */
-#define PCI230P_ADC_INT_FIFO_THRESH PCI230_ADC_INT_FIFO(7) /* threshold */
-#define PCI230_ADC_INT_FIFO_MASK PCI230_ADC_INT_FIFO(7)
-
-/*
- * ADCCON write-only, transient values.
- */
-#define PCI230_ADC_FIFO_RESET BIT(12) /* FIFO reset */
-#define PCI230_ADC_GLOB_RESET BIT(13) /* Global reset */
-
-/*
- * ADCCON read-only values.
- */
-#define PCI230_ADC_BUSY BIT(15) /* ADC busy */
-#define PCI230_ADC_FIFO_EMPTY BIT(12) /* FIFO empty */
-#define PCI230_ADC_FIFO_FULL BIT(13) /* FIFO full */
-#define PCI230_ADC_FIFO_HALF BIT(14) /* FIFO half full */
-#define PCI230_ADC_FIFO_FULL_LATCHED BIT(5) /* FIFO overrun occurred */
-
-/*
- * PCI230 ADC FIFO levels.
- */
-#define PCI230_ADC_FIFOLEVEL_HALFFULL 2049 /* Value for FIFO half full */
-#define PCI230_ADC_FIFOLEVEL_FULL 4096 /* FIFO size */
-
-/*
- * PCI230+ EXTFUNC values.
- */
-/* Route EXTTRIG pin to external gate inputs. */
-#define PCI230P_EXTFUNC_GAT_EXTTRIG BIT(0)
-/* PCI230+ hardware version 2 values. */
-/* Allow DAC FIFO to be enabled. */
-#define PCI230P2_EXTFUNC_DACFIFO BIT(1)
-
-/*
- * Counter/timer clock input configuration sources.
- */
-#define CLK_CLK 0 /* reserved (channel-specific clock) */
-#define CLK_10MHZ 1 /* internal 10 MHz clock */
-#define CLK_1MHZ 2 /* internal 1 MHz clock */
-#define CLK_100KHZ 3 /* internal 100 kHz clock */
-#define CLK_10KHZ 4 /* internal 10 kHz clock */
-#define CLK_1KHZ 5 /* internal 1 kHz clock */
-#define CLK_OUTNM1 6 /* output of channel-1 modulo total */
-#define CLK_EXT 7 /* external clock */
-
-static unsigned int pci230_clk_config(unsigned int chan, unsigned int src)
-{
- return ((chan & 3) << 3) | (src & 7);
-}
-
-/*
- * Counter/timer gate input configuration sources.
- */
-#define GAT_VCC 0 /* VCC (i.e. enabled) */
-#define GAT_GND 1 /* GND (i.e. disabled) */
-#define GAT_EXT 2 /* external gate input (PPCn on PCI230) */
-#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
-
-static unsigned int pci230_gat_config(unsigned int chan, unsigned int src)
-{
- return ((chan & 3) << 3) | (src & 7);
-}
-
-/*
- * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260:
- *
- * Channel's Channel's
- * clock input gate input
- * Channel CLK_OUTNM1 GAT_NOUTNM2
- * ------- ---------- -----------
- * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
- * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
- * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
- */
-
-/*
- * Interrupt enables/status register values.
- */
-#define PCI230_INT_DISABLE 0
-#define PCI230_INT_PPI_C0 BIT(0)
-#define PCI230_INT_PPI_C3 BIT(1)
-#define PCI230_INT_ADC BIT(2)
-#define PCI230_INT_ZCLK_CT1 BIT(5)
-/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
-#define PCI230P2_INT_DAC BIT(4)
-
-/*
- * (Potentially) shared resources and their owners
- */
-enum {
- RES_Z2CT0 = BIT(0), /* Z2-CT0 */
- RES_Z2CT1 = BIT(1), /* Z2-CT1 */
- RES_Z2CT2 = BIT(2) /* Z2-CT2 */
-};
-
-enum {
- OWNER_AICMD, /* Owned by AI command */
- OWNER_AOCMD, /* Owned by AO command */
- NUM_OWNERS /* Number of owners */
-};
-
-/*
- * Handy macros.
- */
-
-/* Combine old and new bits. */
-#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
-
-/* Current CPU. XXX should this be hard_smp_processor_id()? */
-#define THISCPU smp_processor_id()
-
-/*
- * Board descriptions for the two boards supported.
- */
-
-struct pci230_board {
- const char *name;
- unsigned short id;
- unsigned char ai_bits;
- unsigned char ao_bits;
- unsigned char min_hwver; /* Minimum hardware version supported. */
- unsigned int have_dio:1;
-};
-
-static const struct pci230_board pci230_boards[] = {
- {
- .name = "pci230+",
- .id = PCI_DEVICE_ID_PCI230,
- .ai_bits = 16,
- .ao_bits = 12,
- .have_dio = true,
- .min_hwver = 1,
- },
- {
- .name = "pci260+",
- .id = PCI_DEVICE_ID_PCI260,
- .ai_bits = 16,
- .min_hwver = 1,
- },
- {
- .name = "pci230",
- .id = PCI_DEVICE_ID_PCI230,
- .ai_bits = 12,
- .ao_bits = 12,
- .have_dio = true,
- },
- {
- .name = "pci260",
- .id = PCI_DEVICE_ID_PCI260,
- .ai_bits = 12,
- },
-};
-
-struct pci230_private {
- spinlock_t isr_spinlock; /* Interrupt spin lock */
- spinlock_t res_spinlock; /* Shared resources spin lock */
- spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */
- spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */
- unsigned long daqio; /* PCI230's DAQ I/O space */
- int intr_cpuid; /* ID of CPU running ISR */
- unsigned short hwver; /* Hardware version (for '+' models) */
- unsigned short adccon; /* ADCCON register value */
- unsigned short daccon; /* DACCON register value */
- unsigned short adcfifothresh; /* ADC FIFO threshold (PCI230+/260+) */
- unsigned short adcg; /* ADCG register value */
- unsigned char ier; /* Interrupt enable bits */
- unsigned char res_owned[NUM_OWNERS]; /* Owned resources */
- unsigned int intr_running:1; /* Flag set in interrupt routine */
- unsigned int ai_bipolar:1; /* Flag AI range is bipolar */
- unsigned int ao_bipolar:1; /* Flag AO range is bipolar */
- unsigned int ai_cmd_started:1; /* Flag AI command started */
- unsigned int ao_cmd_started:1; /* Flag AO command started */
-};
-
-/* PCI230 clock source periods in ns */
-static const unsigned int pci230_timebase[8] = {
- [CLK_10MHZ] = I8254_OSC_BASE_10MHZ,
- [CLK_1MHZ] = I8254_OSC_BASE_1MHZ,
- [CLK_100KHZ] = I8254_OSC_BASE_100KHZ,
- [CLK_10KHZ] = I8254_OSC_BASE_10KHZ,
- [CLK_1KHZ] = I8254_OSC_BASE_1KHZ,
-};
-
-/* PCI230 analogue input range table */
-static const struct comedi_lrange pci230_ai_range = {
- 7, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5)
- }
-};
-
-/* PCI230 analogue gain bits for each input range. */
-static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 };
-
-/* PCI230 analogue output range table */
-static const struct comedi_lrange pci230_ao_range = {
- 2, {
- UNI_RANGE(10),
- BIP_RANGE(10)
- }
-};
-
-static unsigned short pci230_ai_read(struct comedi_device *dev)
-{
- const struct pci230_board *board = dev->board_ptr;
- struct pci230_private *devpriv = dev->private;
- unsigned short data;
-
- /* Read sample. */
- data = inw(devpriv->daqio + PCI230_ADCDATA);
- /*
- * PCI230 is 12 bit - stored in upper bits of 16 bit register
- * (lower four bits reserved for expansion). PCI230+ is 16 bit AI.
- *
- * If a bipolar range was specified, mangle it
- * (twos complement->straight binary).
- */
- if (devpriv->ai_bipolar)
- data ^= 0x8000;
- data >>= (16 - board->ai_bits);
- return data;
-}
-
-static unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
- unsigned short datum)
-{
- const struct pci230_board *board = dev->board_ptr;
- struct pci230_private *devpriv = dev->private;
-
- /*
- * PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
- * four bits reserved for expansion). PCI230+ is also 12 bit AO.
- */
- datum <<= (16 - board->ao_bits);
- /*
- * If a bipolar range was specified, mangle it
- * (straight binary->twos complement).
- */
- if (devpriv->ao_bipolar)
- datum ^= 0x8000;
- return datum;
-}
-
-static void pci230_ao_write_nofifo(struct comedi_device *dev,
- unsigned short datum, unsigned int chan)
-{
- struct pci230_private *devpriv = dev->private;
-
- /* Write mangled datum to appropriate DACOUT register. */
- outw(pci230_ao_mangle_datum(dev, datum),
- devpriv->daqio + ((chan == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2));
-}
-
-static void pci230_ao_write_fifo(struct comedi_device *dev,
- unsigned short datum, unsigned int chan)
-{
- struct pci230_private *devpriv = dev->private;
-
- /* Write mangled datum to appropriate DACDATA register. */
- outw(pci230_ao_mangle_datum(dev, datum),
- devpriv->daqio + PCI230P2_DACDATA);
-}
-
-static bool pci230_claim_shared(struct comedi_device *dev,
- unsigned char res_mask, unsigned int owner)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned int o;
- unsigned long irqflags;
-
- spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
- for (o = 0; o < NUM_OWNERS; o++) {
- if (o == owner)
- continue;
- if (devpriv->res_owned[o] & res_mask) {
- spin_unlock_irqrestore(&devpriv->res_spinlock,
- irqflags);
- return false;
- }
- }
- devpriv->res_owned[owner] |= res_mask;
- spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
- return true;
-}
-
-static void pci230_release_shared(struct comedi_device *dev,
- unsigned char res_mask, unsigned int owner)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned long irqflags;
-
- spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
- devpriv->res_owned[owner] &= ~res_mask;
- spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
-}
-
-static void pci230_release_all_resources(struct comedi_device *dev,
- unsigned int owner)
-{
- pci230_release_shared(dev, (unsigned char)~0, owner);
-}
-
-static unsigned int pci230_divide_ns(u64 ns, unsigned int timebase,
- unsigned int flags)
-{
- u64 div;
- unsigned int rem;
-
- div = ns;
- rem = do_div(div, timebase);
- switch (flags & CMDF_ROUND_MASK) {
- default:
- case CMDF_ROUND_NEAREST:
- div += DIV_ROUND_CLOSEST(rem, timebase);
- break;
- case CMDF_ROUND_DOWN:
- break;
- case CMDF_ROUND_UP:
- div += DIV_ROUND_UP(rem, timebase);
- break;
- }
- return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
-}
-
-/*
- * Given desired period in ns, returns the required internal clock source
- * and gets the initial count.
- */
-static unsigned int pci230_choose_clk_count(u64 ns, unsigned int *count,
- unsigned int flags)
-{
- unsigned int clk_src, cnt;
-
- for (clk_src = CLK_10MHZ;; clk_src++) {
- cnt = pci230_divide_ns(ns, pci230_timebase[clk_src], flags);
- if (cnt <= 65536 || clk_src == CLK_1KHZ)
- break;
- }
- *count = cnt;
- return clk_src;
-}
-
-static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int flags)
-{
- unsigned int count;
- unsigned int clk_src;
-
- clk_src = pci230_choose_clk_count(*ns, &count, flags);
- *ns = count * pci230_timebase[clk_src];
-}
-
-static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
- unsigned int mode, u64 ns,
- unsigned int flags)
-{
- unsigned int clk_src;
- unsigned int count;
-
- /* Set mode. */
- comedi_8254_set_mode(dev->pacer, ct, mode);
- /* Determine clock source and count. */
- clk_src = pci230_choose_clk_count(ns, &count, flags);
- /* Program clock source. */
- outb(pci230_clk_config(ct, clk_src), dev->iobase + PCI230_ZCLK_SCE);
- /* Set initial count. */
- if (count >= 65536)
- count = 0;
-
- comedi_8254_write(dev->pacer, ct, count);
-}
-
-static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct)
-{
- /* Counter ct, 8254 mode 1, initial count not written. */
- comedi_8254_set_mode(dev->pacer, ct, I8254_MODE1);
-}
-
-static int pci230_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned int status;
-
- status = inw(devpriv->daqio + PCI230_ADCCON);
- if ((status & PCI230_ADC_FIFO_EMPTY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int pci230_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned int n;
- unsigned int chan, range, aref;
- unsigned int gainshift;
- unsigned short adccon, adcen;
- int ret;
-
- /* Unpack channel and range. */
- chan = CR_CHAN(insn->chanspec);
- range = CR_RANGE(insn->chanspec);
- aref = CR_AREF(insn->chanspec);
- if (aref == AREF_DIFF) {
- /* Differential. */
- if (chan >= s->n_chan / 2) {
- dev_dbg(dev->class_dev,
- "%s: differential channel number out of range 0 to %u\n",
- __func__, (s->n_chan / 2) - 1);
- return -EINVAL;
- }
- }
-
- /*
- * Use Z2-CT2 as a conversion trigger instead of the built-in
- * software trigger, as otherwise triggering of differential channels
- * doesn't work properly for some versions of PCI230/260. Also set
- * FIFO mode because the ADC busy bit only works for software triggers.
- */
- adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
- /* Set Z2-CT2 output low to avoid any false triggers. */
- comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0);
- devpriv->ai_bipolar = comedi_range_is_bipolar(s, range);
- if (aref == AREF_DIFF) {
- /* Differential. */
- gainshift = chan * 2;
- if (devpriv->hwver == 0) {
- /*
- * Original PCI230/260 expects both inputs of the
- * differential channel to be enabled.
- */
- adcen = 3 << gainshift;
- } else {
- /*
- * PCI230+/260+ expects only one input of the
- * differential channel to be enabled.
- */
- adcen = 1 << gainshift;
- }
- adccon |= PCI230_ADC_IM_DIF;
- } else {
- /* Single ended. */
- adcen = 1 << chan;
- gainshift = chan & ~1;
- adccon |= PCI230_ADC_IM_SE;
- }
- devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
- (pci230_ai_gain[range] << gainshift);
- if (devpriv->ai_bipolar)
- adccon |= PCI230_ADC_IR_BIP;
- else
- adccon |= PCI230_ADC_IR_UNI;
-
- /*
- * Enable only this channel in the scan list - otherwise by default
- * we'll get one sample from each channel.
- */
- outw(adcen, devpriv->daqio + PCI230_ADCEN);
-
- /* Set gain for channel. */
- outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG);
-
- /* Specify uni/bip, se/diff, conversion source, and reset FIFO. */
- devpriv->adccon = adccon;
- outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON);
-
- /* Convert n samples */
- for (n = 0; n < insn->n; n++) {
- /*
- * Trigger conversion by toggling Z2-CT2 output
- * (finish with output high).
- */
- comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0);
- comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1);
-
- /* wait for conversion to end */
- ret = comedi_timeout(dev, s, insn, pci230_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* read data */
- data[n] = pci230_ai_read(dev);
- }
-
- /* return the number of samples read/written */
- return n;
-}
-
-static int pci230_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- /*
- * Set range - see analogue output range table; 0 => unipolar 10V,
- * 1 => bipolar +/-10V range scale
- */
- devpriv->ao_bipolar = comedi_range_is_bipolar(s, range);
- outw(range, devpriv->daqio + PCI230_DACCON);
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- pci230_ao_write_nofifo(dev, val, chan);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pci230_ao_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int prev_chan = CR_CHAN(cmd->chanlist[0]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- if (chan < prev_chan) {
- dev_dbg(dev->class_dev,
- "%s: channel numbers must increase\n",
- __func__);
- return -EINVAL;
- }
-
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "%s: channels must have the same range\n",
- __func__);
- return -EINVAL;
- }
-
- prev_chan = chan;
- }
-
- return 0;
-}
-
-static int pci230_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- const struct pci230_board *board = dev->board_ptr;
- struct pci230_private *devpriv = dev->private;
- int err = 0;
- unsigned int tmp;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
-
- tmp = TRIG_TIMER | TRIG_INT;
- if (board->min_hwver > 0 && devpriv->hwver >= 2) {
- /*
- * For PCI230+ hardware version 2 onwards, allow external
- * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
- *
- * FIXME: The permitted scan_begin_src values shouldn't depend
- * on devpriv->hwver (the detected card's actual hardware
- * version). They should only depend on board->min_hwver
- * (the static capabilities of the configured card). To fix
- * it, a new card model, e.g. "pci230+2" would have to be
- * defined with min_hwver set to 2. It doesn't seem worth it
- * for this alone. At the moment, please consider
- * scan_begin_src==TRIG_EXT support to be a bonus rather than a
- * guarantee!
- */
- tmp |= TRIG_EXT;
- }
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, tmp);
-
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
-#define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */
-/*
- * Comedi limit due to unsigned int cmd. Driver limit =
- * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
- */
-#define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */
-
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- MAX_SPEED_AO);
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- MIN_SPEED_AO);
- break;
- case TRIG_EXT:
- /*
- * External trigger - for PCI230+ hardware version 2 onwards.
- */
- /* Trigger number must be 0. */
- if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
- cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
- ~CR_FLAGS_MASK);
- err |= -EINVAL;
- }
- /*
- * The only flags allowed are CR_EDGE and CR_INVERT.
- * The CR_EDGE flag is ignored.
- */
- if (cmd->scan_begin_arg & CR_FLAGS_MASK &
- ~(CR_EDGE | CR_INVERT)) {
- cmd->scan_begin_arg =
- COMBINE(cmd->scan_begin_arg, 0,
- CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
- err |= -EINVAL;
- }
- break;
- default:
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- break;
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- tmp = cmd->scan_begin_arg;
- pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
- if (tmp != cmd->scan_begin_arg)
- err++;
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= pci230_ao_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static void pci230_ao_stop(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned long irqflags;
- unsigned char intsrc;
- bool started;
- struct comedi_cmd *cmd;
-
- spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
- started = devpriv->ao_cmd_started;
- devpriv->ao_cmd_started = false;
- spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
- if (!started)
- return;
- cmd = &s->async->cmd;
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Stop scan rate generator. */
- pci230_cancel_ct(dev, 1);
- }
- /* Determine interrupt source. */
- if (devpriv->hwver < 2) {
- /* Not using DAC FIFO. Using CT1 interrupt. */
- intsrc = PCI230_INT_ZCLK_CT1;
- } else {
- /* Using DAC FIFO interrupt. */
- intsrc = PCI230P2_INT_DAC;
- }
- /*
- * Disable interrupt and wait for interrupt routine to finish running
- * unless we are called from the interrupt routine.
- */
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- devpriv->ier &= ~intsrc;
- while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- }
- outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- if (devpriv->hwver >= 2) {
- /*
- * Using DAC FIFO. Reset FIFO, clear underrun error,
- * disable FIFO.
- */
- devpriv->daccon &= PCI230_DAC_OR_MASK;
- outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET |
- PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
- devpriv->daqio + PCI230_DACCON);
- }
- /* Release resources. */
- pci230_release_all_resources(dev, OWNER_AOCMD);
-}
-
-static void pci230_handle_ao_nofifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned short data;
- int i;
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
- return;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (!comedi_buf_read_samples(s, &data, 1)) {
- async->events |= COMEDI_CB_OVERFLOW;
- return;
- }
- pci230_ao_write_nofifo(dev, data, chan);
- s->readback[chan] = data;
- }
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
-}
-
-/*
- * Loads DAC FIFO (if using it) from buffer.
- * Returns false if AO finished due to completion or error, true if still going.
- */
-static bool pci230_handle_ao_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int num_scans = comedi_nscans_left(s, 0);
- unsigned int room;
- unsigned short dacstat;
- unsigned int i, n;
- unsigned int events = 0;
-
- /* Get DAC FIFO status. */
- dacstat = inw(devpriv->daqio + PCI230_DACCON);
-
- if (cmd->stop_src == TRIG_COUNT && num_scans == 0)
- events |= COMEDI_CB_EOA;
-
- if (events == 0) {
- /* Check for FIFO underrun. */
- if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
- dev_err(dev->class_dev, "AO FIFO underrun\n");
- events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
- }
- /*
- * Check for buffer underrun if FIFO less than half full
- * (otherwise there will be loads of "DAC FIFO not half full"
- * interrupts).
- */
- if (num_scans == 0 &&
- (dacstat & PCI230P2_DAC_FIFO_HALF) == 0) {
- dev_err(dev->class_dev, "AO buffer underrun\n");
- events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
- }
- }
- if (events == 0) {
- /* Determine how much room is in the FIFO (in samples). */
- if (dacstat & PCI230P2_DAC_FIFO_FULL)
- room = PCI230P2_DAC_FIFOROOM_FULL;
- else if (dacstat & PCI230P2_DAC_FIFO_HALF)
- room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
- else if (dacstat & PCI230P2_DAC_FIFO_EMPTY)
- room = PCI230P2_DAC_FIFOROOM_EMPTY;
- else
- room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
- /* Convert room to number of scans that can be added. */
- room /= cmd->chanlist_len;
- /* Determine number of scans to process. */
- if (num_scans > room)
- num_scans = room;
- /* Process scans. */
- for (n = 0; n < num_scans; n++) {
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned short datum;
-
- comedi_buf_read_samples(s, &datum, 1);
- pci230_ao_write_fifo(dev, datum, chan);
- s->readback[chan] = datum;
- }
- }
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- /*
- * All data for the command has been written
- * to FIFO. Set FIFO interrupt trigger level
- * to 'empty'.
- */
- devpriv->daccon &= ~PCI230P2_DAC_INT_FIFO_MASK;
- devpriv->daccon |= PCI230P2_DAC_INT_FIFO_EMPTY;
- outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON);
- }
- /* Check if FIFO underrun occurred while writing to FIFO. */
- dacstat = inw(devpriv->daqio + PCI230_DACCON);
- if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
- dev_err(dev->class_dev, "AO FIFO underrun\n");
- events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
- }
- }
- async->events |= events;
- return !(async->events & COMEDI_CB_CANCEL_MASK);
-}
-
-static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned long irqflags;
-
- if (trig_num)
- return -EINVAL;
-
- spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
- if (!devpriv->ao_cmd_started) {
- spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
- return 1;
- }
- /* Perform scan. */
- if (devpriv->hwver < 2) {
- /* Not using DAC FIFO. */
- spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
- pci230_handle_ao_nofifo(dev, s);
- comedi_handle_events(dev, s);
- } else {
- /* Using DAC FIFO. */
- /* Read DACSWTRIG register to trigger conversion. */
- inw(devpriv->daqio + PCI230P2_DACSWTRIG);
- spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
- }
- /* Delay. Should driver be responsible for this? */
- /* XXX TODO: See if DAC busy bit can be used. */
- udelay(8);
- return 1;
-}
-
-static void pci230_ao_start(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned long irqflags;
-
- devpriv->ao_cmd_started = true;
-
- if (devpriv->hwver >= 2) {
- /* Using DAC FIFO. */
- unsigned short scantrig;
- bool run;
-
- /* Preload FIFO data. */
- run = pci230_handle_ao_fifo(dev, s);
- comedi_handle_events(dev, s);
- if (!run) {
- /* Stopped. */
- return;
- }
- /* Set scan trigger source. */
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- scantrig = PCI230P2_DAC_TRIG_Z2CT1;
- break;
- case TRIG_EXT:
- /* Trigger on EXTTRIG/EXTCONVCLK pin. */
- if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
- /* +ve edge */
- scantrig = PCI230P2_DAC_TRIG_EXTP;
- } else {
- /* -ve edge */
- scantrig = PCI230P2_DAC_TRIG_EXTN;
- }
- break;
- case TRIG_INT:
- scantrig = PCI230P2_DAC_TRIG_SW;
- break;
- default:
- /* Shouldn't get here. */
- scantrig = PCI230P2_DAC_TRIG_NONE;
- break;
- }
- devpriv->daccon =
- (devpriv->daccon & ~PCI230P2_DAC_TRIG_MASK) | scantrig;
- outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON);
- }
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- if (devpriv->hwver < 2) {
- /* Not using DAC FIFO. */
- /* Enable CT1 timer interrupt. */
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- devpriv->ier |= PCI230_INT_ZCLK_CT1;
- outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
- spin_unlock_irqrestore(&devpriv->isr_spinlock,
- irqflags);
- }
- /* Set CT1 gate high to start counting. */
- outb(pci230_gat_config(1, GAT_VCC),
- dev->iobase + PCI230_ZGAT_SCE);
- break;
- case TRIG_INT:
- async->inttrig = pci230_ao_inttrig_scan_begin;
- break;
- }
- if (devpriv->hwver >= 2) {
- /* Using DAC FIFO. Enable DAC FIFO interrupt. */
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- devpriv->ier |= PCI230P2_INT_DAC;
- outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- }
-}
-
-static int pci230_ao_inttrig_start(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_src)
- return -EINVAL;
-
- s->async->inttrig = NULL;
- pci230_ao_start(dev, s);
-
- return 1;
-}
-
-static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned short daccon;
- unsigned int range;
-
- /* Get the command. */
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Claim Z2-CT1. */
- if (!pci230_claim_shared(dev, RES_Z2CT1, OWNER_AOCMD))
- return -EBUSY;
- }
-
- /*
- * Set range - see analogue output range table; 0 => unipolar 10V,
- * 1 => bipolar +/-10V range scale
- */
- range = CR_RANGE(cmd->chanlist[0]);
- devpriv->ao_bipolar = comedi_range_is_bipolar(s, range);
- daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
- /* Use DAC FIFO for hardware version 2 onwards. */
- if (devpriv->hwver >= 2) {
- unsigned short dacen;
- unsigned int i;
-
- dacen = 0;
- for (i = 0; i < cmd->chanlist_len; i++)
- dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
-
- /* Set channel scan list. */
- outw(dacen, devpriv->daqio + PCI230P2_DACEN);
- /*
- * Enable DAC FIFO.
- * Set DAC scan source to 'none'.
- * Set DAC FIFO interrupt trigger level to 'not half full'.
- * Reset DAC FIFO and clear underrun.
- *
- * N.B. DAC FIFO interrupts are currently disabled.
- */
- daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET |
- PCI230P2_DAC_FIFO_UNDERRUN_CLEAR |
- PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
- }
-
- /* Set DACCON. */
- outw(daccon, devpriv->daqio + PCI230_DACCON);
- /* Preserve most of DACCON apart from write-only, transient bits. */
- devpriv->daccon = daccon & ~(PCI230P2_DAC_FIFO_RESET |
- PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /*
- * Set the counter timer 1 to the specified scan frequency.
- * cmd->scan_begin_arg is sampling period in ns.
- * Gate it off for now.
- */
- outb(pci230_gat_config(1, GAT_GND),
- dev->iobase + PCI230_ZGAT_SCE);
- pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
- cmd->scan_begin_arg,
- cmd->flags);
- }
-
- /* N.B. cmd->start_src == TRIG_INT */
- s->async->inttrig = pci230_ao_inttrig_start;
-
- return 0;
-}
-
-static int pci230_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- pci230_ao_stop(dev, s);
- return 0;
-}
-
-static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
-{
- unsigned int min_scan_period, chanlist_len;
- int err = 0;
-
- chanlist_len = cmd->chanlist_len;
- if (cmd->chanlist_len == 0)
- chanlist_len = 1;
-
- min_scan_period = chanlist_len * cmd->convert_arg;
- if (min_scan_period < chanlist_len ||
- min_scan_period < cmd->convert_arg) {
- /* Arithmetic overflow. */
- min_scan_period = UINT_MAX;
- err++;
- }
- if (cmd->scan_begin_arg < min_scan_period) {
- cmd->scan_begin_arg = min_scan_period;
- err++;
- }
-
- return !err;
-}
-
-static int pci230_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned int max_diff_chan = (s->n_chan / 2) - 1;
- unsigned int prev_chan = 0;
- unsigned int prev_range = 0;
- unsigned int prev_aref = 0;
- bool prev_bipolar = false;
- unsigned int subseq_len = 0;
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chanspec = cmd->chanlist[i];
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
- bool bipolar = comedi_range_is_bipolar(s, range);
-
- if (aref == AREF_DIFF && chan >= max_diff_chan) {
- dev_dbg(dev->class_dev,
- "%s: differential channel number out of range 0 to %u\n",
- __func__, max_diff_chan);
- return -EINVAL;
- }
-
- if (i > 0) {
- /*
- * Channel numbers must strictly increase or
- * subsequence must repeat exactly.
- */
- if (chan <= prev_chan && subseq_len == 0)
- subseq_len = i;
-
- if (subseq_len > 0 &&
- cmd->chanlist[i % subseq_len] != chanspec) {
- dev_dbg(dev->class_dev,
- "%s: channel numbers must increase or sequence must repeat exactly\n",
- __func__);
- return -EINVAL;
- }
-
- if (aref != prev_aref) {
- dev_dbg(dev->class_dev,
- "%s: channel sequence analogue references must be all the same (single-ended or differential)\n",
- __func__);
- return -EINVAL;
- }
-
- if (bipolar != prev_bipolar) {
- dev_dbg(dev->class_dev,
- "%s: channel sequence ranges must be all bipolar or all unipolar\n",
- __func__);
- return -EINVAL;
- }
-
- if (aref != AREF_DIFF && range != prev_range &&
- ((chan ^ prev_chan) & ~1) == 0) {
- dev_dbg(dev->class_dev,
- "%s: single-ended channel pairs must have the same range\n",
- __func__);
- return -EINVAL;
- }
- }
- prev_chan = chan;
- prev_range = range;
- prev_aref = aref;
- prev_bipolar = bipolar;
- }
-
- if (subseq_len == 0)
- subseq_len = cmd->chanlist_len;
-
- if (cmd->chanlist_len % subseq_len) {
- dev_dbg(dev->class_dev,
- "%s: sequence must repeat exactly\n", __func__);
- return -EINVAL;
- }
-
- /*
- * Buggy PCI230+ or PCI260+ requires channel 0 to be (first) in the
- * sequence if the sequence contains more than one channel. Hardware
- * versions 1 and 2 have the bug. There is no hardware version 3.
- *
- * Actually, there are two firmwares that report themselves as
- * hardware version 1 (the boards have different ADC chips with
- * slightly different timing requirements, which was supposed to
- * be invisible to software). The first one doesn't seem to have
- * the bug, but the second one does, and we can't tell them apart!
- */
- if (devpriv->hwver > 0 && devpriv->hwver < 4) {
- if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0])) {
- dev_info(dev->class_dev,
- "amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n",
- devpriv->hwver);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int pci230_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- const struct pci230_board *board = dev->board_ptr;
- struct pci230_private *devpriv = dev->private;
- int err = 0;
- unsigned int tmp;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
-
- tmp = TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
- if (board->have_dio || board->min_hwver > 0) {
- /*
- * Unfortunately, we cannot trigger a scan off an external
- * source on the PCI260 board, since it uses the PPIC0 (DIO)
- * input, which isn't present on the PCI260. For PCI260+
- * we can use the EXTTRIG/EXTCONVCLK input on pin 17 instead.
- */
- tmp |= TRIG_EXT;
- }
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, tmp);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_INT | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- /*
- * If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
- * set up to generate a fixed number of timed conversion pulses.
- */
- if (cmd->scan_begin_src != TRIG_FOLLOW &&
- cmd->convert_src != TRIG_TIMER)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
-#define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */
-#define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */
-#define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */
-/*
- * Comedi limit due to unsigned int cmd. Driver limit =
- * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
- */
-#define MIN_SPEED_AI 4294967295u /* 4294967295ns = 4.29s */
-
- if (cmd->convert_src == TRIG_TIMER) {
- unsigned int max_speed_ai;
-
- if (devpriv->hwver == 0) {
- /*
- * PCI230 or PCI260. Max speed depends whether
- * single-ended or pseudo-differential.
- */
- if (cmd->chanlist && cmd->chanlist_len > 0) {
- /* Peek analogue reference of first channel. */
- if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
- max_speed_ai = MAX_SPEED_AI_DIFF;
- else
- max_speed_ai = MAX_SPEED_AI_SE;
-
- } else {
- /* No channel list. Assume single-ended. */
- max_speed_ai = MAX_SPEED_AI_SE;
- }
- } else {
- /* PCI230+ or PCI260+. */
- max_speed_ai = MAX_SPEED_AI_PLUS;
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- max_speed_ai);
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
- MIN_SPEED_AI);
- } else if (cmd->convert_src == TRIG_EXT) {
- /*
- * external trigger
- *
- * convert_arg == (CR_EDGE | 0)
- * => trigger on +ve edge.
- * convert_arg == (CR_EDGE | CR_INVERT | 0)
- * => trigger on -ve edge.
- */
- if (cmd->convert_arg & CR_FLAGS_MASK) {
- /* Trigger number must be 0. */
- if (cmd->convert_arg & ~CR_FLAGS_MASK) {
- cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
- ~CR_FLAGS_MASK);
- err |= -EINVAL;
- }
- /*
- * The only flags allowed are CR_INVERT and CR_EDGE.
- * CR_EDGE is required.
- */
- if ((cmd->convert_arg & CR_FLAGS_MASK & ~CR_INVERT) !=
- CR_EDGE) {
- /* Set CR_EDGE, preserve CR_INVERT. */
- cmd->convert_arg =
- COMBINE(cmd->start_arg, CR_EDGE | 0,
- CR_FLAGS_MASK & ~CR_INVERT);
- err |= -EINVAL;
- }
- } else {
- /*
- * Backwards compatibility with previous versions:
- * convert_arg == 0 => trigger on -ve edge.
- * convert_arg == 1 => trigger on +ve edge.
- */
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
- 1);
- }
- } else {
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_EXT) {
- /*
- * external "trigger" to begin each scan:
- * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
- * of CT2 (sample convert trigger is CT2)
- */
- if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
- cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
- ~CR_FLAGS_MASK);
- err |= -EINVAL;
- }
- /* The only flag allowed is CR_EDGE, which is ignored. */
- if (cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) {
- cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
- CR_FLAGS_MASK & ~CR_EDGE);
- err |= -EINVAL;
- }
- } else if (cmd->scan_begin_src == TRIG_TIMER) {
- /* N.B. cmd->convert_arg is also TRIG_TIMER */
- if (!pci230_ai_check_scan_period(cmd))
- err |= -EINVAL;
-
- } else {
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- }
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- tmp = cmd->convert_arg;
- pci230_ns_to_single_timer(&cmd->convert_arg, cmd->flags);
- if (tmp != cmd->convert_arg)
- err++;
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* N.B. cmd->convert_arg is also TRIG_TIMER */
- tmp = cmd->scan_begin_arg;
- pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
- if (!pci230_ai_check_scan_period(cmd)) {
- /* Was below minimum required. Round up. */
- pci230_ns_to_single_timer(&cmd->scan_begin_arg,
- CMDF_ROUND_UP);
- pci230_ai_check_scan_period(cmd);
- }
- if (tmp != cmd->scan_begin_arg)
- err++;
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= pci230_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int wake;
- unsigned short triglev;
- unsigned short adccon;
-
- if (cmd->flags & CMDF_WAKE_EOS)
- wake = cmd->scan_end_arg - s->async->cur_chan;
- else
- wake = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL);
-
- if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
- triglev = PCI230_ADC_INT_FIFO_HALF;
- } else if (wake > 1 && devpriv->hwver > 0) {
- /* PCI230+/260+ programmable FIFO interrupt level. */
- if (devpriv->adcfifothresh != wake) {
- devpriv->adcfifothresh = wake;
- outw(wake, devpriv->daqio + PCI230P_ADCFFTH);
- }
- triglev = PCI230P_ADC_INT_FIFO_THRESH;
- } else {
- triglev = PCI230_ADC_INT_FIFO_NEMPTY;
- }
- adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
- if (adccon != devpriv->adccon) {
- devpriv->adccon = adccon;
- outw(adccon, devpriv->daqio + PCI230_ADCCON);
- }
-}
-
-static int pci230_ai_inttrig_convert(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned long irqflags;
- unsigned int delayus;
-
- if (trig_num)
- return -EINVAL;
-
- spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
- if (!devpriv->ai_cmd_started) {
- spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
- return 1;
- }
- /*
- * Trigger conversion by toggling Z2-CT2 output.
- * Finish with output high.
- */
- comedi_8254_set_mode(dev->pacer, 2, I8254_MODE0);
- comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1);
- /*
- * Delay. Should driver be responsible for this? An
- * alternative would be to wait until conversion is complete,
- * but we can't tell when it's complete because the ADC busy
- * bit has a different meaning when FIFO enabled (and when
- * FIFO not enabled, it only works for software triggers).
- */
- if ((devpriv->adccon & PCI230_ADC_IM_MASK) == PCI230_ADC_IM_DIF &&
- devpriv->hwver == 0) {
- /* PCI230/260 in differential mode */
- delayus = 8;
- } else {
- /* single-ended or PCI230+/260+ */
- delayus = 4;
- }
- spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
- udelay(delayus);
- return 1;
-}
-
-static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned long irqflags;
- unsigned char zgat;
-
- if (trig_num)
- return -EINVAL;
-
- spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
- if (devpriv->ai_cmd_started) {
- /* Trigger scan by waggling CT0 gate source. */
- zgat = pci230_gat_config(0, GAT_GND);
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- zgat = pci230_gat_config(0, GAT_VCC);
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- }
- spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
-
- return 1;
-}
-
-static void pci230_ai_stop(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned long irqflags;
- struct comedi_cmd *cmd;
- bool started;
-
- spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
- started = devpriv->ai_cmd_started;
- devpriv->ai_cmd_started = false;
- spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
- if (!started)
- return;
- cmd = &s->async->cmd;
- if (cmd->convert_src == TRIG_TIMER) {
- /* Stop conversion rate generator. */
- pci230_cancel_ct(dev, 2);
- }
- if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /* Stop scan period monostable. */
- pci230_cancel_ct(dev, 0);
- }
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- /*
- * Disable ADC interrupt and wait for interrupt routine to finish
- * running unless we are called from the interrupt routine.
- */
- devpriv->ier &= ~PCI230_INT_ADC;
- while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- }
- outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- /*
- * Reset FIFO, disable FIFO and set start conversion source to none.
- * Keep se/diff and bip/uni settings.
- */
- devpriv->adccon =
- (devpriv->adccon & (PCI230_ADC_IR_MASK | PCI230_ADC_IM_MASK)) |
- PCI230_ADC_TRIG_NONE;
- outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
- devpriv->daqio + PCI230_ADCCON);
- /* Release resources. */
- pci230_release_all_resources(dev, OWNER_AICMD);
-}
-
-static void pci230_ai_start(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned long irqflags;
- unsigned short conv;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
-
- devpriv->ai_cmd_started = true;
-
- /* Enable ADC FIFO trigger level interrupt. */
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- devpriv->ier |= PCI230_INT_ADC;
- outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
-
- /*
- * Update conversion trigger source which is currently set
- * to CT2 output, which is currently stuck high.
- */
- switch (cmd->convert_src) {
- default:
- conv = PCI230_ADC_TRIG_NONE;
- break;
- case TRIG_TIMER:
- /* Using CT2 output. */
- conv = PCI230_ADC_TRIG_Z2CT2;
- break;
- case TRIG_EXT:
- if (cmd->convert_arg & CR_EDGE) {
- if ((cmd->convert_arg & CR_INVERT) == 0) {
- /* Trigger on +ve edge. */
- conv = PCI230_ADC_TRIG_EXTP;
- } else {
- /* Trigger on -ve edge. */
- conv = PCI230_ADC_TRIG_EXTN;
- }
- } else {
- /* Backwards compatibility. */
- if (cmd->convert_arg) {
- /* Trigger on +ve edge. */
- conv = PCI230_ADC_TRIG_EXTP;
- } else {
- /* Trigger on -ve edge. */
- conv = PCI230_ADC_TRIG_EXTN;
- }
- }
- break;
- case TRIG_INT:
- /*
- * Use CT2 output for software trigger due to problems
- * in differential mode on PCI230/260.
- */
- conv = PCI230_ADC_TRIG_Z2CT2;
- break;
- }
- devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv;
- outw(devpriv->adccon, devpriv->daqio + PCI230_ADCCON);
- if (cmd->convert_src == TRIG_INT)
- async->inttrig = pci230_ai_inttrig_convert;
-
- /*
- * Update FIFO interrupt trigger level, which is currently
- * set to "full".
- */
- pci230_ai_update_fifo_trigger_level(dev, s);
- if (cmd->convert_src == TRIG_TIMER) {
- /* Update timer gates. */
- unsigned char zgat;
-
- if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /*
- * Conversion timer CT2 needs to be gated by
- * inverted output of monostable CT2.
- */
- zgat = pci230_gat_config(2, GAT_NOUTNM2);
- } else {
- /*
- * Conversion timer CT2 needs to be gated on
- * continuously.
- */
- zgat = pci230_gat_config(2, GAT_VCC);
- }
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /* Set monostable CT0 trigger source. */
- switch (cmd->scan_begin_src) {
- default:
- zgat = pci230_gat_config(0, GAT_VCC);
- break;
- case TRIG_EXT:
- /*
- * For CT0 on PCI230, the external trigger
- * (gate) signal comes from PPC0, which is
- * channel 16 of the DIO subdevice. The
- * application needs to configure this as an
- * input in order to use it as an external scan
- * trigger.
- */
- zgat = pci230_gat_config(0, GAT_EXT);
- break;
- case TRIG_TIMER:
- /*
- * Monostable CT0 triggered by rising edge on
- * inverted output of CT1 (falling edge on CT1).
- */
- zgat = pci230_gat_config(0, GAT_NOUTNM2);
- break;
- case TRIG_INT:
- /*
- * Monostable CT0 is triggered by inttrig
- * function waggling the CT0 gate source.
- */
- zgat = pci230_gat_config(0, GAT_VCC);
- break;
- }
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- /*
- * Scan period timer CT1 needs to be
- * gated on to start counting.
- */
- zgat = pci230_gat_config(1, GAT_VCC);
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- break;
- case TRIG_INT:
- async->inttrig = pci230_ai_inttrig_scan_begin;
- break;
- }
- }
- } else if (cmd->convert_src != TRIG_INT) {
- /* No longer need Z2-CT2. */
- pci230_release_shared(dev, RES_Z2CT2, OWNER_AICMD);
- }
-}
-
-static int pci230_ai_inttrig_start(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- s->async->inttrig = NULL;
- pci230_ai_start(dev, s);
-
- return 1;
-}
-
-static void pci230_handle_ai(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int status_fifo;
- unsigned int i;
- unsigned int nsamples;
- unsigned int fifoamount;
- unsigned short val;
-
- /* Determine number of samples to read. */
- nsamples = comedi_nsamples_left(s, PCI230_ADC_FIFOLEVEL_HALFFULL);
- if (nsamples == 0)
- return;
-
- fifoamount = 0;
- for (i = 0; i < nsamples; i++) {
- if (fifoamount == 0) {
- /* Read FIFO state. */
- status_fifo = inw(devpriv->daqio + PCI230_ADCCON);
- if (status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) {
- /*
- * Report error otherwise FIFO overruns will go
- * unnoticed by the caller.
- */
- dev_err(dev->class_dev, "AI FIFO overrun\n");
- async->events |= COMEDI_CB_ERROR;
- break;
- } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) {
- /* FIFO empty. */
- break;
- } else if (status_fifo & PCI230_ADC_FIFO_HALF) {
- /* FIFO half full. */
- fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
- } else if (devpriv->hwver > 0) {
- /* Read PCI230+/260+ ADC FIFO level. */
- fifoamount = inw(devpriv->daqio +
- PCI230P_ADCFFLEV);
- if (fifoamount == 0)
- break; /* Shouldn't happen. */
- } else {
- /* FIFO not empty. */
- fifoamount = 1;
- }
- }
-
- val = pci230_ai_read(dev);
- if (!comedi_buf_write_samples(s, &val, 1))
- break;
-
- fifoamount--;
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- break;
- }
- }
-
- /* update FIFO interrupt trigger level if still running */
- if (!(async->events & COMEDI_CB_CANCEL_MASK))
- pci230_ai_update_fifo_trigger_level(dev, s);
-}
-
-static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pci230_private *devpriv = dev->private;
- unsigned int i, chan, range, diff;
- unsigned int res_mask;
- unsigned short adccon, adcen;
- unsigned char zgat;
-
- /* Get the command. */
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
-
- /*
- * Determine which shared resources are needed.
- */
- res_mask = 0;
- /*
- * Need Z2-CT2 to supply a conversion trigger source at a high
- * logic level, even if not doing timed conversions.
- */
- res_mask |= RES_Z2CT2;
- if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
- res_mask |= RES_Z2CT0;
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Using Z2-CT1 for scan frequency */
- res_mask |= RES_Z2CT1;
- }
- }
- /* Claim resources. */
- if (!pci230_claim_shared(dev, res_mask, OWNER_AICMD))
- return -EBUSY;
-
- /*
- * Steps:
- * - Set channel scan list.
- * - Set channel gains.
- * - Enable and reset FIFO, specify uni/bip, se/diff, and set
- * start conversion source to point to something at a high logic
- * level (we use the output of counter/timer 2 for this purpose.
- * - PAUSE to allow things to settle down.
- * - Reset the FIFO again because it needs resetting twice and there
- * may have been a false conversion trigger on some versions of
- * PCI230/260 due to the start conversion source being set to a
- * high logic level.
- * - Enable ADC FIFO level interrupt.
- * - Set actual conversion trigger source and FIFO interrupt trigger
- * level.
- * - If convert_src is TRIG_TIMER, set up the timers.
- */
-
- adccon = PCI230_ADC_FIFO_EN;
- adcen = 0;
-
- if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
- /* Differential - all channels must be differential. */
- diff = 1;
- adccon |= PCI230_ADC_IM_DIF;
- } else {
- /* Single ended - all channels must be single-ended. */
- diff = 0;
- adccon |= PCI230_ADC_IM_SE;
- }
-
- range = CR_RANGE(cmd->chanlist[0]);
- devpriv->ai_bipolar = comedi_range_is_bipolar(s, range);
- if (devpriv->ai_bipolar)
- adccon |= PCI230_ADC_IR_BIP;
- else
- adccon |= PCI230_ADC_IR_UNI;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int gainshift;
-
- chan = CR_CHAN(cmd->chanlist[i]);
- range = CR_RANGE(cmd->chanlist[i]);
- if (diff) {
- gainshift = 2 * chan;
- if (devpriv->hwver == 0) {
- /*
- * Original PCI230/260 expects both inputs of
- * the differential channel to be enabled.
- */
- adcen |= 3 << gainshift;
- } else {
- /*
- * PCI230+/260+ expects only one input of the
- * differential channel to be enabled.
- */
- adcen |= 1 << gainshift;
- }
- } else {
- gainshift = chan & ~1;
- adcen |= 1 << chan;
- }
- devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
- (pci230_ai_gain[range] << gainshift);
- }
-
- /* Set channel scan list. */
- outw(adcen, devpriv->daqio + PCI230_ADCEN);
-
- /* Set channel gains. */
- outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG);
-
- /*
- * Set counter/timer 2 output high for use as the initial start
- * conversion source.
- */
- comedi_8254_set_mode(dev->pacer, 2, I8254_MODE1);
-
- /*
- * Temporarily use CT2 output as conversion trigger source and
- * temporarily set FIFO interrupt trigger level to 'full'.
- */
- adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
-
- /*
- * Enable and reset FIFO, specify FIFO trigger level full, specify
- * uni/bip, se/diff, and temporarily set the start conversion source
- * to CT2 output. Note that CT2 output is currently high, and this
- * will produce a false conversion trigger on some versions of the
- * PCI230/260, but that will be dealt with later.
- */
- devpriv->adccon = adccon;
- outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON);
-
- /*
- * Delay -
- * Failure to include this will result in the first few channels'-worth
- * of data being corrupt, normally manifesting itself by large negative
- * voltages. It seems the board needs time to settle between the first
- * FIFO reset (above) and the second FIFO reset (below). Setting the
- * channel gains and scan list _before_ the first FIFO reset also
- * helps, though only slightly.
- */
- usleep_range(25, 100);
-
- /* Reset FIFO again. */
- outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON);
-
- if (cmd->convert_src == TRIG_TIMER) {
- /*
- * Set up CT2 as conversion timer, but gate it off for now.
- * Note, counter/timer output 2 can be monitored on the
- * connector: PCI230 pin 21, PCI260 pin 18.
- */
- zgat = pci230_gat_config(2, GAT_GND);
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- /* Set counter/timer 2 to the specified conversion period. */
- pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
- cmd->flags);
- if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /*
- * Set up monostable on CT0 output for scan timing. A
- * rising edge on the trigger (gate) input of CT0 will
- * trigger the monostable, causing its output to go low
- * for the configured period. The period depends on
- * the conversion period and the number of conversions
- * in the scan.
- *
- * Set the trigger high before setting up the
- * monostable to stop it triggering. The trigger
- * source will be changed later.
- */
- zgat = pci230_gat_config(0, GAT_VCC);
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
- ((u64)cmd->convert_arg *
- cmd->scan_end_arg),
- CMDF_ROUND_UP);
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /*
- * Monostable on CT0 will be triggered by
- * output of CT1 at configured scan frequency.
- *
- * Set up CT1 but gate it off for now.
- */
- zgat = pci230_gat_config(1, GAT_GND);
- outb(zgat, dev->iobase + PCI230_ZGAT_SCE);
- pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
- cmd->scan_begin_arg,
- cmd->flags);
- }
- }
- }
-
- if (cmd->start_src == TRIG_INT)
- s->async->inttrig = pci230_ai_inttrig_start;
- else /* TRIG_NOW */
- pci230_ai_start(dev, s);
-
- return 0;
-}
-
-static int pci230_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- pci230_ai_stop(dev, s);
- return 0;
-}
-
-/* Interrupt handler */
-static irqreturn_t pci230_interrupt(int irq, void *d)
-{
- unsigned char status_int, valid_status_int, temp_ier;
- struct comedi_device *dev = d;
- struct pci230_private *devpriv = dev->private;
- struct comedi_subdevice *s_ao = dev->write_subdev;
- struct comedi_subdevice *s_ai = dev->read_subdev;
- unsigned long irqflags;
-
- /* Read interrupt status/enable register. */
- status_int = inb(dev->iobase + PCI230_INT_STAT);
-
- if (status_int == PCI230_INT_DISABLE)
- return IRQ_NONE;
-
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- valid_status_int = devpriv->ier & status_int;
- /*
- * Disable triggered interrupts.
- * (Only those interrupts that need re-enabling, are, later in the
- * handler).
- */
- temp_ier = devpriv->ier & ~status_int;
- outb(temp_ier, dev->iobase + PCI230_INT_SCE);
- devpriv->intr_running = true;
- devpriv->intr_cpuid = THISCPU;
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
-
- /*
- * Check the source of interrupt and handle it.
- * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
- * interrupts. However, at present (Comedi-0.7.60) does not allow
- * concurrent execution of commands, instructions or a mixture of the
- * two.
- */
-
- if (valid_status_int & PCI230_INT_ZCLK_CT1)
- pci230_handle_ao_nofifo(dev, s_ao);
-
- if (valid_status_int & PCI230P2_INT_DAC)
- pci230_handle_ao_fifo(dev, s_ao);
-
- if (valid_status_int & PCI230_INT_ADC)
- pci230_handle_ai(dev, s_ai);
-
- /* Reenable interrupts. */
- spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- if (devpriv->ier != temp_ier)
- outb(devpriv->ier, dev->iobase + PCI230_INT_SCE);
- devpriv->intr_running = false;
- spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
-
- if (s_ao)
- comedi_handle_events(dev, s_ao);
- comedi_handle_events(dev, s_ai);
-
- return IRQ_HANDLED;
-}
-
-/* Check if PCI device matches a specific board. */
-static bool pci230_match_pci_board(const struct pci230_board *board,
- struct pci_dev *pci_dev)
-{
- /* assume pci_dev->device != PCI_DEVICE_ID_INVALID */
- if (board->id != pci_dev->device)
- return false;
- if (board->min_hwver == 0)
- return true;
- /* Looking for a '+' model. First check length of registers. */
- if (pci_resource_len(pci_dev, 3) < 32)
- return false; /* Not a '+' model. */
- /*
- * TODO: temporarily enable PCI device and read the hardware version
- * register. For now, assume it's okay.
- */
- return true;
-}
-
-/* Look for board matching PCI device. */
-static const struct pci230_board *pci230_find_pci_board(struct pci_dev *pci_dev)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(pci230_boards); i++)
- if (pci230_match_pci_board(&pci230_boards[i], pci_dev))
- return &pci230_boards[i];
- return NULL;
-}
-
-static int pci230_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- const struct pci230_board *board;
- struct pci230_private *devpriv;
- struct comedi_subdevice *s;
- int rc;
-
- dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n",
- pci_name(pci_dev));
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- spin_lock_init(&devpriv->isr_spinlock);
- spin_lock_init(&devpriv->res_spinlock);
- spin_lock_init(&devpriv->ai_stop_spinlock);
- spin_lock_init(&devpriv->ao_stop_spinlock);
-
- board = pci230_find_pci_board(pci_dev);
- if (!board) {
- dev_err(dev->class_dev,
- "amplc_pci230: BUG! cannot determine board type!\n");
- return -EINVAL;
- }
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- rc = comedi_pci_enable(dev);
- if (rc)
- return rc;
-
- /*
- * Read base addresses of the PCI230's two I/O regions from PCI
- * configuration register.
- */
- dev->iobase = pci_resource_start(pci_dev, 2);
- devpriv->daqio = pci_resource_start(pci_dev, 3);
- dev_dbg(dev->class_dev,
- "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
- dev->board_name, dev->iobase, devpriv->daqio);
- /* Read bits of DACCON register - only the output range. */
- devpriv->daccon = inw(devpriv->daqio + PCI230_DACCON) &
- PCI230_DAC_OR_MASK;
- /*
- * Read hardware version register and set extended function register
- * if they exist.
- */
- if (pci_resource_len(pci_dev, 3) >= 32) {
- unsigned short extfunc = 0;
-
- devpriv->hwver = inw(devpriv->daqio + PCI230P_HWVER);
- if (devpriv->hwver < board->min_hwver) {
- dev_err(dev->class_dev,
- "%s - bad hardware version - got %u, need %u\n",
- dev->board_name, devpriv->hwver,
- board->min_hwver);
- return -EIO;
- }
- if (devpriv->hwver > 0) {
- if (!board->have_dio) {
- /*
- * No DIO ports. Route counters' external gates
- * to the EXTTRIG signal (PCI260+ pin 17).
- * (Otherwise, they would be routed to DIO
- * inputs PC0, PC1 and PC2 which don't exist
- * on PCI260[+].)
- */
- extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
- }
- if (board->ao_bits && devpriv->hwver >= 2) {
- /* Enable DAC FIFO functionality. */
- extfunc |= PCI230P2_EXTFUNC_DACFIFO;
- }
- }
- outw(extfunc, devpriv->daqio + PCI230P_EXTFUNC);
- if (extfunc & PCI230P2_EXTFUNC_DACFIFO) {
- /*
- * Temporarily enable DAC FIFO, reset it and disable
- * FIFO wraparound.
- */
- outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN |
- PCI230P2_DAC_FIFO_RESET,
- devpriv->daqio + PCI230_DACCON);
- /* Clear DAC FIFO channel enable register. */
- outw(0, devpriv->daqio + PCI230P2_DACEN);
- /* Disable DAC FIFO. */
- outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON);
- }
- }
- /* Disable board's interrupts. */
- outb(0, dev->iobase + PCI230_INT_SCE);
- /* Set ADC to a reasonable state. */
- devpriv->adcg = 0;
- devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE |
- PCI230_ADC_IR_BIP;
- outw(BIT(0), devpriv->daqio + PCI230_ADCEN);
- outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG);
- outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
- devpriv->daqio + PCI230_ADCCON);
-
- if (pci_dev->irq) {
- rc = request_irq(pci_dev->irq, pci230_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (rc == 0)
- dev->irq = pci_dev->irq;
- }
-
- dev->pacer = comedi_8254_init(dev->iobase + PCI230_Z2_CT_BASE,
- 0, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- rc = comedi_alloc_subdevices(dev, 3);
- if (rc)
- return rc;
-
- s = &dev->subdevices[0];
- /* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
- s->n_chan = 16;
- s->maxdata = (1 << board->ai_bits) - 1;
- s->range_table = &pci230_ai_range;
- s->insn_read = pci230_ai_insn_read;
- s->len_chanlist = 256; /* but there are restrictions. */
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->do_cmd = pci230_ai_cmd;
- s->do_cmdtest = pci230_ai_cmdtest;
- s->cancel = pci230_ai_cancel;
- }
-
- s = &dev->subdevices[1];
- /* analog output subdevice */
- if (board->ao_bits) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = 2;
- s->maxdata = (1 << board->ao_bits) - 1;
- s->range_table = &pci230_ao_range;
- s->insn_write = pci230_ao_insn_write;
- s->len_chanlist = 2;
- if (dev->irq) {
- dev->write_subdev = s;
- s->subdev_flags |= SDF_CMD_WRITE;
- s->do_cmd = pci230_ao_cmd;
- s->do_cmdtest = pci230_ao_cmdtest;
- s->cancel = pci230_ao_cancel;
- }
-
- rc = comedi_alloc_subdev_readback(s);
- if (rc)
- return rc;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[2];
- /* digital i/o subdevice */
- if (board->have_dio) {
- rc = subdev_8255_init(dev, s, NULL, PCI230_PPI_X_BASE);
- if (rc)
- return rc;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- return 0;
-}
-
-static struct comedi_driver amplc_pci230_driver = {
- .driver_name = "amplc_pci230",
- .module = THIS_MODULE,
- .auto_attach = pci230_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int amplc_pci230_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &amplc_pci230_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id amplc_pci230_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, amplc_pci230_pci_table);
-
-static struct pci_driver amplc_pci230_pci_driver = {
- .name = "amplc_pci230",
- .id_table = amplc_pci230_pci_table,
- .probe = amplc_pci230_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon PCI230(+) and PCI260(+)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pci236.c b/drivers/staging/comedi/drivers/amplc_pci236.c
deleted file mode 100644
index e7f6fa4d101a..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pci236.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/amplc_pci236.c
- * Driver for Amplicon PCI236 DIO boards.
- *
- * Copyright (C) 2002-2014 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-/*
- * Driver: amplc_pci236
- * Description: Amplicon PCI236
- * Author: Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Amplicon] PCI236 (amplc_pci236)
- * Updated: Fri, 25 Jul 2014 15:32:40 +0000
- * Status: works
- *
- * Configuration options:
- * none
- *
- * Manual configuration of PCI board (PCI236) is not supported; it is
- * configured automatically.
- *
- * The PCI236 board has a single 8255 appearing as subdevice 0.
- *
- * Subdevice 1 pretends to be a digital input device, but it always
- * returns 0 when read. However, if you run a command with
- * scan_begin_src=TRIG_EXT, a rising edge on port C bit 3 acts as an
- * external trigger, which can be used to wake up tasks. This is like
- * the comedi_parport device. If no interrupt is connected, then
- * subdevice 1 is unused.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "amplc_pc236.h"
-#include "plx9052.h"
-
-/* Disable, and clear, interrupts */
-#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1POL | \
- PLX9052_INTCSR_LI2POL | \
- PLX9052_INTCSR_LI1SEL | \
- PLX9052_INTCSR_LI1CLRINT)
-
-/* Enable, and clear, interrupts */
-#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB | \
- PLX9052_INTCSR_LI1POL | \
- PLX9052_INTCSR_LI2POL | \
- PLX9052_INTCSR_PCIENAB | \
- PLX9052_INTCSR_LI1SEL | \
- PLX9052_INTCSR_LI1CLRINT)
-
-static void pci236_intr_update_cb(struct comedi_device *dev, bool enable)
-{
- struct pc236_private *devpriv = dev->private;
-
- /* this will also clear the "local interrupt 1" latch */
- outl(enable ? PCI236_INTR_ENABLE : PCI236_INTR_DISABLE,
- devpriv->lcr_iobase + PLX9052_INTCSR);
-}
-
-static bool pci236_intr_chk_clr_cb(struct comedi_device *dev)
-{
- struct pc236_private *devpriv = dev->private;
-
- /* check if interrupt occurred */
- if (!(inl(devpriv->lcr_iobase + PLX9052_INTCSR) &
- PLX9052_INTCSR_LI1STAT))
- return false;
- /* clear the interrupt */
- pci236_intr_update_cb(dev, devpriv->enable_irq);
- return true;
-}
-
-static const struct pc236_board pc236_pci_board = {
- .name = "pci236",
- .intr_update_cb = pci236_intr_update_cb,
- .intr_chk_clr_cb = pci236_intr_chk_clr_cb,
-};
-
-static int pci236_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- struct pc236_private *devpriv;
- unsigned long iobase;
- int ret;
-
- dev_info(dev->class_dev, "amplc_pci236: attach pci %s\n",
- pci_name(pci_dev));
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- dev->board_ptr = &pc236_pci_board;
- dev->board_name = pc236_pci_board.name;
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
- iobase = pci_resource_start(pci_dev, 2);
- return amplc_pc236_common_attach(dev, iobase, pci_dev->irq,
- IRQF_SHARED);
-}
-
-static struct comedi_driver amplc_pci236_driver = {
- .driver_name = "amplc_pci236",
- .module = THIS_MODULE,
- .auto_attach = pci236_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static const struct pci_device_id pci236_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, 0x0009) },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, pci236_pci_table);
-
-static int amplc_pci236_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &amplc_pci236_driver,
- id->driver_data);
-}
-
-static struct pci_driver amplc_pci236_pci_driver = {
- .name = "amplc_pci236",
- .id_table = pci236_pci_table,
- .probe = &amplc_pci236_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-
-module_comedi_pci_driver(amplc_pci236_driver, amplc_pci236_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon PCI236 DIO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c
deleted file mode 100644
index 9217973f1141..000000000000
--- a/drivers/staging/comedi/drivers/amplc_pci263.c
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Driver for Amplicon PCI263 relay board.
- *
- * Copyright (C) 2002 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: amplc_pci263
- * Description: Amplicon PCI263
- * Author: Ian Abbott <abbotti@mev.co.uk>
- * Devices: [Amplicon] PCI263 (amplc_pci263)
- * Updated: Fri, 12 Apr 2013 15:19:36 +0100
- * Status: works
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * The board appears as one subdevice, with 16 digital outputs, each
- * connected to a reed-relay. Relay contacts are closed when output is 1.
- * The state of the outputs can be read.
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-/* PCI263 registers */
-#define PCI263_DO_0_7_REG 0x00
-#define PCI263_DO_8_15_REG 0x01
-
-static int pci263_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- outb(s->state & 0xff, dev->iobase + PCI263_DO_0_7_REG);
- outb((s->state >> 8) & 0xff, dev->iobase + PCI263_DO_8_15_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pci263_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->iobase = pci_resource_start(pci_dev, 2);
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pci263_do_insn_bits;
-
- /* read initial relay state */
- s->state = inb(dev->iobase + PCI263_DO_0_7_REG) |
- (inb(dev->iobase + PCI263_DO_8_15_REG) << 8);
-
- return 0;
-}
-
-static struct comedi_driver amplc_pci263_driver = {
- .driver_name = "amplc_pci263",
- .module = THIS_MODULE,
- .auto_attach = pci263_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static const struct pci_device_id pci263_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, 0x000c) },
- {0}
-};
-MODULE_DEVICE_TABLE(pci, pci263_pci_table);
-
-static int amplc_pci263_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &amplc_pci263_driver,
- id->driver_data);
-}
-
-static struct pci_driver amplc_pci263_pci_driver = {
- .name = "amplc_pci263",
- .id_table = pci263_pci_table,
- .probe = &amplc_pci263_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(amplc_pci263_driver, amplc_pci263_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Amplicon PCI263 relay board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
deleted file mode 100644
index 786fd15698df..000000000000
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ /dev/null
@@ -1,298 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * c6xdigio.c
- * Hardware driver for Mechatronic Systems Inc. C6x_DIGIO DSP daughter card.
- * http://web.archive.org/web/%2A/http://robot0.ge.uiuc.edu/~spong/mecha/
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999 Dan Block
- */
-
-/*
- * Driver: c6xdigio
- * Description: Mechatronic Systems Inc. C6x_DIGIO DSP daughter card
- * Author: Dan Block
- * Status: unknown
- * Devices: [Mechatronic Systems Inc.] C6x_DIGIO DSP daughter card (c6xdigio)
- * Updated: Sun Nov 20 20:18:34 EST 2005
- *
- * Configuration Options:
- * [0] - base address
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/timer.h>
-#include <linux/io.h>
-#include <linux/pnp.h>
-
-#include "../comedidev.h"
-
-/*
- * Register I/O map
- */
-#define C6XDIGIO_DATA_REG 0x00
-#define C6XDIGIO_DATA_CHAN(x) (((x) + 1) << 4)
-#define C6XDIGIO_DATA_PWM BIT(5)
-#define C6XDIGIO_DATA_ENCODER BIT(6)
-#define C6XDIGIO_STATUS_REG 0x01
-#define C6XDIGIO_CTRL_REG 0x02
-
-#define C6XDIGIO_TIME_OUT 20
-
-static int c6xdigio_chk_status(struct comedi_device *dev, unsigned long context)
-{
- unsigned int status;
- int timeout = 0;
-
- do {
- status = inb(dev->iobase + C6XDIGIO_STATUS_REG);
- if ((status & 0x80) != context)
- return 0;
- timeout++;
- } while (timeout < C6XDIGIO_TIME_OUT);
-
- return -EBUSY;
-}
-
-static int c6xdigio_write_data(struct comedi_device *dev,
- unsigned int val, unsigned int status)
-{
- outb_p(val, dev->iobase + C6XDIGIO_DATA_REG);
- return c6xdigio_chk_status(dev, status);
-}
-
-static int c6xdigio_get_encoder_bits(struct comedi_device *dev,
- unsigned int *bits,
- unsigned int cmd,
- unsigned int status)
-{
- unsigned int val;
-
- val = inb(dev->iobase + C6XDIGIO_STATUS_REG);
- val >>= 3;
- val &= 0x07;
-
- *bits = val;
-
- return c6xdigio_write_data(dev, cmd, status);
-}
-
-static void c6xdigio_pwm_write(struct comedi_device *dev,
- unsigned int chan, unsigned int val)
-{
- unsigned int cmd = C6XDIGIO_DATA_PWM | C6XDIGIO_DATA_CHAN(chan);
- unsigned int bits;
-
- if (val > 498)
- val = 498;
- if (val < 2)
- val = 2;
-
- bits = (val >> 0) & 0x03;
- c6xdigio_write_data(dev, cmd | bits | (0 << 2), 0x00);
- bits = (val >> 2) & 0x03;
- c6xdigio_write_data(dev, cmd | bits | (1 << 2), 0x80);
- bits = (val >> 4) & 0x03;
- c6xdigio_write_data(dev, cmd | bits | (0 << 2), 0x00);
- bits = (val >> 6) & 0x03;
- c6xdigio_write_data(dev, cmd | bits | (1 << 2), 0x80);
- bits = (val >> 8) & 0x03;
- c6xdigio_write_data(dev, cmd | bits | (0 << 2), 0x00);
-
- c6xdigio_write_data(dev, 0x00, 0x80);
-}
-
-static int c6xdigio_encoder_read(struct comedi_device *dev,
- unsigned int chan)
-{
- unsigned int cmd = C6XDIGIO_DATA_ENCODER | C6XDIGIO_DATA_CHAN(chan);
- unsigned int val = 0;
- unsigned int bits;
-
- c6xdigio_write_data(dev, cmd, 0x00);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (1 << 2), 0x80);
- val |= (bits << 0);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (0 << 2), 0x00);
- val |= (bits << 3);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (1 << 2), 0x80);
- val |= (bits << 6);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (0 << 2), 0x00);
- val |= (bits << 9);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (1 << 2), 0x80);
- val |= (bits << 12);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (0 << 2), 0x00);
- val |= (bits << 15);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (1 << 2), 0x80);
- val |= (bits << 18);
-
- c6xdigio_get_encoder_bits(dev, &bits, cmd | (0 << 2), 0x00);
- val |= (bits << 21);
-
- c6xdigio_write_data(dev, 0x00, 0x80);
-
- return val;
-}
-
-static int c6xdigio_pwm_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = (s->state >> (16 * chan)) & 0xffff;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- c6xdigio_pwm_write(dev, chan, val);
- }
-
- /*
- * There are only 2 PWM channels and they have a maxdata of 500.
- * Instead of allocating private data to save the values in for
- * readback this driver just packs the values for the two channels
- * in the s->state.
- */
- s->state &= (0xffff << (16 * chan));
- s->state |= (val << (16 * chan));
-
- return insn->n;
-}
-
-static int c6xdigio_pwm_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
- int i;
-
- val = (s->state >> (16 * chan)) & 0xffff;
-
- for (i = 0; i < insn->n; i++)
- data[i] = val;
-
- return insn->n;
-}
-
-static int c6xdigio_encoder_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = c6xdigio_encoder_read(dev, chan);
-
- /* munge two's complement value to offset binary */
- data[i] = comedi_offset_munge(s, val);
- }
-
- return insn->n;
-}
-
-static void c6xdigio_init(struct comedi_device *dev)
-{
- /* Initialize the PWM */
- c6xdigio_write_data(dev, 0x70, 0x00);
- c6xdigio_write_data(dev, 0x74, 0x80);
- c6xdigio_write_data(dev, 0x70, 0x00);
- c6xdigio_write_data(dev, 0x00, 0x80);
-
- /* Reset the encoders */
- c6xdigio_write_data(dev, 0x68, 0x00);
- c6xdigio_write_data(dev, 0x6c, 0x80);
- c6xdigio_write_data(dev, 0x68, 0x00);
- c6xdigio_write_data(dev, 0x00, 0x80);
-}
-
-static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
- /* Standard LPT Printer Port */
- {.id = "PNP0400", .driver_data = 0},
- /* ECP Printer Port */
- {.id = "PNP0401", .driver_data = 0},
- {}
-};
-
-static struct pnp_driver c6xdigio_pnp_driver = {
- .name = "c6xdigio",
- .id_table = c6xdigio_pnp_tbl,
-};
-
-static int c6xdigio_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x03);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- /* Make sure that PnP ports get activated */
- pnp_register_driver(&c6xdigio_pnp_driver);
-
- s = &dev->subdevices[0];
- /* pwm output subdevice */
- s->type = COMEDI_SUBD_PWM;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 500;
- s->range_table = &range_unknown;
- s->insn_write = c6xdigio_pwm_insn_write;
- s->insn_read = c6xdigio_pwm_insn_read;
-
- s = &dev->subdevices[1];
- /* encoder (counter) subdevice */
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
- s->n_chan = 2;
- s->maxdata = 0xffffff;
- s->range_table = &range_unknown;
- s->insn_read = c6xdigio_encoder_insn_read;
-
- /* I will call this init anyway but more than likely the DSP board */
- /* will not be connected when device driver is loaded. */
- c6xdigio_init(dev);
-
- return 0;
-}
-
-static void c6xdigio_detach(struct comedi_device *dev)
-{
- comedi_legacy_detach(dev);
- pnp_unregister_driver(&c6xdigio_pnp_driver);
-}
-
-static struct comedi_driver c6xdigio_driver = {
- .driver_name = "c6xdigio",
- .module = THIS_MODULE,
- .attach = c6xdigio_attach,
- .detach = c6xdigio_detach,
-};
-module_comedi_driver(c6xdigio_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for the C6x_DIGIO DSP daughter card");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
deleted file mode 100644
index a5d171e71c33..000000000000
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ /dev/null
@@ -1,456 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * cb_das16_cs.c
- * Driver for Computer Boards PC-CARD DAS16/16.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.org>
- *
- * PCMCIA support code for this driver is adapted from the dummy_cs.c
- * driver of the Linux PCMCIA Card Services package.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
- */
-
-/*
- * Driver: cb_das16_cs
- * Description: Computer Boards PC-CARD DAS16/16
- * Devices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs),
- * PC-CARD DAS16/16-AO
- * Author: ds
- * Updated: Mon, 04 Nov 2002 20:04:21 -0800
- * Status: experimental
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include "../comedi_pcmcia.h"
-
-#include "comedi_8254.h"
-
-/*
- * Register I/O map
- */
-#define DAS16CS_AI_DATA_REG 0x00
-#define DAS16CS_AI_MUX_REG 0x02
-#define DAS16CS_AI_MUX_HI_CHAN(x) (((x) & 0xf) << 4)
-#define DAS16CS_AI_MUX_LO_CHAN(x) (((x) & 0xf) << 0)
-#define DAS16CS_AI_MUX_SINGLE_CHAN(x) (DAS16CS_AI_MUX_HI_CHAN(x) | \
- DAS16CS_AI_MUX_LO_CHAN(x))
-#define DAS16CS_MISC1_REG 0x04
-#define DAS16CS_MISC1_INTE BIT(15) /* 1=enable; 0=disable */
-#define DAS16CS_MISC1_INT_SRC(x) (((x) & 0x7) << 12) /* interrupt src */
-#define DAS16CS_MISC1_INT_SRC_NONE DAS16CS_MISC1_INT_SRC(0)
-#define DAS16CS_MISC1_INT_SRC_PACER DAS16CS_MISC1_INT_SRC(1)
-#define DAS16CS_MISC1_INT_SRC_EXT DAS16CS_MISC1_INT_SRC(2)
-#define DAS16CS_MISC1_INT_SRC_FNE DAS16CS_MISC1_INT_SRC(3)
-#define DAS16CS_MISC1_INT_SRC_FHF DAS16CS_MISC1_INT_SRC(4)
-#define DAS16CS_MISC1_INT_SRC_EOS DAS16CS_MISC1_INT_SRC(5)
-#define DAS16CS_MISC1_INT_SRC_MASK DAS16CS_MISC1_INT_SRC(7)
-#define DAS16CS_MISC1_OVR BIT(10) /* ro - 1=FIFO overflow */
-#define DAS16CS_MISC1_AI_CONV(x) (((x) & 0x3) << 8) /* AI convert src */
-#define DAS16CS_MISC1_AI_CONV_SW DAS16CS_MISC1_AI_CONV(0)
-#define DAS16CS_MISC1_AI_CONV_EXT_NEG DAS16CS_MISC1_AI_CONV(1)
-#define DAS16CS_MISC1_AI_CONV_EXT_POS DAS16CS_MISC1_AI_CONV(2)
-#define DAS16CS_MISC1_AI_CONV_PACER DAS16CS_MISC1_AI_CONV(3)
-#define DAS16CS_MISC1_AI_CONV_MASK DAS16CS_MISC1_AI_CONV(3)
-#define DAS16CS_MISC1_EOC BIT(7) /* ro - 0=busy; 1=ready */
-#define DAS16CS_MISC1_SEDIFF BIT(5) /* 0=diff; 1=se */
-#define DAS16CS_MISC1_INTB BIT(4) /* ro - 0=latched; 1=cleared */
-#define DAS16CS_MISC1_MA_MASK (0xf << 0) /* ro - current ai mux */
-#define DAS16CS_MISC1_DAC1CS BIT(3) /* wo - DAC1 chip select */
-#define DAS16CS_MISC1_DACCLK BIT(2) /* wo - Serial DAC clock */
-#define DAS16CS_MISC1_DACSD BIT(1) /* wo - Serial DAC data */
-#define DAS16CS_MISC1_DAC0CS BIT(0) /* wo - DAC0 chip select */
-#define DAS16CS_MISC1_DAC_MASK (0x0f << 0)
-#define DAS16CS_MISC2_REG 0x06
-#define DAS16CS_MISC2_BME BIT(14) /* 1=burst enable; 0=disable */
-#define DAS16CS_MISC2_AI_GAIN(x) (((x) & 0xf) << 8) /* AI gain */
-#define DAS16CS_MISC2_AI_GAIN_1 DAS16CS_MISC2_AI_GAIN(4) /* +/-10V */
-#define DAS16CS_MISC2_AI_GAIN_2 DAS16CS_MISC2_AI_GAIN(0) /* +/-5V */
-#define DAS16CS_MISC2_AI_GAIN_4 DAS16CS_MISC2_AI_GAIN(1) /* +/-2.5V */
-#define DAS16CS_MISC2_AI_GAIN_8 DAS16CS_MISC2_AI_GAIN(2) /* +-1.25V */
-#define DAS16CS_MISC2_AI_GAIN_MASK DAS16CS_MISC2_AI_GAIN(0xf)
-#define DAS16CS_MISC2_UDIR BIT(7) /* 1=dio7:4 output; 0=input */
-#define DAS16CS_MISC2_LDIR BIT(6) /* 1=dio3:0 output; 0=input */
-#define DAS16CS_MISC2_TRGPOL BIT(5) /* 1=active lo; 0=hi */
-#define DAS16CS_MISC2_TRGSEL BIT(4) /* 1=edge; 0=level */
-#define DAS16CS_MISC2_FFNE BIT(3) /* ro - 1=FIFO not empty */
-#define DAS16CS_MISC2_TRGCLR BIT(3) /* wo - 1=clr (monstable) */
-#define DAS16CS_MISC2_CLK2 BIT(2) /* 1=10 MHz; 0=1 MHz */
-#define DAS16CS_MISC2_CTR1 BIT(1) /* 1=int. 100 kHz; 0=ext. clk */
-#define DAS16CS_MISC2_TRG0 BIT(0) /* 1=enable; 0=disable */
-#define DAS16CS_TIMER_BASE 0x08
-#define DAS16CS_DIO_REG 0x10
-
-struct das16cs_board {
- const char *name;
- int device_id;
- unsigned int has_ao:1;
- unsigned int has_4dio:1;
-};
-
-static const struct das16cs_board das16cs_boards[] = {
- {
- .name = "PC-CARD DAS16/16-AO",
- .device_id = 0x0039,
- .has_ao = 1,
- .has_4dio = 1,
- }, {
- .name = "PCM-DAS16s/16",
- .device_id = 0x4009,
- }, {
- .name = "PC-CARD DAS16/16",
- .device_id = 0x0000, /* unknown */
- },
-};
-
-struct das16cs_private {
- unsigned short misc1;
- unsigned short misc2;
-};
-
-static const struct comedi_lrange das16cs_ai_range = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- }
-};
-
-static int das16cs_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + DAS16CS_MISC1_REG);
- if (status & DAS16CS_MISC1_EOC)
- return 0;
- return -EBUSY;
-}
-
-static int das16cs_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct das16cs_private *devpriv = dev->private;
- int chan = CR_CHAN(insn->chanspec);
- int range = CR_RANGE(insn->chanspec);
- int aref = CR_AREF(insn->chanspec);
- int ret;
- int i;
-
- outw(DAS16CS_AI_MUX_SINGLE_CHAN(chan),
- dev->iobase + DAS16CS_AI_MUX_REG);
-
- /* disable interrupts, software convert */
- devpriv->misc1 &= ~(DAS16CS_MISC1_INTE | DAS16CS_MISC1_INT_SRC_MASK |
- DAS16CS_MISC1_AI_CONV_MASK);
- if (aref == AREF_DIFF)
- devpriv->misc1 &= ~DAS16CS_MISC1_SEDIFF;
- else
- devpriv->misc1 |= DAS16CS_MISC1_SEDIFF;
- outw(devpriv->misc1, dev->iobase + DAS16CS_MISC1_REG);
-
- devpriv->misc2 &= ~(DAS16CS_MISC2_BME | DAS16CS_MISC2_AI_GAIN_MASK);
- switch (range) {
- case 0:
- devpriv->misc2 |= DAS16CS_MISC2_AI_GAIN_1;
- break;
- case 1:
- devpriv->misc2 |= DAS16CS_MISC2_AI_GAIN_2;
- break;
- case 2:
- devpriv->misc2 |= DAS16CS_MISC2_AI_GAIN_4;
- break;
- case 3:
- devpriv->misc2 |= DAS16CS_MISC2_AI_GAIN_8;
- break;
- }
- outw(devpriv->misc2, dev->iobase + DAS16CS_MISC2_REG);
-
- for (i = 0; i < insn->n; i++) {
- outw(0, dev->iobase + DAS16CS_AI_DATA_REG);
-
- ret = comedi_timeout(dev, s, insn, das16cs_ai_eoc, 0);
- if (ret)
- return ret;
-
- data[i] = inw(dev->iobase + DAS16CS_AI_DATA_REG);
- }
-
- return i;
-}
-
-static int das16cs_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct das16cs_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- unsigned short misc1;
- int bit;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- outw(devpriv->misc1, dev->iobase + DAS16CS_MISC1_REG);
- udelay(1);
-
- /* raise the DACxCS line for the non-selected channel */
- misc1 = devpriv->misc1 & ~DAS16CS_MISC1_DAC_MASK;
- if (chan)
- misc1 |= DAS16CS_MISC1_DAC0CS;
- else
- misc1 |= DAS16CS_MISC1_DAC1CS;
-
- outw(misc1, dev->iobase + DAS16CS_MISC1_REG);
- udelay(1);
-
- for (bit = 15; bit >= 0; bit--) {
- if ((val >> bit) & 0x1)
- misc1 |= DAS16CS_MISC1_DACSD;
- else
- misc1 &= ~DAS16CS_MISC1_DACSD;
- outw(misc1, dev->iobase + DAS16CS_MISC1_REG);
- udelay(1);
- outw(misc1 | DAS16CS_MISC1_DACCLK,
- dev->iobase + DAS16CS_MISC1_REG);
- udelay(1);
- }
- /*
- * Make both DAC0CS and DAC1CS high to load
- * the new data and update analog the output
- */
- outw(misc1 | DAS16CS_MISC1_DAC0CS | DAS16CS_MISC1_DAC1CS,
- dev->iobase + DAS16CS_MISC1_REG);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int das16cs_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + DAS16CS_DIO_REG);
-
- data[1] = inw(dev->iobase + DAS16CS_DIO_REG);
-
- return insn->n;
-}
-
-static int das16cs_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct das16cs_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 4)
- mask = 0x0f;
- else
- mask = 0xf0;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- if (s->io_bits & 0xf0)
- devpriv->misc2 |= DAS16CS_MISC2_UDIR;
- else
- devpriv->misc2 &= ~DAS16CS_MISC2_UDIR;
- if (s->io_bits & 0x0f)
- devpriv->misc2 |= DAS16CS_MISC2_LDIR;
- else
- devpriv->misc2 &= ~DAS16CS_MISC2_LDIR;
- outw(devpriv->misc2, dev->iobase + DAS16CS_MISC2_REG);
-
- return insn->n;
-}
-
-static int das16cs_counter_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct das16cs_private *devpriv = dev->private;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_CLOCK_SRC:
- switch (data[1]) {
- case 0: /* internal 100 kHz */
- devpriv->misc2 |= DAS16CS_MISC2_CTR1;
- break;
- case 1: /* external */
- devpriv->misc2 &= ~DAS16CS_MISC2_CTR1;
- break;
- default:
- return -EINVAL;
- }
- outw(devpriv->misc2, dev->iobase + DAS16CS_MISC2_REG);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- if (devpriv->misc2 & DAS16CS_MISC2_CTR1) {
- data[1] = 0;
- data[2] = I8254_OSC_BASE_100KHZ;
- } else {
- data[1] = 1;
- data[2] = 0; /* unknown */
- }
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static const void *das16cs_find_boardinfo(struct comedi_device *dev,
- struct pcmcia_device *link)
-{
- const struct das16cs_board *board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(das16cs_boards); i++) {
- board = &das16cs_boards[i];
- if (board->device_id == link->card_id)
- return board;
- }
-
- return NULL;
-}
-
-static int das16cs_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- const struct das16cs_board *board;
- struct das16cs_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- board = das16cs_find_boardinfo(dev, link);
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
- ret = comedi_pcmcia_enable(dev, NULL);
- if (ret)
- return ret;
- dev->iobase = link->resource[0]->start;
-
- link->priv = dev;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- dev->pacer = comedi_8254_init(dev->iobase + DAS16CS_TIMER_BASE,
- I8254_OSC_BASE_10MHZ, I8254_IO16, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = 0xffff;
- s->range_table = &das16cs_ai_range;
- s->insn_read = das16cs_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar10;
- s->insn_write = &das16cs_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = board->has_4dio ? 4 : 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das16cs_dio_insn_bits;
- s->insn_config = das16cs_dio_insn_config;
-
- /* Counter subdevice (8254) */
- s = &dev->subdevices[3];
- comedi_8254_subdevice_init(s, dev->pacer);
-
- dev->pacer->insn_config = das16cs_counter_insn_config;
-
- /* counters 1 and 2 are used internally for the pacer */
- comedi_8254_set_busy(dev->pacer, 1, true);
- comedi_8254_set_busy(dev->pacer, 2, true);
-
- return 0;
-}
-
-static struct comedi_driver driver_das16cs = {
- .driver_name = "cb_das16_cs",
- .module = THIS_MODULE,
- .auto_attach = das16cs_auto_attach,
- .detach = comedi_pcmcia_disable,
-};
-
-static int das16cs_pcmcia_attach(struct pcmcia_device *link)
-{
- return comedi_pcmcia_auto_config(link, &driver_das16cs);
-}
-
-static const struct pcmcia_device_id das16cs_id_table[] = {
- PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039),
- PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
-
-static struct pcmcia_driver das16cs_driver = {
- .name = "cb_das16_cs",
- .owner = THIS_MODULE,
- .id_table = das16cs_id_table,
- .probe = das16cs_pcmcia_attach,
- .remove = comedi_pcmcia_auto_unconfig,
-};
-module_comedi_pcmcia_driver(driver_das16cs, das16cs_driver);
-
-MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");
-MODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
deleted file mode 100644
index 2f20bd56ec6c..000000000000
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ /dev/null
@@ -1,1499 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * cb_pcidas.c
- * Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
- * David Schleef and the rest of the Comedi developers comunity.
- *
- * Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
- * Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: cb_pcidas
- * Description: MeasurementComputing PCI-DAS series
- * with the AMCC S5933 PCI controller
- * Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
- * PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
- * PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
- * Author: Ivan Martinez <imr@oersted.dtu.dk>,
- * Frank Mori Hess <fmhess@users.sourceforge.net>
- * Updated: 2003-3-11
- *
- * Status:
- * There are many reports of the driver being used with most of the
- * supported cards. Despite no detailed log is maintained, it can
- * be said that the driver is quite tested and stable.
- *
- * The boards may be autocalibrated using the comedi_calibrate
- * utility.
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * For commands, the scanned channels must be consecutive
- * (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
- * range and aref.
- *
- * AI Triggering:
- * For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
- * For 1602 series, the start_arg is interpreted as follows:
- * start_arg == 0 => gated trigger (level high)
- * start_arg == CR_INVERT => gated trigger (level low)
- * start_arg == CR_EDGE => Rising edge
- * start_arg == CR_EDGE | CR_INVERT => Falling edge
- * For the other boards the trigger will be done on rising edge
- */
-
-/*
- * TODO:
- * analog triggering on 1602 series
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "comedi_8254.h"
-#include "8255.h"
-#include "amcc_s5933.h"
-
-#define AI_BUFFER_SIZE 1024 /* max ai fifo size */
-#define AO_BUFFER_SIZE 1024 /* max ao fifo size */
-
-/*
- * PCI BAR1 Register map (devpriv->pcibar1)
- */
-#define PCIDAS_CTRL_REG 0x00 /* INTERRUPT / ADC FIFO register */
-#define PCIDAS_CTRL_INT(x) (((x) & 0x3) << 0)
-#define PCIDAS_CTRL_INT_NONE PCIDAS_CTRL_INT(0) /* no int selected */
-#define PCIDAS_CTRL_INT_EOS PCIDAS_CTRL_INT(1) /* int on end of scan */
-#define PCIDAS_CTRL_INT_FHF PCIDAS_CTRL_INT(2) /* int on fifo half full */
-#define PCIDAS_CTRL_INT_FNE PCIDAS_CTRL_INT(3) /* int on fifo not empty */
-#define PCIDAS_CTRL_INT_MASK PCIDAS_CTRL_INT(3) /* mask of int select bits */
-#define PCIDAS_CTRL_INTE BIT(2) /* int enable */
-#define PCIDAS_CTRL_DAHFIE BIT(3) /* dac half full int enable */
-#define PCIDAS_CTRL_EOAIE BIT(4) /* end of acq. int enable */
-#define PCIDAS_CTRL_DAHFI BIT(5) /* dac half full status / clear */
-#define PCIDAS_CTRL_EOAI BIT(6) /* end of acq. int status / clear */
-#define PCIDAS_CTRL_INT_CLR BIT(7) /* int status / clear */
-#define PCIDAS_CTRL_EOBI BIT(9) /* end of burst int status */
-#define PCIDAS_CTRL_ADHFI BIT(10) /* half-full int status */
-#define PCIDAS_CTRL_ADNEI BIT(11) /* fifo not empty int status (latch) */
-#define PCIDAS_CTRL_ADNE BIT(12) /* fifo not empty status (realtime) */
-#define PCIDAS_CTRL_DAEMIE BIT(12) /* dac empty int enable */
-#define PCIDAS_CTRL_LADFUL BIT(13) /* fifo overflow / clear */
-#define PCIDAS_CTRL_DAEMI BIT(14) /* dac fifo empty int status / clear */
-
-#define PCIDAS_CTRL_AI_INT (PCIDAS_CTRL_EOAI | PCIDAS_CTRL_EOBI | \
- PCIDAS_CTRL_ADHFI | PCIDAS_CTRL_ADNEI | \
- PCIDAS_CTRL_LADFUL)
-#define PCIDAS_CTRL_AO_INT (PCIDAS_CTRL_DAHFI | PCIDAS_CTRL_DAEMI)
-
-#define PCIDAS_AI_REG 0x02 /* ADC CHANNEL MUX AND CONTROL reg */
-#define PCIDAS_AI_FIRST(x) ((x) & 0xf)
-#define PCIDAS_AI_LAST(x) (((x) & 0xf) << 4)
-#define PCIDAS_AI_CHAN(x) (PCIDAS_AI_FIRST(x) | PCIDAS_AI_LAST(x))
-#define PCIDAS_AI_GAIN(x) (((x) & 0x3) << 8)
-#define PCIDAS_AI_SE BIT(10) /* Inputs in single-ended mode */
-#define PCIDAS_AI_UNIP BIT(11) /* Analog front-end unipolar mode */
-#define PCIDAS_AI_PACER(x) (((x) & 0x3) << 12)
-#define PCIDAS_AI_PACER_SW PCIDAS_AI_PACER(0) /* software pacer */
-#define PCIDAS_AI_PACER_INT PCIDAS_AI_PACER(1) /* int. pacer */
-#define PCIDAS_AI_PACER_EXTN PCIDAS_AI_PACER(2) /* ext. falling edge */
-#define PCIDAS_AI_PACER_EXTP PCIDAS_AI_PACER(3) /* ext. rising edge */
-#define PCIDAS_AI_PACER_MASK PCIDAS_AI_PACER(3) /* pacer source bits */
-#define PCIDAS_AI_EOC BIT(14) /* adc not busy */
-
-#define PCIDAS_TRIG_REG 0x04 /* TRIGGER CONTROL/STATUS register */
-#define PCIDAS_TRIG_SEL(x) (((x) & 0x3) << 0)
-#define PCIDAS_TRIG_SEL_NONE PCIDAS_TRIG_SEL(0) /* no start trigger */
-#define PCIDAS_TRIG_SEL_SW PCIDAS_TRIG_SEL(1) /* software start trigger */
-#define PCIDAS_TRIG_SEL_EXT PCIDAS_TRIG_SEL(2) /* ext. start trigger */
-#define PCIDAS_TRIG_SEL_ANALOG PCIDAS_TRIG_SEL(3) /* ext. analog trigger */
-#define PCIDAS_TRIG_SEL_MASK PCIDAS_TRIG_SEL(3) /* start trigger mask */
-#define PCIDAS_TRIG_POL BIT(2) /* invert trigger (1602 only) */
-#define PCIDAS_TRIG_MODE BIT(3) /* edge/level triggered (1602 only) */
-#define PCIDAS_TRIG_EN BIT(4) /* enable external start trigger */
-#define PCIDAS_TRIG_BURSTE BIT(5) /* burst mode enable */
-#define PCIDAS_TRIG_CLR BIT(7) /* clear external trigger */
-
-#define PCIDAS_CALIB_REG 0x06 /* CALIBRATION register */
-#define PCIDAS_CALIB_8800_SEL BIT(8) /* select 8800 caldac */
-#define PCIDAS_CALIB_TRIM_SEL BIT(9) /* select ad7376 trim pot */
-#define PCIDAS_CALIB_DAC08_SEL BIT(10) /* select dac08 caldac */
-#define PCIDAS_CALIB_SRC(x) (((x) & 0x7) << 11)
-#define PCIDAS_CALIB_EN BIT(14) /* calibration source enable */
-#define PCIDAS_CALIB_DATA BIT(15) /* serial data bit going to caldac */
-
-#define PCIDAS_AO_REG 0x08 /* dac control and status register */
-#define PCIDAS_AO_EMPTY BIT(0) /* fifo empty, write clear (1602) */
-#define PCIDAS_AO_DACEN BIT(1) /* dac enable */
-#define PCIDAS_AO_START BIT(2) /* start/arm fifo (1602) */
-#define PCIDAS_AO_PACER(x) (((x) & 0x3) << 3) /* (1602) */
-#define PCIDAS_AO_PACER_SW PCIDAS_AO_PACER(0) /* software pacer */
-#define PCIDAS_AO_PACER_INT PCIDAS_AO_PACER(1) /* int. pacer */
-#define PCIDAS_AO_PACER_EXTN PCIDAS_AO_PACER(2) /* ext. falling edge */
-#define PCIDAS_AO_PACER_EXTP PCIDAS_AO_PACER(3) /* ext. rising edge */
-#define PCIDAS_AO_PACER_MASK PCIDAS_AO_PACER(3) /* pacer source bits */
-#define PCIDAS_AO_CHAN_EN(c) BIT(5 + ((c) & 0x1))
-#define PCIDAS_AO_CHAN_MASK (PCIDAS_AO_CHAN_EN(0) | PCIDAS_AO_CHAN_EN(1))
-#define PCIDAS_AO_UPDATE_BOTH BIT(7) /* update both dacs */
-#define PCIDAS_AO_RANGE(c, r) (((r) & 0x3) << (8 + 2 * ((c) & 0x1)))
-#define PCIDAS_AO_RANGE_MASK(c) PCIDAS_AO_RANGE((c), 0x3)
-
-/*
- * PCI BAR2 Register map (devpriv->pcibar2)
- */
-#define PCIDAS_AI_DATA_REG 0x00
-#define PCIDAS_AI_FIFO_CLR_REG 0x02
-
-/*
- * PCI BAR3 Register map (dev->iobase)
- */
-#define PCIDAS_AI_8254_BASE 0x00
-#define PCIDAS_8255_BASE 0x04
-#define PCIDAS_AO_8254_BASE 0x08
-
-/*
- * PCI BAR4 Register map (devpriv->pcibar4)
- */
-#define PCIDAS_AO_DATA_REG(x) (0x00 + ((x) * 2))
-#define PCIDAS_AO_FIFO_REG 0x00
-#define PCIDAS_AO_FIFO_CLR_REG 0x02
-
-/* analog input ranges for most boards */
-static const struct comedi_lrange cb_pcidas_ranges = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-/* pci-das1001 input ranges */
-static const struct comedi_lrange cb_pcidas_alt_ranges = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.01),
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01)
- }
-};
-
-/* analog output ranges */
-static const struct comedi_lrange cb_pcidas_ao_ranges = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-enum cb_pcidas_boardid {
- BOARD_PCIDAS1602_16,
- BOARD_PCIDAS1200,
- BOARD_PCIDAS1602_12,
- BOARD_PCIDAS1200_JR,
- BOARD_PCIDAS1602_16_JR,
- BOARD_PCIDAS1000,
- BOARD_PCIDAS1001,
- BOARD_PCIDAS1002,
-};
-
-struct cb_pcidas_board {
- const char *name;
- int ai_speed; /* fastest conversion period in ns */
- int ao_scan_speed; /* analog output scan speed for 1602 series */
- int fifo_size; /* number of samples fifo can hold */
- unsigned int is_16bit; /* ai/ao is 1=16-bit; 0=12-bit */
- unsigned int use_alt_range:1; /* use alternate ai range table */
- unsigned int has_ao:1; /* has 2 analog output channels */
- unsigned int has_ao_fifo:1; /* analog output has fifo */
- unsigned int has_ad8402:1; /* trimpot type 1=AD8402; 0=AD7376 */
- unsigned int has_dac08:1;
- unsigned int is_1602:1;
-};
-
-static const struct cb_pcidas_board cb_pcidas_boards[] = {
- [BOARD_PCIDAS1602_16] = {
- .name = "pci-das1602/16",
- .ai_speed = 5000,
- .ao_scan_speed = 10000,
- .fifo_size = 512,
- .is_16bit = 1,
- .has_ao = 1,
- .has_ao_fifo = 1,
- .has_ad8402 = 1,
- .has_dac08 = 1,
- .is_1602 = 1,
- },
- [BOARD_PCIDAS1200] = {
- .name = "pci-das1200",
- .ai_speed = 3200,
- .fifo_size = 1024,
- .has_ao = 1,
- },
- [BOARD_PCIDAS1602_12] = {
- .name = "pci-das1602/12",
- .ai_speed = 3200,
- .ao_scan_speed = 4000,
- .fifo_size = 1024,
- .has_ao = 1,
- .has_ao_fifo = 1,
- .is_1602 = 1,
- },
- [BOARD_PCIDAS1200_JR] = {
- .name = "pci-das1200/jr",
- .ai_speed = 3200,
- .fifo_size = 1024,
- },
- [BOARD_PCIDAS1602_16_JR] = {
- .name = "pci-das1602/16/jr",
- .ai_speed = 5000,
- .fifo_size = 512,
- .is_16bit = 1,
- .has_ad8402 = 1,
- .has_dac08 = 1,
- .is_1602 = 1,
- },
- [BOARD_PCIDAS1000] = {
- .name = "pci-das1000",
- .ai_speed = 4000,
- .fifo_size = 1024,
- },
- [BOARD_PCIDAS1001] = {
- .name = "pci-das1001",
- .ai_speed = 6800,
- .fifo_size = 1024,
- .use_alt_range = 1,
- .has_ao = 1,
- },
- [BOARD_PCIDAS1002] = {
- .name = "pci-das1002",
- .ai_speed = 6800,
- .fifo_size = 1024,
- .has_ao = 1,
- },
-};
-
-struct cb_pcidas_private {
- struct comedi_8254 *ao_pacer;
- /* base addresses */
- unsigned long amcc; /* pcibar0 */
- unsigned long pcibar1;
- unsigned long pcibar2;
- unsigned long pcibar4;
- /* bits to write to registers */
- unsigned int ctrl;
- unsigned int amcc_intcsr;
- unsigned int ao_ctrl;
- /* fifo buffers */
- unsigned short ai_buffer[AI_BUFFER_SIZE];
- unsigned short ao_buffer[AO_BUFFER_SIZE];
- unsigned int calib_src;
-};
-
-static int cb_pcidas_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int status;
-
- status = inw(devpriv->pcibar1 + PCIDAS_AI_REG);
- if (status & PCIDAS_AI_EOC)
- return 0;
- return -EBUSY;
-}
-
-static int cb_pcidas_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- unsigned int bits;
- int ret;
- int n;
-
- /* enable calibration input if appropriate */
- if (insn->chanspec & CR_ALT_SOURCE) {
- outw(PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src),
- devpriv->pcibar1 + PCIDAS_CALIB_REG);
- chan = 0;
- } else {
- outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG);
- }
-
- /* set mux limits and gain */
- bits = PCIDAS_AI_CHAN(chan) | PCIDAS_AI_GAIN(range);
- /* set unipolar/bipolar */
- if (comedi_range_is_unipolar(s, range))
- bits |= PCIDAS_AI_UNIP;
- /* set single-ended/differential */
- if (aref != AREF_DIFF)
- bits |= PCIDAS_AI_SE;
- outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG);
-
- /* clear fifo */
- outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
-
- /* convert n samples */
- for (n = 0; n < insn->n; n++) {
- /* trigger conversion */
- outw(0, devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
-
- /* wait for conversion to end */
- ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* read data */
- data[n] = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
- }
-
- /* return the number of samples read/written */
- return n;
-}
-
-static int cb_pcidas_ai_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- int id = data[0];
- unsigned int source = data[1];
-
- switch (id) {
- case INSN_CONFIG_ALT_SOURCE:
- if (source >= 8) {
- dev_err(dev->class_dev,
- "invalid calibration source: %i\n",
- source);
- return -EINVAL;
- }
- devpriv->calib_src = source;
- break;
- default:
- return -EINVAL;
- }
- return insn->n;
-}
-
-/* analog output insn for pcidas-1000 and 1200 series */
-static int cb_pcidas_ao_nofifo_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val = s->readback[chan];
- unsigned long flags;
- int i;
-
- /* set channel and range */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->ao_ctrl &= ~(PCIDAS_AO_UPDATE_BOTH |
- PCIDAS_AO_RANGE_MASK(chan));
- devpriv->ao_ctrl |= PCIDAS_AO_DACEN | PCIDAS_AO_RANGE(chan, range);
- outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outw(val, devpriv->pcibar4 + PCIDAS_AO_DATA_REG(chan));
- }
-
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-/* analog output insn for pcidas-1602 series */
-static int cb_pcidas_ao_fifo_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val = s->readback[chan];
- unsigned long flags;
- int i;
-
- /* clear dac fifo */
- outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
-
- /* set channel and range */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->ao_ctrl &= ~(PCIDAS_AO_CHAN_MASK | PCIDAS_AO_RANGE_MASK(chan) |
- PCIDAS_AO_PACER_MASK);
- devpriv->ao_ctrl |= PCIDAS_AO_DACEN | PCIDAS_AO_RANGE(chan, range) |
- PCIDAS_AO_CHAN_EN(chan) | PCIDAS_AO_START;
- outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outw(val, devpriv->pcibar4 + PCIDAS_AO_FIFO_REG);
- }
-
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int cb_pcidas_eeprom_ready(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int status;
-
- status = inb(devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
- if ((status & MCSR_NV_BUSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int cb_pcidas_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- /* make sure eeprom is ready */
- ret = comedi_timeout(dev, s, insn, cb_pcidas_eeprom_ready, 0);
- if (ret)
- return ret;
-
- /* set address (chan) and read operation */
- outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
- devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
- outb(chan & 0xff, devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA);
- outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
- devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
- outb((chan >> 8) & 0xff,
- devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA);
- outb(MCSR_NV_ENABLE | MCSR_NV_READ,
- devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
-
- /* wait for data to be returned */
- ret = comedi_timeout(dev, s, insn, cb_pcidas_eeprom_ready, 0);
- if (ret)
- return ret;
-
- data[i] = inb(devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA);
- }
-
- return insn->n;
-}
-
-static void cb_pcidas_calib_write(struct comedi_device *dev,
- unsigned int val, unsigned int len,
- bool trimpot)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int calib_bits;
- unsigned int bit;
-
- calib_bits = PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src);
- if (trimpot) {
- /* select trimpot */
- calib_bits |= PCIDAS_CALIB_TRIM_SEL;
- outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
- }
-
- /* write bitstream to calibration device */
- for (bit = 1 << (len - 1); bit; bit >>= 1) {
- if (val & bit)
- calib_bits |= PCIDAS_CALIB_DATA;
- else
- calib_bits &= ~PCIDAS_CALIB_DATA;
- udelay(1);
- outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
- }
- udelay(1);
-
- calib_bits = PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src);
-
- if (!trimpot) {
- /* select caldac */
- outw(calib_bits | PCIDAS_CALIB_8800_SEL,
- devpriv->pcibar1 + PCIDAS_CALIB_REG);
- udelay(1);
- }
-
- /* latch value to trimpot/caldac */
- outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
-}
-
-static int cb_pcidas_caldac_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- if (s->readback[chan] != val) {
- /* write 11-bit channel/value to caldac */
- cb_pcidas_calib_write(dev, (chan << 8) | val, 11,
- false);
- s->readback[chan] = val;
- }
- }
-
- return insn->n;
-}
-
-static void cb_pcidas_dac08_write(struct comedi_device *dev, unsigned int val)
-{
- struct cb_pcidas_private *devpriv = dev->private;
-
- val |= PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src);
-
- /* latch the new value into the caldac */
- outw(val, devpriv->pcibar1 + PCIDAS_CALIB_REG);
- udelay(1);
- outw(val | PCIDAS_CALIB_DAC08_SEL,
- devpriv->pcibar1 + PCIDAS_CALIB_REG);
- udelay(1);
- outw(val, devpriv->pcibar1 + PCIDAS_CALIB_REG);
- udelay(1);
-}
-
-static int cb_pcidas_dac08_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- if (s->readback[chan] != val) {
- cb_pcidas_dac08_write(dev, val);
- s->readback[chan] = val;
- }
- }
-
- return insn->n;
-}
-
-static void cb_pcidas_trimpot_write(struct comedi_device *dev,
- unsigned int chan, unsigned int val)
-{
- const struct cb_pcidas_board *board = dev->board_ptr;
-
- if (board->has_ad8402) {
- /* write 10-bit channel/value to AD8402 trimpot */
- cb_pcidas_calib_write(dev, (chan << 8) | val, 10, true);
- } else {
- /* write 7-bit value to AD7376 trimpot */
- cb_pcidas_calib_write(dev, val, 7, true);
- }
-}
-
-static int cb_pcidas_trimpot_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- if (s->readback[chan] != val) {
- cb_pcidas_trimpot_write(dev, chan, val);
- s->readback[chan] = val;
- }
- }
-
- return insn->n;
-}
-
-static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- if (chan != (chan0 + i) % s->n_chan) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- return -EINVAL;
- }
-
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must all have the same gain\n");
- return -EINVAL;
- }
- }
- return 0;
-}
-
-static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct cb_pcidas_board *board = dev->board_ptr;
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
- err |= -EINVAL;
- if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
- err |= -EINVAL;
- if (cmd->start_src == TRIG_EXT &&
- (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
- if ((cmd->start_arg
- & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
- cmd->start_arg &= ~(CR_FLAGS_MASK &
- ~(CR_EDGE | CR_INVERT));
- err |= -EINVAL;
- }
- if (!board->is_1602 && (cmd->start_arg & CR_INVERT)) {
- cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
- err |= -EINVAL;
- }
- break;
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- board->ai_speed *
- cmd->chanlist_len);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int cb_pcidas_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct cb_pcidas_board *board = dev->board_ptr;
- struct cb_pcidas_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- unsigned int bits;
- unsigned long flags;
-
- /* make sure PCIDAS_CALIB_EN is disabled */
- outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG);
- /* initialize before settings pacer source and count values */
- outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG);
- /* clear fifo */
- outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
-
- /* set mux limits, gain and pacer source */
- bits = PCIDAS_AI_FIRST(CR_CHAN(cmd->chanlist[0])) |
- PCIDAS_AI_LAST(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
- PCIDAS_AI_GAIN(range0);
- /* set unipolar/bipolar */
- if (comedi_range_is_unipolar(s, range0))
- bits |= PCIDAS_AI_UNIP;
- /* set singleended/differential */
- if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
- bits |= PCIDAS_AI_SE;
- /* set pacer source */
- if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
- bits |= PCIDAS_AI_PACER_EXTP;
- else
- bits |= PCIDAS_AI_PACER_INT;
- outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG);
-
- /* load counters */
- if (cmd->scan_begin_src == TRIG_TIMER ||
- cmd->convert_src == TRIG_TIMER) {
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- }
-
- /* enable interrupts */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->ctrl |= PCIDAS_CTRL_INTE;
- devpriv->ctrl &= ~PCIDAS_CTRL_INT_MASK;
- if (cmd->flags & CMDF_WAKE_EOS) {
- if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
- /* interrupt end of burst */
- devpriv->ctrl |= PCIDAS_CTRL_INT_EOS;
- } else {
- /* interrupt fifo not empty */
- devpriv->ctrl |= PCIDAS_CTRL_INT_FNE;
- }
- } else {
- /* interrupt fifo half full */
- devpriv->ctrl |= PCIDAS_CTRL_INT_FHF;
- }
-
- /* enable (and clear) interrupts */
- outw(devpriv->ctrl |
- PCIDAS_CTRL_EOAI | PCIDAS_CTRL_INT_CLR | PCIDAS_CTRL_LADFUL,
- devpriv->pcibar1 + PCIDAS_CTRL_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* set start trigger and burst mode */
- bits = 0;
- if (cmd->start_src == TRIG_NOW) {
- bits |= PCIDAS_TRIG_SEL_SW;
- } else { /* TRIG_EXT */
- bits |= PCIDAS_TRIG_SEL_EXT | PCIDAS_TRIG_EN | PCIDAS_TRIG_CLR;
- if (board->is_1602) {
- if (cmd->start_arg & CR_INVERT)
- bits |= PCIDAS_TRIG_POL;
- if (cmd->start_arg & CR_EDGE)
- bits |= PCIDAS_TRIG_MODE;
- }
- }
- if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
- bits |= PCIDAS_TRIG_BURSTE;
- outw(bits, devpriv->pcibar1 + PCIDAS_TRIG_REG);
-
- return 0;
-}
-
-static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
-
- if (cmd->chanlist_len > 1) {
- unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
-
- if (chan0 != 0 || chan1 != 1) {
- dev_dbg(dev->class_dev,
- "channels must be ordered channel 0, channel 1 in chanlist\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct cb_pcidas_board *board = dev->board_ptr;
- struct cb_pcidas_private *devpriv = dev->private;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- board->ao_scan_speed);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- unsigned int arg = cmd->scan_begin_arg;
-
- comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer,
- &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int cb_pcidas_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- /* disable interrupts */
- devpriv->ctrl &= ~(PCIDAS_CTRL_INTE | PCIDAS_CTRL_EOAIE);
- outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* disable start trigger source and burst mode */
- outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG);
- outw(PCIDAS_AI_PACER_SW, devpriv->pcibar1 + PCIDAS_AI_REG);
-
- return 0;
-}
-
-static void cb_pcidas_ao_load_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int nsamples)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int nbytes;
-
- nsamples = comedi_nsamples_left(s, nsamples);
- nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples);
-
- nsamples = comedi_bytes_to_samples(s, nbytes);
- outsw(devpriv->pcibar4 + PCIDAS_AO_FIFO_REG,
- devpriv->ao_buffer, nsamples);
-}
-
-static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- const struct cb_pcidas_board *board = dev->board_ptr;
- struct cb_pcidas_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned long flags;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- cb_pcidas_ao_load_fifo(dev, s, board->fifo_size);
-
- /* enable dac half-full and empty interrupts */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->ctrl |= PCIDAS_CTRL_DAEMIE | PCIDAS_CTRL_DAHFIE;
-
- /* enable and clear interrupts */
- outw(devpriv->ctrl | PCIDAS_CTRL_DAEMI | PCIDAS_CTRL_DAHFI,
- devpriv->pcibar1 + PCIDAS_CTRL_REG);
-
- /* start dac */
- devpriv->ao_ctrl |= PCIDAS_AO_START | PCIDAS_AO_DACEN | PCIDAS_AO_EMPTY;
- outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- async->inttrig = NULL;
-
- return 0;
-}
-
-static int cb_pcidas_ao_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int i;
- unsigned long flags;
-
- /* set channel limits, gain */
- spin_lock_irqsave(&dev->spinlock, flags);
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- /* enable channel */
- devpriv->ao_ctrl |= PCIDAS_AO_CHAN_EN(chan);
- /* set range */
- devpriv->ao_ctrl |= PCIDAS_AO_RANGE(chan, range);
- }
-
- /* disable analog out before settings pacer source and count values */
- outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* clear fifo */
- outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
-
- /* load counters */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- comedi_8254_update_divisors(devpriv->ao_pacer);
- comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true);
- }
-
- /* set pacer source */
- spin_lock_irqsave(&dev->spinlock, flags);
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- devpriv->ao_ctrl |= PCIDAS_AO_PACER_INT;
- break;
- case TRIG_EXT:
- devpriv->ao_ctrl |= PCIDAS_AO_PACER_EXTP;
- break;
- default:
- spin_unlock_irqrestore(&dev->spinlock, flags);
- dev_err(dev->class_dev, "error setting dac pacer source\n");
- return -1;
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- async->inttrig = cb_pcidas_ao_inttrig;
-
- return 0;
-}
-
-static int cb_pcidas_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- /* disable interrupts */
- devpriv->ctrl &= ~(PCIDAS_CTRL_DAHFIE | PCIDAS_CTRL_DAEMIE);
- outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
-
- /* disable output */
- devpriv->ao_ctrl &= ~(PCIDAS_AO_DACEN | PCIDAS_AO_PACER_MASK);
- outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return 0;
-}
-
-static unsigned int cb_pcidas_ao_interrupt(struct comedi_device *dev,
- unsigned int status)
-{
- const struct cb_pcidas_board *board = dev->board_ptr;
- struct cb_pcidas_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int irq_clr = 0;
-
- if (status & PCIDAS_CTRL_DAEMI) {
- irq_clr |= PCIDAS_CTRL_DAEMI;
-
- if (inw(devpriv->pcibar4 + PCIDAS_AO_REG) & PCIDAS_AO_EMPTY) {
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- } else {
- dev_err(dev->class_dev, "dac fifo underflow\n");
- async->events |= COMEDI_CB_ERROR;
- }
- }
- } else if (status & PCIDAS_CTRL_DAHFI) {
- irq_clr |= PCIDAS_CTRL_DAHFI;
-
- cb_pcidas_ao_load_fifo(dev, s, board->fifo_size / 2);
- }
-
- comedi_handle_events(dev, s);
-
- return irq_clr;
-}
-
-static unsigned int cb_pcidas_ai_interrupt(struct comedi_device *dev,
- unsigned int status)
-{
- const struct cb_pcidas_board *board = dev->board_ptr;
- struct cb_pcidas_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int irq_clr = 0;
-
- if (status & PCIDAS_CTRL_ADHFI) {
- unsigned int num_samples;
-
- irq_clr |= PCIDAS_CTRL_INT_CLR;
-
- /* FIFO is half-full - read data */
- num_samples = comedi_nsamples_left(s, board->fifo_size / 2);
- insw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG,
- devpriv->ai_buffer, num_samples);
- comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples);
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
- } else if (status & (PCIDAS_CTRL_ADNEI | PCIDAS_CTRL_EOBI)) {
- unsigned int i;
-
- irq_clr |= PCIDAS_CTRL_INT_CLR;
-
- /* FIFO is not empty - read data until empty or timeoout */
- for (i = 0; i < 10000; i++) {
- unsigned short val;
-
- /* break if fifo is empty */
- if ((inw(devpriv->pcibar1 + PCIDAS_CTRL_REG) &
- PCIDAS_CTRL_ADNE) == 0)
- break;
- val = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
- comedi_buf_write_samples(s, &val, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- break;
- }
- }
- } else if (status & PCIDAS_CTRL_EOAI) {
- irq_clr |= PCIDAS_CTRL_EOAI;
-
- dev_err(dev->class_dev,
- "bug! encountered end of acquisition interrupt?\n");
- }
-
- /* check for fifo overflow */
- if (status & PCIDAS_CTRL_LADFUL) {
- irq_clr |= PCIDAS_CTRL_LADFUL;
-
- dev_err(dev->class_dev, "fifo overflow\n");
- async->events |= COMEDI_CB_ERROR;
- }
-
- comedi_handle_events(dev, s);
-
- return irq_clr;
-}
-
-static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct cb_pcidas_private *devpriv = dev->private;
- unsigned int irq_clr = 0;
- unsigned int amcc_status;
- unsigned int status;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- amcc_status = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- if ((INTCSR_INTR_ASSERTED & amcc_status) == 0)
- return IRQ_NONE;
-
- /* make sure mailbox 4 is empty */
- inl_p(devpriv->amcc + AMCC_OP_REG_IMB4);
- /* clear interrupt on amcc s5933 */
- outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS,
- devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- status = inw(devpriv->pcibar1 + PCIDAS_CTRL_REG);
-
- /* handle analog output interrupts */
- if (status & PCIDAS_CTRL_AO_INT)
- irq_clr |= cb_pcidas_ao_interrupt(dev, status);
-
- /* handle analog input interrupts */
- if (status & PCIDAS_CTRL_AI_INT)
- irq_clr |= cb_pcidas_ai_interrupt(dev, status);
-
- if (irq_clr) {
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- outw(devpriv->ctrl | irq_clr,
- devpriv->pcibar1 + PCIDAS_CTRL_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
- }
-
- return IRQ_HANDLED;
-}
-
-static int cb_pcidas_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct cb_pcidas_board *board = NULL;
- struct cb_pcidas_private *devpriv;
- struct comedi_subdevice *s;
- int i;
- int ret;
-
- if (context < ARRAY_SIZE(cb_pcidas_boards))
- board = &cb_pcidas_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv->amcc = pci_resource_start(pcidev, 0);
- devpriv->pcibar1 = pci_resource_start(pcidev, 1);
- devpriv->pcibar2 = pci_resource_start(pcidev, 2);
- dev->iobase = pci_resource_start(pcidev, 3);
- if (board->has_ao)
- devpriv->pcibar4 = pci_resource_start(pcidev, 4);
-
- /* disable and clear interrupts on amcc s5933 */
- outl(INTCSR_INBOX_INTR_STATUS,
- devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
- "cb_pcidas", dev);
- if (ret) {
- dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
- pcidev->irq);
- return ret;
- }
- dev->irq = pcidev->irq;
-
- dev->pacer = comedi_8254_init(dev->iobase + PCIDAS_AI_8254_BASE,
- I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- devpriv->ao_pacer = comedi_8254_init(dev->iobase + PCIDAS_AO_8254_BASE,
- I8254_OSC_BASE_10MHZ,
- I8254_IO8, 0);
- if (!devpriv->ao_pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 7);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
- s->range_table = board->use_alt_range ? &cb_pcidas_alt_ranges
- : &cb_pcidas_ranges;
- s->insn_read = cb_pcidas_ai_insn_read;
- s->insn_config = cb_pcidas_ai_insn_config;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmd = cb_pcidas_ai_cmd;
- s->do_cmdtest = cb_pcidas_ai_cmdtest;
- s->cancel = cb_pcidas_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = 2;
- s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
- s->range_table = &cb_pcidas_ao_ranges;
- s->insn_write = (board->has_ao_fifo)
- ? cb_pcidas_ao_fifo_insn_write
- : cb_pcidas_ao_nofifo_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- if (dev->irq && board->has_ao_fifo) {
- dev->write_subdev = s;
- s->subdev_flags |= SDF_CMD_WRITE;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = cb_pcidas_ao_cmdtest;
- s->do_cmd = cb_pcidas_ao_cmd;
- s->cancel = cb_pcidas_ao_cancel;
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* 8255 */
- s = &dev->subdevices[2];
- ret = subdev_8255_init(dev, s, NULL, PCIDAS_8255_BASE);
- if (ret)
- return ret;
-
- /* Memory subdevice - serial EEPROM */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->n_chan = 256;
- s->maxdata = 0xff;
- s->insn_read = cb_pcidas_eeprom_insn_read;
-
- /* Calibration subdevice - 8800 caldac */
- s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 8;
- s->maxdata = 0xff;
- s->insn_write = cb_pcidas_caldac_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++) {
- unsigned int val = s->maxdata / 2;
-
- /* write 11-bit channel/value to caldac */
- cb_pcidas_calib_write(dev, (i << 8) | val, 11, false);
- s->readback[i] = val;
- }
-
- /* Calibration subdevice - trim potentiometer */
- s = &dev->subdevices[5];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
- if (board->has_ad8402) {
- /*
- * pci-das1602/16 have an AD8402 trimpot:
- * chan 0 : adc gain
- * chan 1 : adc postgain offset
- */
- s->n_chan = 2;
- s->maxdata = 0xff;
- } else {
- /* all other boards have an AD7376 trimpot */
- s->n_chan = 1;
- s->maxdata = 0x7f;
- }
- s->insn_write = cb_pcidas_trimpot_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++) {
- cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
- s->readback[i] = s->maxdata / 2;
- }
-
- /* Calibration subdevice - pci-das1602/16 pregain offset (dac08) */
- s = &dev->subdevices[6];
- if (board->has_dac08) {
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 1;
- s->maxdata = 0xff;
- s->insn_write = cb_pcidas_dac08_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++) {
- cb_pcidas_dac08_write(dev, s->maxdata / 2);
- s->readback[i] = s->maxdata / 2;
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* make sure mailbox 4 is empty */
- inl(devpriv->amcc + AMCC_OP_REG_IMB4);
- /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
- devpriv->amcc_intcsr = INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
- INTCSR_INBOX_FULL_INT;
- /* clear and enable interrupt on amcc s5933 */
- outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS,
- devpriv->amcc + AMCC_OP_REG_INTCSR);
-
- return 0;
-}
-
-static void cb_pcidas_detach(struct comedi_device *dev)
-{
- struct cb_pcidas_private *devpriv = dev->private;
-
- if (devpriv) {
- if (devpriv->amcc)
- outl(INTCSR_INBOX_INTR_STATUS,
- devpriv->amcc + AMCC_OP_REG_INTCSR);
- kfree(devpriv->ao_pacer);
- }
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver cb_pcidas_driver = {
- .driver_name = "cb_pcidas",
- .module = THIS_MODULE,
- .auto_attach = cb_pcidas_auto_attach,
- .detach = cb_pcidas_detach,
-};
-
-static int cb_pcidas_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &cb_pcidas_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id cb_pcidas_pci_table[] = {
- { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
- { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
- { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
- { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
- { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
- { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
- { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
- { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
-
-static struct pci_driver cb_pcidas_pci_driver = {
- .name = "cb_pcidas",
- .id_table = cb_pcidas_pci_table,
- .probe = cb_pcidas_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for MeasurementComputing PCI-DAS series");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
deleted file mode 100644
index 41a8fea7f48a..000000000000
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ /dev/null
@@ -1,4119 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/cb_pcidas64.c
- * This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
- * 64xx, 60xx, and 4020 cards.
- *
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Copyright (C) 2001, 2002 Frank Mori Hess
- *
- * Thanks also go to the following people:
- *
- * Steve Rosenbluth, for providing the source code for
- * his pci-das6402 driver, and source code for working QNX pci-6402
- * drivers by Greg Laird and Mariusz Bogacz. None of the code was
- * used directly here, but it was useful as an additional source of
- * documentation on how to program the boards.
- *
- * John Sims, for much testing and feedback on pcidas-4020 support.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: cb_pcidas64
- * Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series
- * with the PLX 9080 PCI controller
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Status: works
- * Updated: Fri, 02 Nov 2012 18:58:55 +0000
- * Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
- * PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
- * PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
- * PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
- * PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
- * PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
- * PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
- * PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
- * PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
- *
- * Configuration options:
- * None.
- *
- * Manual attachment of PCI cards with the comedi_config utility is not
- * supported by this driver; they are attached automatically.
- *
- * These boards may be autocalibrated with the comedi_calibrate utility.
- *
- * To select the bnc trigger input on the 4020 (instead of the dio input),
- * specify a nonzero channel in the chanspec. If you wish to use an external
- * master clock on the 4020, you may do so by setting the scan_begin_src
- * to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
- * to configure the divisor to use for the external clock.
- *
- * Some devices are not identified because the PCI device IDs are not yet
- * known. If you have such a board, please let the maintainers know.
- */
-
-/*
- * TODO:
- * make it return error if user attempts an ai command that uses the
- * external queue, and an ao command simultaneously user counter subdevice
- * there are a number of boards this driver will support when they are
- * fully released, but does not yet since the pci device id numbers
- * are not yet available.
- *
- * support prescaled 100khz clock for slow pacing (not available on 6000
- * series?)
- *
- * make ao fifo size adjustable like ai fifo
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "8255.h"
-#include "plx9080.h"
-
-#define TIMER_BASE 25 /* 40MHz master clock */
-/*
- * 100kHz 'prescaled' clock for slow acquisition,
- * maybe I'll support this someday
- */
-#define PRESCALED_TIMER_BASE 10000
-#define DMA_BUFFER_SIZE 0x1000
-#define DAC_FIFO_SIZE 0x2000
-
-/* maximum value that can be loaded into board's 24-bit counters */
-static const int max_counter_value = 0xffffff;
-
-/* PCI-DAS64xxx base addresses */
-
-/* devpriv->main_iobase registers */
-enum write_only_registers {
- INTR_ENABLE_REG = 0x0, /* interrupt enable register */
- HW_CONFIG_REG = 0x2, /* hardware config register */
- DAQ_SYNC_REG = 0xc,
- DAQ_ATRIG_LOW_4020_REG = 0xc,
- ADC_CONTROL0_REG = 0x10, /* adc control register 0 */
- ADC_CONTROL1_REG = 0x12, /* adc control register 1 */
- CALIBRATION_REG = 0x14,
- /* lower 16 bits of adc sample interval counter */
- ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16,
- /* upper 8 bits of adc sample interval counter */
- ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18,
- /* lower 16 bits of delay interval counter */
- ADC_DELAY_INTERVAL_LOWER_REG = 0x1a,
- /* upper 8 bits of delay interval counter */
- ADC_DELAY_INTERVAL_UPPER_REG = 0x1c,
- /* lower 16 bits of hardware conversion/scan counter */
- ADC_COUNT_LOWER_REG = 0x1e,
- /* upper 8 bits of hardware conversion/scan counter */
- ADC_COUNT_UPPER_REG = 0x20,
- ADC_START_REG = 0x22, /* software trigger to start acquisition */
- ADC_CONVERT_REG = 0x24, /* initiates single conversion */
- ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */
- ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */
- ADC_BUFFER_CLEAR_REG = 0x2a,
- /* high channel for internal queue, use adc_chan_bits() inline above */
- ADC_QUEUE_HIGH_REG = 0x2c,
- DAC_CONTROL0_REG = 0x50, /* dac control register 0 */
- DAC_CONTROL1_REG = 0x52, /* dac control register 0 */
- /* lower 16 bits of dac sample interval counter */
- DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54,
- /* upper 8 bits of dac sample interval counter */
- DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56,
- DAC_SELECT_REG = 0x60,
- DAC_START_REG = 0x64,
- DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */
-};
-
-static inline unsigned int dac_convert_reg(unsigned int channel)
-{
- return 0x70 + (2 * (channel & 0x1));
-}
-
-static inline unsigned int dac_lsb_4020_reg(unsigned int channel)
-{
- return 0x70 + (4 * (channel & 0x1));
-}
-
-static inline unsigned int dac_msb_4020_reg(unsigned int channel)
-{
- return 0x72 + (4 * (channel & 0x1));
-}
-
-enum read_only_registers {
- /*
- * hardware status register,
- * reading this apparently clears pending interrupts as well
- */
- HW_STATUS_REG = 0x0,
- PIPE1_READ_REG = 0x4,
- ADC_READ_PNTR_REG = 0x8,
- LOWER_XFER_REG = 0x10,
- ADC_WRITE_PNTR_REG = 0xc,
- PREPOST_REG = 0x14,
-};
-
-enum read_write_registers {
- I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */
- /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */
- ADC_QUEUE_FIFO_REG = 0x100,
- ADC_FIFO_REG = 0x200, /* adc data fifo */
- /* dac data fifo, has weird interactions with external channel queue */
- DAC_FIFO_REG = 0x300,
-};
-
-/* dev->mmio registers */
-enum dio_counter_registers {
- DIO_8255_OFFSET = 0x0,
- DO_REG = 0x20,
- DI_REG = 0x28,
- DIO_DIRECTION_60XX_REG = 0x40,
- DIO_DATA_60XX_REG = 0x48,
-};
-
-/* bit definitions for write-only registers */
-
-enum intr_enable_contents {
- ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */
- ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */
- ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */
- ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */
- ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */
- EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */
- EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */
- DAC_INTR_SRC_MASK = 0x30,
- DAC_INTR_QEMPTY_BITS = 0x0,
- DAC_INTR_HIGH_CHAN_BITS = 0x10,
- EN_DAC_INTR_SRC_BIT = 0x40, /* enable dac interrupt source */
- EN_DAC_DONE_INTR_BIT = 0x80,
- EN_ADC_ACTIVE_INTR_BIT = 0x200, /* enable adc active interrupt */
- EN_ADC_STOP_INTR_BIT = 0x400, /* enable adc stop trigger interrupt */
- EN_DAC_ACTIVE_INTR_BIT = 0x800, /* enable dac active interrupt */
- EN_DAC_UNDERRUN_BIT = 0x4000, /* enable dac underrun status bit */
- EN_ADC_OVERRUN_BIT = 0x8000, /* enable adc overrun status bit */
-};
-
-enum hw_config_contents {
- MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */
- INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */
- BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */
- EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */
- EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */
- /* use 225 nanosec strobe when loading dac instead of 50 nanosec */
- SLOW_DAC_BIT = 0x400,
- /*
- * bit with unknown function yet given as default value in pci-das64
- * manual
- */
- HW_CONFIG_DUMMY_BITS = 0x2000,
- /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */
- DMA_CH_SELECT_BIT = 0x8000,
- FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */
- DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */
- DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
-};
-
-enum daq_atrig_low_4020_contents {
- /* use trig/ext clk bnc input for analog gate signal */
- EXT_AGATE_BNC_BIT = 0x8000,
- /* use trig/ext clk bnc input for external stop trigger signal */
- EXT_STOP_TRIG_BNC_BIT = 0x4000,
- /* use trig/ext clk bnc input for external start trigger signal */
- EXT_START_TRIG_BNC_BIT = 0x2000,
-};
-
-enum adc_control0_contents {
- ADC_GATE_SRC_MASK = 0x3, /* bits that select gate */
- ADC_SOFT_GATE_BITS = 0x1, /* software gate */
- ADC_EXT_GATE_BITS = 0x2, /* external digital gate */
- ADC_ANALOG_GATE_BITS = 0x3, /* analog level gate */
- /* level-sensitive gate (for digital) */
- ADC_GATE_LEVEL_BIT = 0x4,
- ADC_GATE_POLARITY_BIT = 0x8, /* gate active low */
- ADC_START_TRIG_SOFT_BITS = 0x10,
- ADC_START_TRIG_EXT_BITS = 0x20,
- ADC_START_TRIG_ANALOG_BITS = 0x30,
- ADC_START_TRIG_MASK = 0x30,
- ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */
- /* external pacing uses falling edge */
- ADC_EXT_CONV_FALLING_BIT = 0x800,
- /* enable hardware scan counter */
- ADC_SAMPLE_COUNTER_EN_BIT = 0x1000,
- ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */
- ADC_ENABLE_BIT = 0x8000, /* master adc enable */
-};
-
-enum adc_control1_contents {
- /* should be set for boards with > 16 channels */
- ADC_QUEUE_CONFIG_BIT = 0x1,
- CONVERT_POLARITY_BIT = 0x10,
- EOC_POLARITY_BIT = 0x20,
- ADC_SW_GATE_BIT = 0x40, /* software gate of adc */
- ADC_DITHER_BIT = 0x200, /* turn on extra noise for dithering */
- RETRIGGER_BIT = 0x800,
- ADC_LO_CHANNEL_4020_MASK = 0x300,
- ADC_HI_CHANNEL_4020_MASK = 0xc00,
- TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */
- FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */
- CHANNEL_MODE_4020_MASK = 0x3000,
- ADC_MODE_MASK = 0xf000,
-};
-
-static inline u16 adc_lo_chan_4020_bits(unsigned int channel)
-{
- return (channel & 0x3) << 8;
-};
-
-static inline u16 adc_hi_chan_4020_bits(unsigned int channel)
-{
- return (channel & 0x3) << 10;
-};
-
-static inline u16 adc_mode_bits(unsigned int mode)
-{
- return (mode & 0xf) << 12;
-};
-
-enum calibration_contents {
- SELECT_8800_BIT = 0x1,
- SELECT_8402_64XX_BIT = 0x2,
- SELECT_1590_60XX_BIT = 0x2,
- CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */
- SERIAL_DATA_IN_BIT = 0x80,
- SERIAL_CLOCK_BIT = 0x100,
- CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */
- CAL_GAIN_BIT = 0x800,
-};
-
-/*
- * calibration sources for 6025 are:
- * 0 : ground
- * 1 : 10V
- * 2 : 5V
- * 3 : 0.5V
- * 4 : 0.05V
- * 5 : ground
- * 6 : dac channel 0
- * 7 : dac channel 1
- */
-
-static inline u16 adc_src_bits(unsigned int source)
-{
- return (source & 0xf) << 3;
-};
-
-static inline u16 adc_convert_chan_4020_bits(unsigned int channel)
-{
- return (channel & 0x3) << 8;
-};
-
-enum adc_queue_load_contents {
- UNIP_BIT = 0x800, /* unipolar/bipolar bit */
- ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */
- /* non-referenced single-ended (common-mode input) */
- ADC_COMMON_BIT = 0x2000,
- QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */
- QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */
-};
-
-static inline u16 adc_chan_bits(unsigned int channel)
-{
- return channel & 0x3f;
-};
-
-enum dac_control0_contents {
- DAC_ENABLE_BIT = 0x8000, /* dac controller enable bit */
- DAC_CYCLIC_STOP_BIT = 0x4000,
- DAC_WAVEFORM_MODE_BIT = 0x100,
- DAC_EXT_UPDATE_FALLING_BIT = 0x80,
- DAC_EXT_UPDATE_ENABLE_BIT = 0x40,
- WAVEFORM_TRIG_MASK = 0x30,
- WAVEFORM_TRIG_DISABLED_BITS = 0x0,
- WAVEFORM_TRIG_SOFT_BITS = 0x10,
- WAVEFORM_TRIG_EXT_BITS = 0x20,
- WAVEFORM_TRIG_ADC1_BITS = 0x30,
- WAVEFORM_TRIG_FALLING_BIT = 0x8,
- WAVEFORM_GATE_LEVEL_BIT = 0x4,
- WAVEFORM_GATE_ENABLE_BIT = 0x2,
- WAVEFORM_GATE_SELECT_BIT = 0x1,
-};
-
-enum dac_control1_contents {
- DAC_WRITE_POLARITY_BIT = 0x800, /* board-dependent setting */
- DAC1_EXT_REF_BIT = 0x200,
- DAC0_EXT_REF_BIT = 0x100,
- DAC_OUTPUT_ENABLE_BIT = 0x80, /* dac output enable bit */
- DAC_UPDATE_POLARITY_BIT = 0x40, /* board-dependent setting */
- DAC_SW_GATE_BIT = 0x20,
- DAC1_UNIPOLAR_BIT = 0x8,
- DAC0_UNIPOLAR_BIT = 0x2,
-};
-
-/* bit definitions for read-only registers */
-enum hw_status_contents {
- DAC_UNDERRUN_BIT = 0x1,
- ADC_OVERRUN_BIT = 0x2,
- DAC_ACTIVE_BIT = 0x4,
- ADC_ACTIVE_BIT = 0x8,
- DAC_INTR_PENDING_BIT = 0x10,
- ADC_INTR_PENDING_BIT = 0x20,
- DAC_DONE_BIT = 0x40,
- ADC_DONE_BIT = 0x80,
- EXT_INTR_PENDING_BIT = 0x100,
- ADC_STOP_BIT = 0x200,
-};
-
-static inline u16 pipe_full_bits(u16 hw_status_bits)
-{
- return (hw_status_bits >> 10) & 0x3;
-};
-
-static inline unsigned int dma_chain_flag_bits(u16 prepost_bits)
-{
- return (prepost_bits >> 6) & 0x3;
-}
-
-static inline unsigned int adc_upper_read_ptr_code(u16 prepost_bits)
-{
- return (prepost_bits >> 12) & 0x3;
-}
-
-static inline unsigned int adc_upper_write_ptr_code(u16 prepost_bits)
-{
- return (prepost_bits >> 14) & 0x3;
-}
-
-/* I2C addresses for 4020 */
-enum i2c_addresses {
- RANGE_CAL_I2C_ADDR = 0x20,
- CALDAC0_I2C_ADDR = 0xc,
- CALDAC1_I2C_ADDR = 0xd,
-};
-
-enum range_cal_i2c_contents {
- /* bits that set what source the adc converter measures */
- ADC_SRC_4020_MASK = 0x70,
- /* make bnc trig/ext clock threshold 0V instead of 2.5V */
- BNC_TRIG_THRESHOLD_0V_BIT = 0x80,
-};
-
-static inline u8 adc_src_4020_bits(unsigned int source)
-{
- return (source << 4) & ADC_SRC_4020_MASK;
-};
-
-static inline u8 attenuate_bit(unsigned int channel)
-{
- /* attenuate channel (+-5V input range) */
- return 1 << (channel & 0x3);
-};
-
-/* analog input ranges for 64xx boards */
-static const struct comedi_lrange ai_ranges_64xx = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const u8 ai_range_code_64xx[8] = {
- 0x0, 0x1, 0x2, 0x3, /* bipolar 10, 5, 2,5, 1.25 */
- 0x8, 0x9, 0xa, 0xb /* unipolar 10, 5, 2.5, 1.25 */
-};
-
-/* analog input ranges for 64-Mx boards */
-static const struct comedi_lrange ai_ranges_64_mx = {
- 7, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const u8 ai_range_code_64_mx[7] = {
- 0x0, 0x1, 0x2, 0x3, /* bipolar 5, 2.5, 1.25, 0.625 */
- 0x9, 0xa, 0xb /* unipolar 5, 2.5, 1.25 */
-};
-
-/* analog input ranges for 60xx boards */
-static const struct comedi_lrange ai_ranges_60xx = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05)
- }
-};
-
-static const u8 ai_range_code_60xx[4] = {
- 0x0, 0x1, 0x4, 0x7 /* bipolar 10, 5, 0.5, 0.05 */
-};
-
-/* analog input ranges for 6030, etc boards */
-static const struct comedi_lrange ai_ranges_6030 = {
- 14, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.2),
- BIP_RANGE(0.1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5),
- UNI_RANGE(0.2),
- UNI_RANGE(0.1)
- }
-};
-
-static const u8 ai_range_code_6030[14] = {
- 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */
- 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */
-};
-
-/* analog input ranges for 6052, etc boards */
-static const struct comedi_lrange ai_ranges_6052 = {
- 15, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.25),
- BIP_RANGE(0.1),
- BIP_RANGE(0.05),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5),
- UNI_RANGE(0.2),
- UNI_RANGE(0.1)
- }
-};
-
-static const u8 ai_range_code_6052[15] = {
- 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */
- 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* unipolar 10 ... 0.1 */
-};
-
-/* analog input ranges for 4020 board */
-static const struct comedi_lrange ai_ranges_4020 = {
- 2, {
- BIP_RANGE(5),
- BIP_RANGE(1)
- }
-};
-
-/* analog output ranges */
-static const struct comedi_lrange ao_ranges_64xx = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-static const int ao_range_code_64xx[] = {
- 0x0,
- 0x1,
- 0x2,
- 0x3,
-};
-
-static const int ao_range_code_60xx[] = {
- 0x0,
-};
-
-static const struct comedi_lrange ao_ranges_6030 = {
- 2, {
- BIP_RANGE(10),
- UNI_RANGE(10)
- }
-};
-
-static const int ao_range_code_6030[] = {
- 0x0,
- 0x2,
-};
-
-static const struct comedi_lrange ao_ranges_4020 = {
- 2, {
- BIP_RANGE(5),
- BIP_RANGE(10)
- }
-};
-
-static const int ao_range_code_4020[] = {
- 0x1,
- 0x0,
-};
-
-enum register_layout {
- LAYOUT_60XX,
- LAYOUT_64XX,
- LAYOUT_4020,
-};
-
-struct hw_fifo_info {
- unsigned int num_segments;
- unsigned int max_segment_length;
- unsigned int sample_packing_ratio;
- u16 fifo_size_reg_mask;
-};
-
-enum pcidas64_boardid {
- BOARD_PCIDAS6402_16,
- BOARD_PCIDAS6402_12,
- BOARD_PCIDAS64_M1_16,
- BOARD_PCIDAS64_M2_16,
- BOARD_PCIDAS64_M3_16,
- BOARD_PCIDAS6013,
- BOARD_PCIDAS6014,
- BOARD_PCIDAS6023,
- BOARD_PCIDAS6025,
- BOARD_PCIDAS6030,
- BOARD_PCIDAS6031,
- BOARD_PCIDAS6032,
- BOARD_PCIDAS6033,
- BOARD_PCIDAS6034,
- BOARD_PCIDAS6035,
- BOARD_PCIDAS6036,
- BOARD_PCIDAS6040,
- BOARD_PCIDAS6052,
- BOARD_PCIDAS6070,
- BOARD_PCIDAS6071,
- BOARD_PCIDAS4020_12,
- BOARD_PCIDAS6402_16_JR,
- BOARD_PCIDAS64_M1_16_JR,
- BOARD_PCIDAS64_M2_16_JR,
- BOARD_PCIDAS64_M3_16_JR,
- BOARD_PCIDAS64_M1_14,
- BOARD_PCIDAS64_M2_14,
- BOARD_PCIDAS64_M3_14,
-};
-
-struct pcidas64_board {
- const char *name;
- int ai_se_chans; /* number of ai inputs in single-ended mode */
- int ai_bits; /* analog input resolution */
- int ai_speed; /* fastest conversion period in ns */
- const struct comedi_lrange *ai_range_table;
- const u8 *ai_range_code;
- int ao_nchan; /* number of analog out channels */
- int ao_bits; /* analog output resolution */
- int ao_scan_speed; /* analog output scan speed */
- const struct comedi_lrange *ao_range_table;
- const int *ao_range_code;
- const struct hw_fifo_info *const ai_fifo;
- /* different board families have slightly different registers */
- enum register_layout layout;
- unsigned has_8255:1;
-};
-
-static const struct hw_fifo_info ai_fifo_4020 = {
- .num_segments = 2,
- .max_segment_length = 0x8000,
- .sample_packing_ratio = 2,
- .fifo_size_reg_mask = 0x7f,
-};
-
-static const struct hw_fifo_info ai_fifo_64xx = {
- .num_segments = 4,
- .max_segment_length = 0x800,
- .sample_packing_ratio = 1,
- .fifo_size_reg_mask = 0x3f,
-};
-
-static const struct hw_fifo_info ai_fifo_60xx = {
- .num_segments = 4,
- .max_segment_length = 0x800,
- .sample_packing_ratio = 1,
- .fifo_size_reg_mask = 0x7f,
-};
-
-/*
- * maximum number of dma transfers we will chain together into a ring
- * (and the maximum number of dma buffers we maintain)
- */
-#define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE)
-#define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
-#define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
-static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board)
-{
- if (board->layout == LAYOUT_4020)
- return MAX_AI_DMA_RING_COUNT;
-
- return MIN_AI_DMA_RING_COUNT;
-}
-
-static const int bytes_in_sample = 2;
-
-static const struct pcidas64_board pcidas64_boards[] = {
- [BOARD_PCIDAS6402_16] = {
- .name = "pci-das6402/16",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_range_code = ai_range_code_64xx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS6402_12] = {
- .name = "pci-das6402/12", /* XXX check */
- .ai_se_chans = 64,
- .ai_bits = 12,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_range_code = ai_range_code_64xx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M1_16] = {
- .name = "pci-das64/m1/16",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 1000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M2_16] = {
- .name = "pci-das64/m2/16",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 500,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M3_16] = {
- .name = "pci-das64/m3/16",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 333,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS6013] = {
- .name = "pci-das6013",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_bits = 16,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_range_code = ai_range_code_60xx,
- .ao_range_table = &range_bipolar10,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6014] = {
- .name = "pci-das6014",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_range_code = ai_range_code_60xx,
- .ao_range_table = &range_bipolar10,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6023] = {
- .name = "pci-das6023",
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_range_code = ai_range_code_60xx,
- .ao_range_table = &range_bipolar10,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS6025] = {
- .name = "pci-das6025",
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_range_code = ai_range_code_60xx,
- .ao_range_table = &range_bipolar10,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS6030] = {
- .name = "pci-das6030",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ai_range_code = ai_range_code_6030,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6031] = {
- .name = "pci-das6031",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ai_range_code = ai_range_code_6030,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6032] = {
- .name = "pci-das6032",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 0,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ai_range_code = ai_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6033] = {
- .name = "pci-das6033",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 0,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ai_range_code = ai_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6034] = {
- .name = "pci-das6034",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_scan_speed = 0,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_range_code = ai_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6035] = {
- .name = "pci-das6035",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_range_code = ai_range_code_60xx,
- .ao_range_table = &range_bipolar10,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6036] = {
- .name = "pci-das6036",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_range_code = ai_range_code_60xx,
- .ao_range_table = &range_bipolar10,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6040] = {
- .name = "pci-das6040",
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 2000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 1000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ai_range_code = ai_range_code_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6052] = {
- .name = "pci-das6052",
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 3333,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 3333,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ai_range_code = ai_range_code_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6070] = {
- .name = "pci-das6070",
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 800,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 1000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ai_range_code = ai_range_code_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS6071] = {
- .name = "pci-das6071",
- .ai_se_chans = 64,
- .ai_bits = 12,
- .ai_speed = 800,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 1000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ai_range_code = ai_range_code_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- [BOARD_PCIDAS4020_12] = {
- .name = "pci-das4020/12",
- .ai_se_chans = 4,
- .ai_bits = 12,
- .ai_speed = 50,
- .ao_bits = 12,
- .ao_nchan = 2,
- .ao_scan_speed = 0, /* no hardware pacing on ao */
- .layout = LAYOUT_4020,
- .ai_range_table = &ai_ranges_4020,
- .ao_range_table = &ao_ranges_4020,
- .ao_range_code = ao_range_code_4020,
- .ai_fifo = &ai_fifo_4020,
- .has_8255 = 1,
- },
-#if 0
- /* The device id for these boards is unknown */
-
- [BOARD_PCIDAS6402_16_JR] = {
- .name = "pci-das6402/16/jr",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_range_code = ai_range_code_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M1_16_JR] = {
- .name = "pci-das64/m1/16/jr",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 1000,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M2_16_JR] = {
- .name = "pci-das64/m2/16/jr",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 500,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M3_16_JR] = {
- .name = "pci-das64/m3/16/jr",
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 333,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M1_14] = {
- .name = "pci-das64/m1/14",
- .ai_se_chans = 64,
- .ai_bits = 14,
- .ai_speed = 1000,
- .ao_nchan = 2,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M2_14] = {
- .name = "pci-das64/m2/14",
- .ai_se_chans = 64,
- .ai_bits = 14,
- .ai_speed = 500,
- .ao_nchan = 2,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- [BOARD_PCIDAS64_M3_14] = {
- .name = "pci-das64/m3/14",
- .ai_se_chans = 64,
- .ai_bits = 14,
- .ai_speed = 333,
- .ao_nchan = 2,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64_mx,
- .ai_range_code = ai_range_code_64_mx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
-#endif
-};
-
-static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
- int use_differential)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- if ((board->layout == LAYOUT_64XX && !use_differential) ||
- (board->layout == LAYOUT_60XX && use_differential))
- return ADC_SE_DIFF_BIT;
-
- return 0;
-}
-
-struct ext_clock_info {
- /* master clock divisor to use for scans with external master clock */
- unsigned int divisor;
- /* chanspec for master clock input when used as scan begin src */
- unsigned int chanspec;
-};
-
-/* this structure is for data unique to this hardware driver. */
-struct pcidas64_private {
- /* base addresses (physical) */
- resource_size_t main_phys_iobase;
- resource_size_t dio_counter_phys_iobase;
- /* base addresses (ioremapped) */
- void __iomem *plx9080_iobase;
- void __iomem *main_iobase;
- /* local address (used by dma controller) */
- u32 local0_iobase;
- u32 local1_iobase;
- /* dma buffers for analog input */
- u16 *ai_buffer[MAX_AI_DMA_RING_COUNT];
- /* physical addresses of ai dma buffers */
- dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT];
- /*
- * array of ai dma descriptors read by plx9080,
- * allocated to get proper alignment
- */
- struct plx_dma_desc *ai_dma_desc;
- /* physical address of ai dma descriptor array */
- dma_addr_t ai_dma_desc_bus_addr;
- /*
- * index of the ai dma descriptor/buffer
- * that is currently being used
- */
- unsigned int ai_dma_index;
- /* dma buffers for analog output */
- u16 *ao_buffer[AO_DMA_RING_COUNT];
- /* physical addresses of ao dma buffers */
- dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT];
- struct plx_dma_desc *ao_dma_desc;
- dma_addr_t ao_dma_desc_bus_addr;
- /* keeps track of buffer where the next ao sample should go */
- unsigned int ao_dma_index;
- unsigned int hw_revision; /* stc chip hardware revision number */
- /* last bits sent to INTR_ENABLE_REG register */
- unsigned int intr_enable_bits;
- /* last bits sent to ADC_CONTROL1_REG register */
- u16 adc_control1_bits;
- /* last bits sent to FIFO_SIZE_REG register */
- u16 fifo_size_bits;
- /* last bits sent to HW_CONFIG_REG register */
- u16 hw_config_bits;
- u16 dac_control1_bits;
- /* last bits written to plx9080 control register */
- u32 plx_control_bits;
- /* last bits written to plx interrupt control and status register */
- u32 plx_intcsr_bits;
- /* index of calibration source readable through ai ch0 */
- int calibration_source;
- /* bits written to i2c calibration/range register */
- u8 i2c_cal_range_bits;
- /* configure digital triggers to trigger on falling edge */
- unsigned int ext_trig_falling;
- short ai_cmd_running;
- unsigned int ai_fifo_segment_length;
- struct ext_clock_info ext_clock;
- unsigned short ao_bounce_buffer[DAC_FIFO_SIZE];
-};
-
-static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
- unsigned int range_index)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- return board->ai_range_code[range_index] << 8;
-}
-
-static unsigned int hw_revision(const struct comedi_device *dev,
- u16 hw_status_bits)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- if (board->layout == LAYOUT_4020)
- return (hw_status_bits >> 13) & 0x7;
-
- return (hw_status_bits >> 12) & 0xf;
-}
-
-static void set_dac_range_bits(struct comedi_device *dev,
- u16 *bits, unsigned int channel,
- unsigned int range)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- unsigned int code = board->ao_range_code[range];
-
- if (channel > 1)
- dev_err(dev->class_dev, "bug! bad channel?\n");
- if (code & ~0x3)
- dev_err(dev->class_dev, "bug! bad range code?\n");
-
- *bits &= ~(0x3 << (2 * channel));
- *bits |= code << (2 * channel);
-};
-
-static inline int ao_cmd_is_supported(const struct pcidas64_board *board)
-{
- return board->ao_nchan && board->layout != LAYOUT_4020;
-}
-
-static void abort_dma(struct comedi_device *dev, unsigned int channel)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned long flags;
-
- /* spinlock for plx dma control/status reg */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- plx9080_abort_dma(devpriv->plx9080_iobase, channel);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static void disable_plx_interrupts(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
-
- devpriv->plx_intcsr_bits = 0;
- writel(devpriv->plx_intcsr_bits,
- devpriv->plx9080_iobase + PLX_REG_INTCSR);
-}
-
-static void disable_ai_interrupts(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->intr_enable_bits &=
- ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
- ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
- ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
- writew(devpriv->intr_enable_bits,
- devpriv->main_iobase + INTR_ENABLE_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static void enable_ai_interrupts(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- u32 bits;
- unsigned long flags;
-
- bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
- EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
- /*
- * Use pio transfer and interrupt on end of conversion
- * if CMDF_WAKE_EOS flag is set.
- */
- if (cmd->flags & CMDF_WAKE_EOS) {
- /* 4020 doesn't support pio transfers except for fifo dregs */
- if (board->layout != LAYOUT_4020)
- bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
- }
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->intr_enable_bits |= bits;
- writew(devpriv->intr_enable_bits,
- devpriv->main_iobase + INTR_ENABLE_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-/* initialize plx9080 chip */
-static void init_plx9080(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- u32 bits;
- void __iomem *plx_iobase = devpriv->plx9080_iobase;
-
- devpriv->plx_control_bits =
- readl(devpriv->plx9080_iobase + PLX_REG_CNTRL);
-
-#ifdef __BIG_ENDIAN
- bits = PLX_BIGEND_DMA0 | PLX_BIGEND_DMA1;
-#else
- bits = 0;
-#endif
- writel(bits, devpriv->plx9080_iobase + PLX_REG_BIGEND);
-
- disable_plx_interrupts(dev);
-
- abort_dma(dev, 0);
- abort_dma(dev, 1);
-
- /* configure dma0 mode */
- bits = 0;
- /* enable ready input, not sure if this is necessary */
- bits |= PLX_DMAMODE_READYIEN;
- /* enable bterm, not sure if this is necessary */
- bits |= PLX_DMAMODE_BTERMIEN;
- /* enable dma chaining */
- bits |= PLX_DMAMODE_CHAINEN;
- /*
- * enable interrupt on dma done
- * (probably don't need this, since chain never finishes)
- */
- bits |= PLX_DMAMODE_DONEIEN;
- /*
- * don't increment local address during transfers
- * (we are transferring from a fixed fifo register)
- */
- bits |= PLX_DMAMODE_LACONST;
- /* route dma interrupt to pci bus */
- bits |= PLX_DMAMODE_INTRPCI;
- /* enable demand mode */
- bits |= PLX_DMAMODE_DEMAND;
- /* enable local burst mode */
- bits |= PLX_DMAMODE_BURSTEN;
- /* 4020 uses 32 bit dma */
- if (board->layout == LAYOUT_4020)
- bits |= PLX_DMAMODE_WIDTH_32;
- else /* localspace0 bus is 16 bits wide */
- bits |= PLX_DMAMODE_WIDTH_16;
- writel(bits, plx_iobase + PLX_REG_DMAMODE1);
- if (ao_cmd_is_supported(board))
- writel(bits, plx_iobase + PLX_REG_DMAMODE0);
-
- /* enable interrupts on plx 9080 */
- devpriv->plx_intcsr_bits |=
- PLX_INTCSR_LSEABORTEN | PLX_INTCSR_LSEPARITYEN | PLX_INTCSR_PIEN |
- PLX_INTCSR_PLIEN | PLX_INTCSR_PABORTIEN | PLX_INTCSR_LIOEN |
- PLX_INTCSR_DMA0IEN | PLX_INTCSR_DMA1IEN;
- writel(devpriv->plx_intcsr_bits,
- devpriv->plx9080_iobase + PLX_REG_INTCSR);
-}
-
-static void disable_ai_pacing(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned long flags;
-
- disable_ai_interrupts(dev);
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT;
- writew(devpriv->adc_control1_bits,
- devpriv->main_iobase + ADC_CONTROL1_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* disable pacing, triggering, etc */
- writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
- devpriv->main_iobase + ADC_CONTROL0_REG);
-}
-
-static int set_ai_fifo_segment_length(struct comedi_device *dev,
- unsigned int num_entries)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- static const int increment_size = 0x100;
- const struct hw_fifo_info *const fifo = board->ai_fifo;
- unsigned int num_increments;
- u16 bits;
-
- if (num_entries < increment_size)
- num_entries = increment_size;
- if (num_entries > fifo->max_segment_length)
- num_entries = fifo->max_segment_length;
-
- /* 1 == 256 entries, 2 == 512 entries, etc */
- num_increments = DIV_ROUND_CLOSEST(num_entries, increment_size);
-
- bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
- devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
- devpriv->fifo_size_bits |= bits;
- writew(devpriv->fifo_size_bits,
- devpriv->main_iobase + FIFO_SIZE_REG);
-
- devpriv->ai_fifo_segment_length = num_increments * increment_size;
-
- return devpriv->ai_fifo_segment_length;
-}
-
-/*
- * adjusts the size of hardware fifo (which determines block size for dma xfers)
- */
-static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- unsigned int num_fifo_entries;
- int retval;
- const struct hw_fifo_info *const fifo = board->ai_fifo;
-
- num_fifo_entries = num_samples / fifo->sample_packing_ratio;
-
- retval = set_ai_fifo_segment_length(dev,
- num_fifo_entries /
- fifo->num_segments);
- if (retval < 0)
- return retval;
-
- return retval * fifo->num_segments * fifo->sample_packing_ratio;
-}
-
-/* query length of fifo */
-static unsigned int ai_fifo_size(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
-
- return devpriv->ai_fifo_segment_length *
- board->ai_fifo->num_segments *
- board->ai_fifo->sample_packing_ratio;
-}
-
-static void init_stc_registers(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- u16 bits;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
-
- /*
- * bit should be set for 6025,
- * although docs say boards with <= 16 chans should be cleared XXX
- */
- if (1)
- devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
- writew(devpriv->adc_control1_bits,
- devpriv->main_iobase + ADC_CONTROL1_REG);
-
- /* 6402/16 manual says this register must be initialized to 0xff? */
- writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
-
- bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
- if (board->layout == LAYOUT_4020)
- bits |= INTERNAL_CLOCK_4020_BITS;
- devpriv->hw_config_bits |= bits;
- writew(devpriv->hw_config_bits,
- devpriv->main_iobase + HW_CONFIG_REG);
-
- writew(0, devpriv->main_iobase + DAQ_SYNC_REG);
- writew(0, devpriv->main_iobase + CALIBRATION_REG);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* set fifos to maximum size */
- devpriv->fifo_size_bits |= DAC_FIFO_BITS;
- set_ai_fifo_segment_length(dev, board->ai_fifo->max_segment_length);
-
- devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
- devpriv->intr_enable_bits =
- /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
- EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
- writew(devpriv->intr_enable_bits,
- devpriv->main_iobase + INTR_ENABLE_REG);
-
- disable_ai_pacing(dev);
-};
-
-static int alloc_and_init_dma_members(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct pcidas64_private *devpriv = dev->private;
- int i;
-
- /* allocate pci dma buffers */
- for (i = 0; i < ai_dma_ring_count(board); i++) {
- devpriv->ai_buffer[i] =
- dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
- &devpriv->ai_buffer_bus_addr[i],
- GFP_KERNEL);
- if (!devpriv->ai_buffer[i])
- return -ENOMEM;
- }
- for (i = 0; i < AO_DMA_RING_COUNT; i++) {
- if (ao_cmd_is_supported(board)) {
- devpriv->ao_buffer[i] =
- dma_alloc_coherent(&pcidev->dev,
- DMA_BUFFER_SIZE,
- &devpriv->ao_buffer_bus_addr[i],
- GFP_KERNEL);
- if (!devpriv->ao_buffer[i])
- return -ENOMEM;
- }
- }
- /* allocate dma descriptors */
- devpriv->ai_dma_desc =
- dma_alloc_coherent(&pcidev->dev, sizeof(struct plx_dma_desc) *
- ai_dma_ring_count(board),
- &devpriv->ai_dma_desc_bus_addr, GFP_KERNEL);
- if (!devpriv->ai_dma_desc)
- return -ENOMEM;
-
- if (ao_cmd_is_supported(board)) {
- devpriv->ao_dma_desc =
- dma_alloc_coherent(&pcidev->dev,
- sizeof(struct plx_dma_desc) *
- AO_DMA_RING_COUNT,
- &devpriv->ao_dma_desc_bus_addr,
- GFP_KERNEL);
- if (!devpriv->ao_dma_desc)
- return -ENOMEM;
- }
- /* initialize dma descriptors */
- for (i = 0; i < ai_dma_ring_count(board); i++) {
- devpriv->ai_dma_desc[i].pci_start_addr =
- cpu_to_le32(devpriv->ai_buffer_bus_addr[i]);
- if (board->layout == LAYOUT_4020)
- devpriv->ai_dma_desc[i].local_start_addr =
- cpu_to_le32(devpriv->local1_iobase +
- ADC_FIFO_REG);
- else
- devpriv->ai_dma_desc[i].local_start_addr =
- cpu_to_le32(devpriv->local0_iobase +
- ADC_FIFO_REG);
- devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
- devpriv->ai_dma_desc[i].next =
- cpu_to_le32((devpriv->ai_dma_desc_bus_addr +
- ((i + 1) % ai_dma_ring_count(board)) *
- sizeof(devpriv->ai_dma_desc[0])) |
- PLX_DMADPR_DESCPCI | PLX_DMADPR_TCINTR |
- PLX_DMADPR_XFERL2P);
- }
- if (ao_cmd_is_supported(board)) {
- for (i = 0; i < AO_DMA_RING_COUNT; i++) {
- devpriv->ao_dma_desc[i].pci_start_addr =
- cpu_to_le32(devpriv->ao_buffer_bus_addr[i]);
- devpriv->ao_dma_desc[i].local_start_addr =
- cpu_to_le32(devpriv->local0_iobase +
- DAC_FIFO_REG);
- devpriv->ao_dma_desc[i].transfer_size = cpu_to_le32(0);
- devpriv->ao_dma_desc[i].next =
- cpu_to_le32((devpriv->ao_dma_desc_bus_addr +
- ((i + 1) % (AO_DMA_RING_COUNT)) *
- sizeof(devpriv->ao_dma_desc[0])) |
- PLX_DMADPR_DESCPCI |
- PLX_DMADPR_TCINTR);
- }
- }
- return 0;
-}
-
-static void cb_pcidas64_free_dma(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct pcidas64_private *devpriv = dev->private;
- int i;
-
- if (!devpriv)
- return;
-
- /* free pci dma buffers */
- for (i = 0; i < ai_dma_ring_count(board); i++) {
- if (devpriv->ai_buffer[i])
- dma_free_coherent(&pcidev->dev,
- DMA_BUFFER_SIZE,
- devpriv->ai_buffer[i],
- devpriv->ai_buffer_bus_addr[i]);
- }
- for (i = 0; i < AO_DMA_RING_COUNT; i++) {
- if (devpriv->ao_buffer[i])
- dma_free_coherent(&pcidev->dev,
- DMA_BUFFER_SIZE,
- devpriv->ao_buffer[i],
- devpriv->ao_buffer_bus_addr[i]);
- }
- /* free dma descriptors */
- if (devpriv->ai_dma_desc)
- dma_free_coherent(&pcidev->dev,
- sizeof(struct plx_dma_desc) *
- ai_dma_ring_count(board),
- devpriv->ai_dma_desc,
- devpriv->ai_dma_desc_bus_addr);
- if (devpriv->ao_dma_desc)
- dma_free_coherent(&pcidev->dev,
- sizeof(struct plx_dma_desc) *
- AO_DMA_RING_COUNT,
- devpriv->ao_dma_desc,
- devpriv->ao_dma_desc_bus_addr);
-}
-
-static inline void warn_external_queue(struct comedi_device *dev)
-{
- dev_err(dev->class_dev,
- "AO command and AI external channel queue cannot be used simultaneously\n");
- dev_err(dev->class_dev,
- "Use internal AI channel queue (channels must be consecutive and use same range/aref)\n");
-}
-
-/*
- * their i2c requires a huge delay on setting clock or data high for some reason
- */
-static const int i2c_high_udelay = 1000;
-static const int i2c_low_udelay = 10;
-
-/* set i2c data line high or low */
-static void i2c_set_sda(struct comedi_device *dev, int state)
-{
- struct pcidas64_private *devpriv = dev->private;
- static const int data_bit = PLX_CNTRL_EEWB;
- void __iomem *plx_control_addr = devpriv->plx9080_iobase +
- PLX_REG_CNTRL;
-
- if (state) { /* set data line high */
- devpriv->plx_control_bits &= ~data_bit;
- writel(devpriv->plx_control_bits, plx_control_addr);
- udelay(i2c_high_udelay);
- } else { /* set data line low */
- devpriv->plx_control_bits |= data_bit;
- writel(devpriv->plx_control_bits, plx_control_addr);
- udelay(i2c_low_udelay);
- }
-}
-
-/* set i2c clock line high or low */
-static void i2c_set_scl(struct comedi_device *dev, int state)
-{
- struct pcidas64_private *devpriv = dev->private;
- static const int clock_bit = PLX_CNTRL_USERO;
- void __iomem *plx_control_addr = devpriv->plx9080_iobase +
- PLX_REG_CNTRL;
-
- if (state) { /* set clock line high */
- devpriv->plx_control_bits &= ~clock_bit;
- writel(devpriv->plx_control_bits, plx_control_addr);
- udelay(i2c_high_udelay);
- } else { /* set clock line low */
- devpriv->plx_control_bits |= clock_bit;
- writel(devpriv->plx_control_bits, plx_control_addr);
- udelay(i2c_low_udelay);
- }
-}
-
-static void i2c_write_byte(struct comedi_device *dev, u8 byte)
-{
- u8 bit;
- unsigned int num_bits = 8;
-
- for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
- i2c_set_scl(dev, 0);
- if ((byte & bit))
- i2c_set_sda(dev, 1);
- else
- i2c_set_sda(dev, 0);
- i2c_set_scl(dev, 1);
- }
-}
-
-/* we can't really read the lines, so fake it */
-static int i2c_read_ack(struct comedi_device *dev)
-{
- i2c_set_scl(dev, 0);
- i2c_set_sda(dev, 1);
- i2c_set_scl(dev, 1);
-
- return 0; /* return fake acknowledge bit */
-}
-
-/* send start bit */
-static void i2c_start(struct comedi_device *dev)
-{
- i2c_set_scl(dev, 1);
- i2c_set_sda(dev, 1);
- i2c_set_sda(dev, 0);
-}
-
-/* send stop bit */
-static void i2c_stop(struct comedi_device *dev)
-{
- i2c_set_scl(dev, 0);
- i2c_set_sda(dev, 0);
- i2c_set_scl(dev, 1);
- i2c_set_sda(dev, 1);
-}
-
-static void i2c_write(struct comedi_device *dev, unsigned int address,
- const u8 *data, unsigned int length)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int i;
- u8 bitstream;
- static const int read_bit = 0x1;
-
- /*
- * XXX need mutex to prevent simultaneous attempts to access
- * eeprom and i2c bus
- */
-
- /* make sure we don't send anything to eeprom */
- devpriv->plx_control_bits &= ~PLX_CNTRL_EECS;
-
- i2c_stop(dev);
- i2c_start(dev);
-
- /* send address and write bit */
- bitstream = (address << 1) & ~read_bit;
- i2c_write_byte(dev, bitstream);
-
- /* get acknowledge */
- if (i2c_read_ack(dev) != 0) {
- dev_err(dev->class_dev, "failed: no acknowledge\n");
- i2c_stop(dev);
- return;
- }
- /* write data bytes */
- for (i = 0; i < length; i++) {
- i2c_write_byte(dev, data[i]);
- if (i2c_read_ack(dev) != 0) {
- dev_err(dev->class_dev, "failed: no acknowledge\n");
- i2c_stop(dev);
- return;
- }
- }
- i2c_stop(dev);
-}
-
-static int cb_pcidas64_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- unsigned int status;
-
- status = readw(devpriv->main_iobase + HW_STATUS_REG);
- if (board->layout == LAYOUT_4020) {
- status = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG);
- if (status)
- return 0;
- } else {
- if (pipe_full_bits(status))
- return 0;
- }
- return -EBUSY;
-}
-
-static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- unsigned int bits = 0, n;
- unsigned int channel, range, aref;
- unsigned long flags;
- int ret;
-
- channel = CR_CHAN(insn->chanspec);
- range = CR_RANGE(insn->chanspec);
- aref = CR_AREF(insn->chanspec);
-
- /* disable card's analog input interrupt sources and pacing */
- /* 4020 generates dac done interrupts even though they are disabled */
- disable_ai_pacing(dev);
-
- spin_lock_irqsave(&dev->spinlock, flags);
- if (insn->chanspec & CR_ALT_FILTER)
- devpriv->adc_control1_bits |= ADC_DITHER_BIT;
- else
- devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
- writew(devpriv->adc_control1_bits,
- devpriv->main_iobase + ADC_CONTROL1_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- if (board->layout != LAYOUT_4020) {
- /* use internal queue */
- devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
- writew(devpriv->hw_config_bits,
- devpriv->main_iobase + HW_CONFIG_REG);
-
- /* ALT_SOURCE is internal calibration reference */
- if (insn->chanspec & CR_ALT_SOURCE) {
- unsigned int cal_en_bit;
-
- if (board->layout == LAYOUT_60XX)
- cal_en_bit = CAL_EN_60XX_BIT;
- else
- cal_en_bit = CAL_EN_64XX_BIT;
- /*
- * select internal reference source to connect
- * to channel 0
- */
- writew(cal_en_bit |
- adc_src_bits(devpriv->calibration_source),
- devpriv->main_iobase + CALIBRATION_REG);
- } else {
- /*
- * make sure internal calibration source
- * is turned off
- */
- writew(0, devpriv->main_iobase + CALIBRATION_REG);
- }
- /* load internal queue */
- bits = 0;
- /* set gain */
- bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
- /* set single-ended / differential */
- bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
- if (aref == AREF_COMMON)
- bits |= ADC_COMMON_BIT;
- bits |= adc_chan_bits(channel);
- /* set stop channel */
- writew(adc_chan_bits(channel),
- devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
- /* set start channel, and rest of settings */
- writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
- } else {
- u8 old_cal_range_bits = devpriv->i2c_cal_range_bits;
-
- devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
- if (insn->chanspec & CR_ALT_SOURCE) {
- devpriv->i2c_cal_range_bits |=
- adc_src_4020_bits(devpriv->calibration_source);
- } else { /* select BNC inputs */
- devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
- }
- /* select range */
- if (range == 0)
- devpriv->i2c_cal_range_bits |= attenuate_bit(channel);
- else
- devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel);
- /*
- * update calibration/range i2c register only if necessary,
- * as it is very slow
- */
- if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
- u8 i2c_data = devpriv->i2c_cal_range_bits;
-
- i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
- sizeof(i2c_data));
- }
-
- /*
- * 4020 manual asks that sample interval register to be set
- * before writing to convert register.
- * Using somewhat arbitrary setting of 4 master clock ticks
- * = 0.1 usec
- */
- writew(0, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
- writew(2, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
- }
-
- for (n = 0; n < insn->n; n++) {
- /* clear adc buffer (inside loop for 4020 sake) */
- writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
-
- /* trigger conversion, bits sent only matter for 4020 */
- writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
- devpriv->main_iobase + ADC_CONVERT_REG);
-
- /* wait for data */
- ret = comedi_timeout(dev, s, insn, cb_pcidas64_ai_eoc, 0);
- if (ret)
- return ret;
-
- if (board->layout == LAYOUT_4020)
- data[n] = readl(dev->mmio + ADC_FIFO_REG) & 0xffff;
- else
- data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG);
- }
-
- return n;
-}
-
-static int ai_config_calibration_source(struct comedi_device *dev,
- unsigned int *data)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- unsigned int source = data[1];
- int num_calibration_sources;
-
- if (board->layout == LAYOUT_60XX)
- num_calibration_sources = 16;
- else
- num_calibration_sources = 8;
- if (source >= num_calibration_sources) {
- dev_dbg(dev->class_dev, "invalid calibration source: %i\n",
- source);
- return -EINVAL;
- }
-
- devpriv->calibration_source = source;
-
- return 2;
-}
-
-static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- int fifo_size;
- const struct hw_fifo_info *const fifo = board->ai_fifo;
- unsigned int block_size, requested_block_size;
- int retval;
-
- requested_block_size = data[1];
-
- if (requested_block_size) {
- fifo_size = requested_block_size * fifo->num_segments /
- bytes_in_sample;
-
- retval = set_ai_fifo_size(dev, fifo_size);
- if (retval < 0)
- return retval;
- }
-
- block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample;
-
- data[1] = block_size;
-
- return 2;
-}
-
-static int ai_config_master_clock_4020(struct comedi_device *dev,
- unsigned int *data)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int divisor = data[4];
- int retval = 0;
-
- if (divisor < 2) {
- divisor = 2;
- retval = -EAGAIN;
- }
-
- switch (data[1]) {
- case COMEDI_EV_SCAN_BEGIN:
- devpriv->ext_clock.divisor = divisor;
- devpriv->ext_clock.chanspec = data[2];
- break;
- default:
- return -EINVAL;
- }
-
- data[4] = divisor;
-
- return retval ? retval : 5;
-}
-
-/* XXX could add support for 60xx series */
-static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- switch (board->layout) {
- case LAYOUT_4020:
- return ai_config_master_clock_4020(dev, data);
- default:
- return -EINVAL;
- }
-
- return -EINVAL;
-}
-
-static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int id = data[0];
-
- switch (id) {
- case INSN_CONFIG_ALT_SOURCE:
- return ai_config_calibration_source(dev, data);
- case INSN_CONFIG_BLOCK_SIZE:
- return ai_config_block_size(dev, data);
- case INSN_CONFIG_TIMER_1:
- return ai_config_master_clock(dev, data);
- default:
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-/*
- * Gets nearest achievable timing given master clock speed, does not
- * take into account possible minimum/maximum divisor values. Used
- * by other timing checking functions.
- */
-static unsigned int get_divisor(unsigned int ns, unsigned int flags)
-{
- unsigned int divisor;
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_UP:
- divisor = DIV_ROUND_UP(ns, TIMER_BASE);
- break;
- case CMDF_ROUND_DOWN:
- divisor = ns / TIMER_BASE;
- break;
- case CMDF_ROUND_NEAREST:
- default:
- divisor = DIV_ROUND_CLOSEST(ns, TIMER_BASE);
- break;
- }
- return divisor;
-}
-
-/*
- * utility function that rounds desired timing to an achievable time, and
- * sets cmd members appropriately.
- * adc paces conversions from master clock by dividing by (x + 3) where x is
- * 24 bit number
- */
-static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- unsigned long long convert_divisor = 0;
- unsigned int scan_divisor;
- static const int min_convert_divisor = 3;
- static const int max_convert_divisor =
- max_counter_value + min_convert_divisor;
- static const int min_scan_divisor_4020 = 2;
- unsigned long long max_scan_divisor, min_scan_divisor;
-
- if (cmd->convert_src == TRIG_TIMER) {
- if (board->layout == LAYOUT_4020) {
- cmd->convert_arg = 0;
- } else {
- convert_divisor = get_divisor(cmd->convert_arg,
- cmd->flags);
- if (convert_divisor > max_convert_divisor)
- convert_divisor = max_convert_divisor;
- if (convert_divisor < min_convert_divisor)
- convert_divisor = min_convert_divisor;
- cmd->convert_arg = convert_divisor * TIMER_BASE;
- }
- } else if (cmd->convert_src == TRIG_NOW) {
- cmd->convert_arg = 0;
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
- if (cmd->convert_src == TRIG_TIMER) {
- min_scan_divisor = convert_divisor * cmd->chanlist_len;
- max_scan_divisor =
- (convert_divisor * cmd->chanlist_len - 1) +
- max_counter_value;
- } else {
- min_scan_divisor = min_scan_divisor_4020;
- max_scan_divisor = max_counter_value + min_scan_divisor;
- }
- if (scan_divisor > max_scan_divisor)
- scan_divisor = max_scan_divisor;
- if (scan_divisor < min_scan_divisor)
- scan_divisor = min_scan_divisor;
- cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
- }
-}
-
-static int cb_pcidas64_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- if (aref != aref0) {
- dev_dbg(dev->class_dev,
- "all elements in chanlist must use the same analog reference\n");
- return -EINVAL;
- }
- }
-
- if (board->layout == LAYOUT_4020) {
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (chan != (chan0 + i)) {
- dev_dbg(dev->class_dev,
- "chanlist must use consecutive channels\n");
- return -EINVAL;
- }
- }
- if (cmd->chanlist_len == 3) {
- dev_dbg(dev->class_dev,
- "chanlist cannot be 3 channels long, use 1, 2, or 4 channels\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- int err = 0;
- unsigned int tmp_arg, tmp_arg2;
- unsigned int triggers;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
-
- triggers = TRIG_TIMER;
- if (board->layout == LAYOUT_4020)
- triggers |= TRIG_OTHER;
- else
- triggers |= TRIG_FOLLOW;
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, triggers);
-
- triggers = TRIG_TIMER;
- if (board->layout == LAYOUT_4020)
- triggers |= TRIG_NOW;
- else
- triggers |= TRIG_EXT;
- err |= comedi_check_trigger_src(&cmd->convert_src, triggers);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src,
- TRIG_COUNT | TRIG_EXT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- /*
- * start_arg is the CR_CHAN | CR_INVERT of the
- * external trigger.
- */
- break;
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- if (board->layout == LAYOUT_4020) {
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg,
- 0);
- } else {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- /*
- * if scans are timed faster than conversion rate
- * allows
- */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(
- &cmd->scan_begin_arg,
- cmd->convert_arg *
- cmd->chanlist_len);
- }
- }
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- switch (cmd->stop_src) {
- case TRIG_EXT:
- break;
- case TRIG_COUNT:
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- break;
- case TRIG_NONE:
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
- break;
- default:
- break;
- }
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- tmp_arg = cmd->convert_arg;
- tmp_arg2 = cmd->scan_begin_arg;
- check_adc_timing(dev, cmd);
- if (tmp_arg != cmd->convert_arg)
- err++;
- if (tmp_arg2 != cmd->scan_begin_arg)
- err++;
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= cb_pcidas64_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int use_hw_sample_counter(struct comedi_cmd *cmd)
-{
-/* disable for now until I work out a race */
- return 0;
-
- if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
- return 1;
-
- return 0;
-}
-
-static void setup_sample_counters(struct comedi_device *dev,
- struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
-
- /* load hardware conversion counter */
- if (use_hw_sample_counter(cmd)) {
- writew(cmd->stop_arg & 0xffff,
- devpriv->main_iobase + ADC_COUNT_LOWER_REG);
- writew((cmd->stop_arg >> 16) & 0xff,
- devpriv->main_iobase + ADC_COUNT_UPPER_REG);
- } else {
- writew(1, devpriv->main_iobase + ADC_COUNT_LOWER_REG);
- }
-}
-
-static inline unsigned int dma_transfer_size(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- unsigned int num_samples;
-
- num_samples = devpriv->ai_fifo_segment_length *
- board->ai_fifo->sample_packing_ratio;
- if (num_samples > DMA_BUFFER_SIZE / sizeof(u16))
- num_samples = DMA_BUFFER_SIZE / sizeof(u16);
-
- return num_samples;
-}
-
-static u32 ai_convert_counter_6xxx(const struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- /* supposed to load counter with desired divisor minus 3 */
- return cmd->convert_arg / TIMER_BASE - 3;
-}
-
-static u32 ai_scan_counter_6xxx(struct comedi_device *dev,
- struct comedi_cmd *cmd)
-{
- u32 count;
-
- /* figure out how long we need to delay at end of scan */
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- count = (cmd->scan_begin_arg -
- (cmd->convert_arg * (cmd->chanlist_len - 1))) /
- TIMER_BASE;
- break;
- case TRIG_FOLLOW:
- count = cmd->convert_arg / TIMER_BASE;
- break;
- default:
- return 0;
- }
- return count - 3;
-}
-
-static u32 ai_convert_counter_4020(struct comedi_device *dev,
- struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int divisor;
-
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- divisor = cmd->scan_begin_arg / TIMER_BASE;
- break;
- case TRIG_OTHER:
- divisor = devpriv->ext_clock.divisor;
- break;
- default: /* should never happen */
- dev_err(dev->class_dev, "bug! failed to set ai pacing!\n");
- divisor = 1000;
- break;
- }
-
- /* supposed to load counter with desired divisor minus 2 for 4020 */
- return divisor - 2;
-}
-
-static void select_master_clock_4020(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
-
- /* select internal/external master clock */
- devpriv->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
- if (cmd->scan_begin_src == TRIG_OTHER) {
- int chanspec = devpriv->ext_clock.chanspec;
-
- if (CR_CHAN(chanspec))
- devpriv->hw_config_bits |= BNC_CLOCK_4020_BITS;
- else
- devpriv->hw_config_bits |= EXT_CLOCK_4020_BITS;
- } else {
- devpriv->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
- }
- writew(devpriv->hw_config_bits,
- devpriv->main_iobase + HW_CONFIG_REG);
-}
-
-static void select_master_clock(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- switch (board->layout) {
- case LAYOUT_4020:
- select_master_clock_4020(dev, cmd);
- break;
- default:
- break;
- }
-}
-
-static inline void dma_start_sync(struct comedi_device *dev,
- unsigned int channel)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned long flags;
-
- /* spinlock for plx dma control/status reg */
- spin_lock_irqsave(&dev->spinlock, flags);
- writeb(PLX_DMACSR_ENABLE | PLX_DMACSR_START | PLX_DMACSR_CLEARINTR,
- devpriv->plx9080_iobase + PLX_REG_DMACSR(channel));
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- u32 convert_counter = 0, scan_counter = 0;
-
- check_adc_timing(dev, cmd);
-
- select_master_clock(dev, cmd);
-
- if (board->layout == LAYOUT_4020) {
- convert_counter = ai_convert_counter_4020(dev, cmd);
- } else {
- convert_counter = ai_convert_counter_6xxx(dev, cmd);
- scan_counter = ai_scan_counter_6xxx(dev, cmd);
- }
-
- /* load lower 16 bits of convert interval */
- writew(convert_counter & 0xffff,
- devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
- /* load upper 8 bits of convert interval */
- writew((convert_counter >> 16) & 0xff,
- devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
- /* load lower 16 bits of scan delay */
- writew(scan_counter & 0xffff,
- devpriv->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
- /* load upper 8 bits of scan delay */
- writew((scan_counter >> 16) & 0xff,
- devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
-}
-
-static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
-{
- int i;
-
- for (i = 0; i + 1 < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i + 1]) !=
- CR_CHAN(cmd->chanlist[i]) + 1)
- return 0;
- if (CR_RANGE(cmd->chanlist[i + 1]) !=
- CR_RANGE(cmd->chanlist[i]))
- return 0;
- if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
- return 0;
- }
- return 1;
-}
-
-static int setup_channel_queue(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- unsigned short bits;
- int i;
-
- if (board->layout != LAYOUT_4020) {
- if (use_internal_queue_6xxx(cmd)) {
- devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
- writew(devpriv->hw_config_bits,
- devpriv->main_iobase + HW_CONFIG_REG);
- bits = 0;
- /* set channel */
- bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
- /* set gain */
- bits |= ai_range_bits_6xxx(dev,
- CR_RANGE(cmd->chanlist[0]));
- /* set single-ended / differential */
- bits |= se_diff_bit_6xxx(dev,
- CR_AREF(cmd->chanlist[0]) ==
- AREF_DIFF);
- if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
- bits |= ADC_COMMON_BIT;
- /* set stop channel */
- writew(adc_chan_bits
- (CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])),
- devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
- /* set start channel, and rest of settings */
- writew(bits,
- devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
- } else {
- /* use external queue */
- if (dev->write_subdev && dev->write_subdev->busy) {
- warn_external_queue(dev);
- return -EBUSY;
- }
- devpriv->hw_config_bits |= EXT_QUEUE_BIT;
- writew(devpriv->hw_config_bits,
- devpriv->main_iobase + HW_CONFIG_REG);
- /* clear DAC buffer to prevent weird interactions */
- writew(0,
- devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
- /* clear queue pointer */
- writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
- /* load external queue */
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chanspec = cmd->chanlist[i];
- int use_differential;
-
- bits = 0;
- /* set channel */
- bits |= adc_chan_bits(CR_CHAN(chanspec));
- /* set gain */
- bits |= ai_range_bits_6xxx(dev,
- CR_RANGE(chanspec));
- /* set single-ended / differential */
- use_differential = 0;
- if (CR_AREF(chanspec) == AREF_DIFF)
- use_differential = 1;
- bits |= se_diff_bit_6xxx(dev, use_differential);
-
- if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
- bits |= ADC_COMMON_BIT;
- /* mark end of queue */
- if (i == cmd->chanlist_len - 1)
- bits |= QUEUE_EOSCAN_BIT |
- QUEUE_EOSEQ_BIT;
- writew(bits,
- devpriv->main_iobase +
- ADC_QUEUE_FIFO_REG);
- }
- /*
- * doing a queue clear is not specified in board docs,
- * but required for reliable operation
- */
- writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
- /* prime queue holding register */
- writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
- }
- } else {
- unsigned short old_cal_range_bits = devpriv->i2c_cal_range_bits;
-
- devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
- /* select BNC inputs */
- devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
- /* select ranges */
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int channel = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- if (range == 0)
- devpriv->i2c_cal_range_bits |=
- attenuate_bit(channel);
- else
- devpriv->i2c_cal_range_bits &=
- ~attenuate_bit(channel);
- }
- /*
- * update calibration/range i2c register only if necessary,
- * as it is very slow
- */
- if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
- u8 i2c_data = devpriv->i2c_cal_range_bits;
-
- i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
- sizeof(i2c_data));
- }
- }
- return 0;
-}
-
-static inline void load_first_dma_descriptor(struct comedi_device *dev,
- unsigned int dma_channel,
- unsigned int descriptor_bits)
-{
- struct pcidas64_private *devpriv = dev->private;
-
- /*
- * The transfer size, pci address, and local address registers
- * are supposedly unused during chained dma,
- * but I have found that left over values from last operation
- * occasionally cause problems with transfer of first dma
- * block. Initializing them to zero seems to fix the problem.
- */
- if (dma_channel) {
- writel(0, devpriv->plx9080_iobase + PLX_REG_DMASIZ1);
- writel(0, devpriv->plx9080_iobase + PLX_REG_DMAPADR1);
- writel(0, devpriv->plx9080_iobase + PLX_REG_DMALADR1);
- writel(descriptor_bits,
- devpriv->plx9080_iobase + PLX_REG_DMADPR1);
- } else {
- writel(0, devpriv->plx9080_iobase + PLX_REG_DMASIZ0);
- writel(0, devpriv->plx9080_iobase + PLX_REG_DMAPADR0);
- writel(0, devpriv->plx9080_iobase + PLX_REG_DMALADR0);
- writel(descriptor_bits,
- devpriv->plx9080_iobase + PLX_REG_DMADPR0);
- }
-}
-
-static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u32 bits;
- unsigned int i;
- unsigned long flags;
- int retval;
-
- disable_ai_pacing(dev);
- abort_dma(dev, 1);
-
- retval = setup_channel_queue(dev, cmd);
- if (retval < 0)
- return retval;
-
- /* make sure internal calibration source is turned off */
- writew(0, devpriv->main_iobase + CALIBRATION_REG);
-
- set_ai_pacing(dev, cmd);
-
- setup_sample_counters(dev, cmd);
-
- enable_ai_interrupts(dev, cmd);
-
- spin_lock_irqsave(&dev->spinlock, flags);
- /* set mode, allow conversions through software gate */
- devpriv->adc_control1_bits |= ADC_SW_GATE_BIT;
- devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
- if (board->layout != LAYOUT_4020) {
- devpriv->adc_control1_bits &= ~ADC_MODE_MASK;
- if (cmd->convert_src == TRIG_EXT)
- /* good old mode 13 */
- devpriv->adc_control1_bits |= adc_mode_bits(13);
- else
- /* mode 8. What else could you need? */
- devpriv->adc_control1_bits |= adc_mode_bits(8);
- } else {
- devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
- if (cmd->chanlist_len == 4)
- devpriv->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
- else if (cmd->chanlist_len == 2)
- devpriv->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
- devpriv->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
- devpriv->adc_control1_bits |=
- adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
- devpriv->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
- devpriv->adc_control1_bits |=
- adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist
- [cmd->chanlist_len - 1]));
- }
- writew(devpriv->adc_control1_bits,
- devpriv->main_iobase + ADC_CONTROL1_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* clear adc buffer */
- writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
-
- if ((cmd->flags & CMDF_WAKE_EOS) == 0 ||
- board->layout == LAYOUT_4020) {
- devpriv->ai_dma_index = 0;
-
- /* set dma transfer size */
- for (i = 0; i < ai_dma_ring_count(board); i++)
- devpriv->ai_dma_desc[i].transfer_size =
- cpu_to_le32(dma_transfer_size(dev) *
- sizeof(u16));
-
- /* give location of first dma descriptor */
- load_first_dma_descriptor(dev, 1,
- devpriv->ai_dma_desc_bus_addr |
- PLX_DMADPR_DESCPCI |
- PLX_DMADPR_TCINTR |
- PLX_DMADPR_XFERL2P);
-
- dma_start_sync(dev, 1);
- }
-
- if (board->layout == LAYOUT_4020) {
- /* set source for external triggers */
- bits = 0;
- if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
- bits |= EXT_START_TRIG_BNC_BIT;
- if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
- bits |= EXT_STOP_TRIG_BNC_BIT;
- writew(bits, devpriv->main_iobase + DAQ_ATRIG_LOW_4020_REG);
- }
-
- spin_lock_irqsave(&dev->spinlock, flags);
-
- /* enable pacing, triggering, etc */
- bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
- if (cmd->flags & CMDF_WAKE_EOS)
- bits |= ADC_DMA_DISABLE_BIT;
- /* set start trigger */
- if (cmd->start_src == TRIG_EXT) {
- bits |= ADC_START_TRIG_EXT_BITS;
- if (cmd->start_arg & CR_INVERT)
- bits |= ADC_START_TRIG_FALLING_BIT;
- } else if (cmd->start_src == TRIG_NOW) {
- bits |= ADC_START_TRIG_SOFT_BITS;
- }
- if (use_hw_sample_counter(cmd))
- bits |= ADC_SAMPLE_COUNTER_EN_BIT;
- writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG);
-
- devpriv->ai_cmd_running = 1;
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* start acquisition */
- if (cmd->start_src == TRIG_NOW)
- writew(0, devpriv->main_iobase + ADC_START_REG);
-
- return 0;
-}
-
-/* read num_samples from 16 bit wide ai fifo */
-static void pio_drain_ai_fifo_16(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int i;
- u16 prepost_bits;
- int read_segment, read_index, write_segment, write_index;
- int num_samples;
-
- do {
- /* get least significant 15 bits */
- read_index = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
- 0x7fff;
- write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) &
- 0x7fff;
- /*
- * Get most significant bits (grey code).
- * Different boards use different code so use a scheme
- * that doesn't depend on encoding. This read must
- * occur after reading least significant 15 bits to avoid race
- * with fifo switching to next segment.
- */
- prepost_bits = readw(devpriv->main_iobase + PREPOST_REG);
-
- /*
- * if read and write pointers are not on the same fifo segment,
- * read to the end of the read segment
- */
- read_segment = adc_upper_read_ptr_code(prepost_bits);
- write_segment = adc_upper_write_ptr_code(prepost_bits);
-
- if (read_segment != write_segment)
- num_samples =
- devpriv->ai_fifo_segment_length - read_index;
- else
- num_samples = write_index - read_index;
- if (num_samples < 0) {
- dev_err(dev->class_dev,
- "cb_pcidas64: bug! num_samples < 0\n");
- break;
- }
-
- num_samples = comedi_nsamples_left(s, num_samples);
- if (num_samples == 0)
- break;
-
- for (i = 0; i < num_samples; i++) {
- unsigned short val;
-
- val = readw(devpriv->main_iobase + ADC_FIFO_REG);
- comedi_buf_write_samples(s, &val, 1);
- }
-
- } while (read_segment != write_segment);
-}
-
-/*
- * Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of
- * pointers. The pci-4020 hardware only supports dma transfers (it only
- * supports the use of pio for draining the last remaining points from the
- * fifo when a data acquisition operation has completed).
- */
-static void pio_drain_ai_fifo_32(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int nsamples;
- unsigned int i;
- u32 fifo_data;
- int write_code =
- readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
- int read_code =
- readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
-
- nsamples = comedi_nsamples_left(s, 100000);
- for (i = 0; read_code != write_code && i < nsamples;) {
- unsigned short val;
-
- fifo_data = readl(dev->mmio + ADC_FIFO_REG);
- val = fifo_data & 0xffff;
- comedi_buf_write_samples(s, &val, 1);
- i++;
- if (i < nsamples) {
- val = (fifo_data >> 16) & 0xffff;
- comedi_buf_write_samples(s, &val, 1);
- i++;
- }
- read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
- 0x7fff;
- }
-}
-
-/* empty fifo */
-static void pio_drain_ai_fifo(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- if (board->layout == LAYOUT_4020)
- pio_drain_ai_fifo_32(dev);
- else
- pio_drain_ai_fifo_16(dev);
-}
-
-static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- u32 next_transfer_addr;
- int j;
- int num_samples = 0;
- void __iomem *pci_addr_reg;
-
- pci_addr_reg = devpriv->plx9080_iobase + PLX_REG_DMAPADR(channel);
-
- /* loop until we have read all the full buffers */
- for (j = 0, next_transfer_addr = readl(pci_addr_reg);
- (next_transfer_addr <
- devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] ||
- next_transfer_addr >=
- devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] +
- DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board); j++) {
- /* transfer data from dma buffer to comedi buffer */
- num_samples = comedi_nsamples_left(s, dma_transfer_size(dev));
- comedi_buf_write_samples(s,
- devpriv->ai_buffer[devpriv->ai_dma_index],
- num_samples);
- devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) %
- ai_dma_ring_count(board);
- }
- /*
- * XXX check for dma ring buffer overrun
- * (use end-of-chain bit to mark last unused buffer)
- */
-}
-
-static void handle_ai_interrupt(struct comedi_device *dev,
- unsigned short status,
- unsigned int plx_status)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u8 dma1_status;
- unsigned long flags;
-
- /* check for fifo overrun */
- if (status & ADC_OVERRUN_BIT) {
- dev_err(dev->class_dev, "fifo overrun\n");
- async->events |= COMEDI_CB_ERROR;
- }
- /* spin lock makes sure no one else changes plx dma control reg */
- spin_lock_irqsave(&dev->spinlock, flags);
- dma1_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR1);
- if (plx_status & PLX_INTCSR_DMA1IA) { /* dma chan 1 interrupt */
- writeb((dma1_status & PLX_DMACSR_ENABLE) | PLX_DMACSR_CLEARINTR,
- devpriv->plx9080_iobase + PLX_REG_DMACSR1);
-
- if (dma1_status & PLX_DMACSR_ENABLE)
- drain_dma_buffers(dev, 1);
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* drain fifo with pio */
- if ((status & ADC_DONE_BIT) ||
- ((cmd->flags & CMDF_WAKE_EOS) &&
- (status & ADC_INTR_PENDING_BIT) &&
- (board->layout != LAYOUT_4020))) {
- spin_lock_irqsave(&dev->spinlock, flags);
- if (devpriv->ai_cmd_running) {
- spin_unlock_irqrestore(&dev->spinlock, flags);
- pio_drain_ai_fifo(dev);
- } else {
- spin_unlock_irqrestore(&dev->spinlock, flags);
- }
- }
- /* if we are have all the data, then quit */
- if ((cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) ||
- (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT)))
- async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
-}
-
-static inline unsigned int prev_ao_dma_index(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int buffer_index;
-
- if (devpriv->ao_dma_index == 0)
- buffer_index = AO_DMA_RING_COUNT - 1;
- else
- buffer_index = devpriv->ao_dma_index - 1;
- return buffer_index;
-}
-
-static int last_ao_dma_load_completed(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int buffer_index;
- unsigned int transfer_address;
- unsigned short dma_status;
-
- buffer_index = prev_ao_dma_index(dev);
- dma_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR0);
- if ((dma_status & PLX_DMACSR_DONE) == 0)
- return 0;
-
- transfer_address =
- readl(devpriv->plx9080_iobase + PLX_REG_DMAPADR0);
- if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index])
- return 0;
-
- return 1;
-}
-
-static inline int ao_dma_needs_restart(struct comedi_device *dev,
- unsigned short dma_status)
-{
- if ((dma_status & PLX_DMACSR_DONE) == 0 ||
- (dma_status & PLX_DMACSR_ENABLE) == 0)
- return 0;
- if (last_ao_dma_load_completed(dev))
- return 0;
-
- return 1;
-}
-
-static void restart_ao_dma(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int dma_desc_bits;
-
- dma_desc_bits = readl(devpriv->plx9080_iobase + PLX_REG_DMADPR0);
- dma_desc_bits &= ~PLX_DMADPR_CHAINEND;
- load_first_dma_descriptor(dev, 0, dma_desc_bits);
-
- dma_start_sync(dev, 0);
-}
-
-static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned short *dest,
- unsigned int max_bytes)
-{
- unsigned int nsamples = comedi_bytes_to_samples(s, max_bytes);
- unsigned int actual_bytes;
-
- nsamples = comedi_nsamples_left(s, nsamples);
- actual_bytes = comedi_buf_read_samples(s, dest, nsamples);
-
- return comedi_bytes_to_samples(s, actual_bytes);
-}
-
-static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- unsigned int buffer_index = devpriv->ao_dma_index;
- unsigned int prev_buffer_index = prev_ao_dma_index(dev);
- unsigned int nsamples;
- unsigned int nbytes;
- unsigned int next_bits;
-
- nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
- devpriv->ao_buffer[buffer_index],
- DMA_BUFFER_SIZE);
- if (nsamples == 0)
- return 0;
-
- nbytes = comedi_samples_to_bytes(s, nsamples);
- devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(nbytes);
- /* set end of chain bit so we catch underruns */
- next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next);
- next_bits |= PLX_DMADPR_CHAINEND;
- devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
- /*
- * clear end of chain bit on previous buffer now that we have set it
- * for the last buffer
- */
- next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next);
- next_bits &= ~PLX_DMADPR_CHAINEND;
- devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
-
- devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
-
- return nbytes;
-}
-
-static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int num_bytes;
- unsigned int next_transfer_addr;
- void __iomem *pci_addr_reg = devpriv->plx9080_iobase + PLX_REG_DMAPADR0;
- unsigned int buffer_index;
-
- do {
- buffer_index = devpriv->ao_dma_index;
- /* don't overwrite data that hasn't been transferred yet */
- next_transfer_addr = readl(pci_addr_reg);
- if (next_transfer_addr >=
- devpriv->ao_buffer_bus_addr[buffer_index] &&
- next_transfer_addr <
- devpriv->ao_buffer_bus_addr[buffer_index] +
- DMA_BUFFER_SIZE)
- return;
- num_bytes = load_ao_dma_buffer(dev, cmd);
- } while (num_bytes >= DMA_BUFFER_SIZE);
-}
-
-static void handle_ao_interrupt(struct comedi_device *dev,
- unsigned short status, unsigned int plx_status)
-{
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- struct comedi_async *async;
- struct comedi_cmd *cmd;
- u8 dma0_status;
- unsigned long flags;
-
- /* board might not support ao, in which case write_subdev is NULL */
- if (!s)
- return;
- async = s->async;
- cmd = &async->cmd;
-
- /* spin lock makes sure no one else changes plx dma control reg */
- spin_lock_irqsave(&dev->spinlock, flags);
- dma0_status = readb(devpriv->plx9080_iobase + PLX_REG_DMACSR0);
- if (plx_status & PLX_INTCSR_DMA0IA) { /* dma chan 0 interrupt */
- if ((dma0_status & PLX_DMACSR_ENABLE) &&
- !(dma0_status & PLX_DMACSR_DONE)) {
- writeb(PLX_DMACSR_ENABLE | PLX_DMACSR_CLEARINTR,
- devpriv->plx9080_iobase + PLX_REG_DMACSR0);
- } else {
- writeb(PLX_DMACSR_CLEARINTR,
- devpriv->plx9080_iobase + PLX_REG_DMACSR0);
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
- if (dma0_status & PLX_DMACSR_ENABLE) {
- load_ao_dma(dev, cmd);
- /* try to recover from dma end-of-chain event */
- if (ao_dma_needs_restart(dev, dma0_status))
- restart_ao_dma(dev);
- }
- } else {
- spin_unlock_irqrestore(&dev->spinlock, flags);
- }
-
- if ((status & DAC_DONE_BIT)) {
- if ((cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) ||
- last_ao_dma_load_completed(dev))
- async->events |= COMEDI_CB_EOA;
- else
- async->events |= COMEDI_CB_ERROR;
- }
- comedi_handle_events(dev, s);
-}
-
-static irqreturn_t handle_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct pcidas64_private *devpriv = dev->private;
- unsigned short status;
- u32 plx_status;
- u32 plx_bits;
-
- plx_status = readl(devpriv->plx9080_iobase + PLX_REG_INTCSR);
- status = readw(devpriv->main_iobase + HW_STATUS_REG);
-
- /*
- * an interrupt before all the postconfig stuff gets done could
- * cause a NULL dereference if we continue through the
- * interrupt handler
- */
- if (!dev->attached)
- return IRQ_HANDLED;
-
- handle_ai_interrupt(dev, status, plx_status);
- handle_ao_interrupt(dev, status, plx_status);
-
- /* clear possible plx9080 interrupt sources */
- if (plx_status & PLX_INTCSR_LDBIA) {
- /* clear local doorbell interrupt */
- plx_bits = readl(devpriv->plx9080_iobase + PLX_REG_L2PDBELL);
- writel(plx_bits, devpriv->plx9080_iobase + PLX_REG_L2PDBELL);
- }
-
- return IRQ_HANDLED;
-}
-
-static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- if (devpriv->ai_cmd_running == 0) {
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return 0;
- }
- devpriv->ai_cmd_running = 0;
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- disable_ai_pacing(dev);
-
- abort_dma(dev, 1);
-
- return 0;
-}
-
-static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val = s->readback[chan];
- unsigned int i;
-
- /* do some initializing */
- writew(0, devpriv->main_iobase + DAC_CONTROL0_REG);
-
- /* set range */
- set_dac_range_bits(dev, &devpriv->dac_control1_bits, chan, range);
- writew(devpriv->dac_control1_bits,
- devpriv->main_iobase + DAC_CONTROL1_REG);
-
- for (i = 0; i < insn->n; i++) {
- /* write to channel */
- val = data[i];
- if (board->layout == LAYOUT_4020) {
- writew(val & 0xff,
- devpriv->main_iobase + dac_lsb_4020_reg(chan));
- writew((val >> 8) & 0xf,
- devpriv->main_iobase + dac_msb_4020_reg(chan));
- } else {
- writew(val,
- devpriv->main_iobase + dac_convert_reg(chan));
- }
- }
-
- /* remember last output value */
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static void set_dac_control0_reg(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
- WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
-
- if (cmd->start_src == TRIG_EXT) {
- bits |= WAVEFORM_TRIG_EXT_BITS;
- if (cmd->start_arg & CR_INVERT)
- bits |= WAVEFORM_TRIG_FALLING_BIT;
- } else {
- bits |= WAVEFORM_TRIG_SOFT_BITS;
- }
- if (cmd->scan_begin_src == TRIG_EXT) {
- bits |= DAC_EXT_UPDATE_ENABLE_BIT;
- if (cmd->scan_begin_arg & CR_INVERT)
- bits |= DAC_EXT_UPDATE_FALLING_BIT;
- }
- writew(bits, devpriv->main_iobase + DAC_CONTROL0_REG);
-}
-
-static void set_dac_control1_reg(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- int channel, range;
-
- channel = CR_CHAN(cmd->chanlist[i]);
- range = CR_RANGE(cmd->chanlist[i]);
- set_dac_range_bits(dev, &devpriv->dac_control1_bits, channel,
- range);
- }
- devpriv->dac_control1_bits |= DAC_SW_GATE_BIT;
- writew(devpriv->dac_control1_bits,
- devpriv->main_iobase + DAC_CONTROL1_REG);
-}
-
-static void set_dac_select_reg(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- u16 bits;
- unsigned int first_channel, last_channel;
-
- first_channel = CR_CHAN(cmd->chanlist[0]);
- last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
- if (last_channel < first_channel)
- dev_err(dev->class_dev,
- "bug! last ao channel < first ao channel\n");
-
- bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
-
- writew(bits, devpriv->main_iobase + DAC_SELECT_REG);
-}
-
-static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
-{
- return get_divisor(ns, flags) - 2;
-}
-
-static void set_dac_interval_regs(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- unsigned int divisor;
-
- if (cmd->scan_begin_src != TRIG_TIMER)
- return;
-
- divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
- if (divisor > max_counter_value) {
- dev_err(dev->class_dev, "bug! ao divisor too big\n");
- divisor = max_counter_value;
- }
- writew(divisor & 0xffff,
- devpriv->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
- writew((divisor >> 16) & 0xff,
- devpriv->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
-}
-
-static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
-{
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- unsigned int nsamples;
- unsigned int nbytes;
- int i;
-
- /*
- * clear queue pointer too, since external queue has
- * weird interactions with ao fifo
- */
- writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
- writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
-
- nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
- devpriv->ao_bounce_buffer,
- DAC_FIFO_SIZE);
- if (nsamples == 0)
- return -1;
-
- for (i = 0; i < nsamples; i++) {
- writew(devpriv->ao_bounce_buffer[i],
- devpriv->main_iobase + DAC_FIFO_REG);
- }
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- return 0;
-
- nbytes = load_ao_dma_buffer(dev, cmd);
- if (nbytes == 0)
- return -1;
- load_ao_dma(dev, cmd);
-
- dma_start_sync(dev, 0);
-
- return 0;
-}
-
-static inline int external_ai_queue_in_use(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- if (!dev->read_subdev->busy)
- return 0;
- if (board->layout == LAYOUT_4020)
- return 0;
- else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd))
- return 0;
- return 1;
-}
-
-static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int retval;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- retval = prep_ao_dma(dev, cmd);
- if (retval < 0)
- return -EPIPE;
-
- set_dac_control0_reg(dev, cmd);
-
- if (cmd->start_src == TRIG_INT)
- writew(0, devpriv->main_iobase + DAC_START_REG);
-
- s->async->inttrig = NULL;
-
- return 0;
-}
-
-static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (external_ai_queue_in_use(dev)) {
- warn_external_queue(dev);
- return -EBUSY;
- }
- /* disable analog output system during setup */
- writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
-
- devpriv->ao_dma_index = 0;
-
- set_dac_select_reg(dev, cmd);
- set_dac_interval_regs(dev, cmd);
- load_first_dma_descriptor(dev, 0, devpriv->ao_dma_desc_bus_addr |
- PLX_DMADPR_DESCPCI | PLX_DMADPR_TCINTR);
-
- set_dac_control1_reg(dev, cmd);
- s->async->inttrig = ao_inttrig;
-
- return 0;
-}
-
-static int cb_pcidas64_ao_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (chan != (chan0 + i)) {
- dev_dbg(dev->class_dev,
- "chanlist must use consecutive channels\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- int err = 0;
- unsigned int tmp_arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
- err |= -EINVAL;
- if (cmd->stop_src != TRIG_COUNT &&
- cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- board->ao_scan_speed);
- if (get_ao_divisor(cmd->scan_begin_arg, cmd->flags) >
- max_counter_value) {
- cmd->scan_begin_arg = (max_counter_value + 2) *
- TIMER_BASE;
- err |= -EINVAL;
- }
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- tmp_arg = cmd->scan_begin_arg;
- cmd->scan_begin_arg = get_divisor(cmd->scan_begin_arg,
- cmd->flags) * TIMER_BASE;
- if (tmp_arg != cmd->scan_begin_arg)
- err++;
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= cb_pcidas64_ao_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcidas64_private *devpriv = dev->private;
-
- writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
- abort_dma(dev, 0);
- return 0;
-}
-
-static int dio_callback_4020(struct comedi_device *dev,
- int dir, int port, int data, unsigned long iobase)
-{
- struct pcidas64_private *devpriv = dev->private;
-
- if (dir) {
- writew(data, devpriv->main_iobase + iobase + 2 * port);
- return 0;
- }
- return readw(devpriv->main_iobase + iobase + 2 * port);
-}
-
-static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int bits;
-
- bits = readb(dev->mmio + DI_REG);
- bits &= 0xf;
- data[1] = bits;
- data[0] = 0;
-
- return insn->n;
-}
-
-static int do_wbits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- writeb(s->state, dev->mmio + DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int dio_60xx_config_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- writeb(s->io_bits, dev->mmio + DIO_DIRECTION_60XX_REG);
-
- return insn->n;
-}
-
-static int dio_60xx_wbits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- writeb(s->state, dev->mmio + DIO_DATA_60XX_REG);
-
- data[1] = readb(dev->mmio + DIO_DATA_60XX_REG);
-
- return insn->n;
-}
-
-/*
- * pci-6025 8800 caldac:
- * address 0 == dac channel 0 offset
- * address 1 == dac channel 0 gain
- * address 2 == dac channel 1 offset
- * address 3 == dac channel 1 gain
- * address 4 == fine adc offset
- * address 5 == coarse adc offset
- * address 6 == coarse adc gain
- * address 7 == fine adc gain
- */
-/*
- * pci-6402/16 uses all 8 channels for dac:
- * address 0 == dac channel 0 fine gain
- * address 1 == dac channel 0 coarse gain
- * address 2 == dac channel 0 coarse offset
- * address 3 == dac channel 1 coarse offset
- * address 4 == dac channel 1 fine gain
- * address 5 == dac channel 1 coarse gain
- * address 6 == dac channel 0 fine offset
- * address 7 == dac channel 1 fine offset
- */
-
-static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
- u8 value)
-{
- struct pcidas64_private *devpriv = dev->private;
- static const int num_caldac_channels = 8;
- static const int bitstream_length = 11;
- unsigned int bitstream = ((address & 0x7) << 8) | value;
- unsigned int bit, register_bits;
- static const int caldac_8800_udelay = 1;
-
- if (address >= num_caldac_channels) {
- dev_err(dev->class_dev, "illegal caldac channel\n");
- return -1;
- }
- for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
- register_bits = 0;
- if (bitstream & bit)
- register_bits |= SERIAL_DATA_IN_BIT;
- udelay(caldac_8800_udelay);
- writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
- register_bits |= SERIAL_CLOCK_BIT;
- udelay(caldac_8800_udelay);
- writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
- }
- udelay(caldac_8800_udelay);
- writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG);
- udelay(caldac_8800_udelay);
- writew(0, devpriv->main_iobase + CALIBRATION_REG);
- udelay(caldac_8800_udelay);
- return 0;
-}
-
-/* 4020 caldacs */
-static int caldac_i2c_write(struct comedi_device *dev,
- unsigned int caldac_channel, unsigned int value)
-{
- u8 serial_bytes[3];
- u8 i2c_addr;
- enum pointer_bits {
- /* manual has gain and offset bits switched */
- OFFSET_0_2 = 0x1,
- GAIN_0_2 = 0x2,
- OFFSET_1_3 = 0x4,
- GAIN_1_3 = 0x8,
- };
- enum data_bits {
- NOT_CLEAR_REGISTERS = 0x20,
- };
-
- switch (caldac_channel) {
- case 0: /* chan 0 offset */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = OFFSET_0_2;
- break;
- case 1: /* chan 1 offset */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = OFFSET_1_3;
- break;
- case 2: /* chan 2 offset */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = OFFSET_0_2;
- break;
- case 3: /* chan 3 offset */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = OFFSET_1_3;
- break;
- case 4: /* chan 0 gain */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = GAIN_0_2;
- break;
- case 5: /* chan 1 gain */
- i2c_addr = CALDAC0_I2C_ADDR;
- serial_bytes[0] = GAIN_1_3;
- break;
- case 6: /* chan 2 gain */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = GAIN_0_2;
- break;
- case 7: /* chan 3 gain */
- i2c_addr = CALDAC1_I2C_ADDR;
- serial_bytes[0] = GAIN_1_3;
- break;
- default:
- dev_err(dev->class_dev, "invalid caldac channel\n");
- return -1;
- }
- serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
- serial_bytes[2] = value & 0xff;
- i2c_write(dev, i2c_addr, serial_bytes, 3);
- return 0;
-}
-
-static void caldac_write(struct comedi_device *dev, unsigned int channel,
- unsigned int value)
-{
- const struct pcidas64_board *board = dev->board_ptr;
-
- switch (board->layout) {
- case LAYOUT_60XX:
- case LAYOUT_64XX:
- caldac_8800_write(dev, channel, value);
- break;
- case LAYOUT_4020:
- caldac_i2c_write(dev, channel, value);
- break;
- default:
- break;
- }
-}
-
-static int cb_pcidas64_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /*
- * Programming the calib device is slow. Only write the
- * last data value if the value has changed.
- */
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- if (s->readback[chan] != val) {
- caldac_write(dev, chan, val);
- s->readback[chan] = val;
- }
- }
-
- return insn->n;
-}
-
-static void ad8402_write(struct comedi_device *dev, unsigned int channel,
- unsigned int value)
-{
- struct pcidas64_private *devpriv = dev->private;
- static const int bitstream_length = 10;
- unsigned int bit, register_bits;
- unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
- static const int ad8402_udelay = 1;
-
- register_bits = SELECT_8402_64XX_BIT;
- udelay(ad8402_udelay);
- writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
-
- for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
- if (bitstream & bit)
- register_bits |= SERIAL_DATA_IN_BIT;
- else
- register_bits &= ~SERIAL_DATA_IN_BIT;
- udelay(ad8402_udelay);
- writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
- udelay(ad8402_udelay);
- writew(register_bits | SERIAL_CLOCK_BIT,
- devpriv->main_iobase + CALIBRATION_REG);
- }
-
- udelay(ad8402_udelay);
- writew(0, devpriv->main_iobase + CALIBRATION_REG);
-}
-
-/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
-static int cb_pcidas64_ad8402_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /*
- * Programming the calib device is slow. Only write the
- * last data value if the value has changed.
- */
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- if (s->readback[chan] != val) {
- ad8402_write(dev, chan, val);
- s->readback[chan] = val;
- }
- }
-
- return insn->n;
-}
-
-static u16 read_eeprom(struct comedi_device *dev, u8 address)
-{
- struct pcidas64_private *devpriv = dev->private;
- static const int bitstream_length = 11;
- static const int read_command = 0x6;
- unsigned int bitstream = (read_command << 8) | address;
- unsigned int bit;
- void __iomem * const plx_control_addr =
- devpriv->plx9080_iobase + PLX_REG_CNTRL;
- u16 value;
- static const int value_length = 16;
- static const int eeprom_udelay = 1;
-
- udelay(eeprom_udelay);
- devpriv->plx_control_bits &= ~PLX_CNTRL_EESK & ~PLX_CNTRL_EECS;
- /* make sure we don't send anything to the i2c bus on 4020 */
- devpriv->plx_control_bits |= PLX_CNTRL_USERO;
- writel(devpriv->plx_control_bits, plx_control_addr);
- /* activate serial eeprom */
- udelay(eeprom_udelay);
- devpriv->plx_control_bits |= PLX_CNTRL_EECS;
- writel(devpriv->plx_control_bits, plx_control_addr);
-
- /* write read command and desired memory address */
- for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
- /* set bit to be written */
- udelay(eeprom_udelay);
- if (bitstream & bit)
- devpriv->plx_control_bits |= PLX_CNTRL_EEWB;
- else
- devpriv->plx_control_bits &= ~PLX_CNTRL_EEWB;
- writel(devpriv->plx_control_bits, plx_control_addr);
- /* clock in bit */
- udelay(eeprom_udelay);
- devpriv->plx_control_bits |= PLX_CNTRL_EESK;
- writel(devpriv->plx_control_bits, plx_control_addr);
- udelay(eeprom_udelay);
- devpriv->plx_control_bits &= ~PLX_CNTRL_EESK;
- writel(devpriv->plx_control_bits, plx_control_addr);
- }
- /* read back value from eeprom memory location */
- value = 0;
- for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
- /* clock out bit */
- udelay(eeprom_udelay);
- devpriv->plx_control_bits |= PLX_CNTRL_EESK;
- writel(devpriv->plx_control_bits, plx_control_addr);
- udelay(eeprom_udelay);
- devpriv->plx_control_bits &= ~PLX_CNTRL_EESK;
- writel(devpriv->plx_control_bits, plx_control_addr);
- udelay(eeprom_udelay);
- if (readl(plx_control_addr) & PLX_CNTRL_EERB)
- value |= bit;
- }
-
- /* deactivate eeprom serial input */
- udelay(eeprom_udelay);
- devpriv->plx_control_bits &= ~PLX_CNTRL_EECS;
- writel(devpriv->plx_control_bits, plx_control_addr);
-
- return value;
-}
-
-static int eeprom_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int val;
- unsigned int i;
-
- if (insn->n) {
- /* No point reading the same EEPROM location more than once. */
- val = read_eeprom(dev, CR_CHAN(insn->chanspec));
- for (i = 0; i < insn->n; i++)
- data[i] = val;
- }
-
- return insn->n;
-}
-
-/* Allocate and initialize the subdevice structures. */
-static int setup_subdevices(struct comedi_device *dev)
-{
- const struct pcidas64_board *board = dev->board_ptr;
- struct pcidas64_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- int i;
- int ret;
-
- ret = comedi_alloc_subdevices(dev, 10);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* analog input subdevice */
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
- if (board->layout == LAYOUT_60XX)
- s->subdev_flags |= SDF_COMMON | SDF_DIFF;
- else if (board->layout == LAYOUT_64XX)
- s->subdev_flags |= SDF_DIFF;
- /* XXX Number of inputs in differential mode is ignored */
- s->n_chan = board->ai_se_chans;
- s->len_chanlist = 0x2000;
- s->maxdata = (1 << board->ai_bits) - 1;
- s->range_table = board->ai_range_table;
- s->insn_read = ai_rinsn;
- s->insn_config = ai_config_insn;
- s->do_cmd = ai_cmd;
- s->do_cmdtest = ai_cmdtest;
- s->cancel = ai_cancel;
- if (board->layout == LAYOUT_4020) {
- u8 data;
- /*
- * set adc to read from inputs
- * (not internal calibration sources)
- */
- devpriv->i2c_cal_range_bits = adc_src_4020_bits(4);
- /* set channels to +-5 volt input ranges */
- for (i = 0; i < s->n_chan; i++)
- devpriv->i2c_cal_range_bits |= attenuate_bit(i);
- data = devpriv->i2c_cal_range_bits;
- i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
- }
-
- /* analog output subdevice */
- s = &dev->subdevices[1];
- if (board->ao_nchan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
- SDF_GROUND | SDF_CMD_WRITE;
- s->n_chan = board->ao_nchan;
- s->maxdata = (1 << board->ao_bits) - 1;
- s->range_table = board->ao_range_table;
- s->insn_write = ao_winsn;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- if (ao_cmd_is_supported(board)) {
- dev->write_subdev = s;
- s->do_cmdtest = ao_cmdtest;
- s->do_cmd = ao_cmd;
- s->len_chanlist = board->ao_nchan;
- s->cancel = ao_cancel;
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* digital input */
- s = &dev->subdevices[2];
- if (board->layout == LAYOUT_64XX) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = di_rbits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* digital output */
- if (board->layout == LAYOUT_64XX) {
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = do_wbits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* 8255 */
- s = &dev->subdevices[4];
- if (board->has_8255) {
- if (board->layout == LAYOUT_4020) {
- ret = subdev_8255_init(dev, s, dio_callback_4020,
- I8255_4020_REG);
- } else {
- ret = subdev_8255_mm_init(dev, s, NULL,
- DIO_8255_OFFSET);
- }
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* 8 channel dio for 60xx */
- s = &dev->subdevices[5];
- if (board->layout == LAYOUT_60XX) {
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = dio_60xx_config_insn;
- s->insn_bits = dio_60xx_wbits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* caldac */
- s = &dev->subdevices[6];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 8;
- if (board->layout == LAYOUT_4020)
- s->maxdata = 0xfff;
- else
- s->maxdata = 0xff;
- s->insn_write = cb_pcidas64_calib_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++) {
- caldac_write(dev, i, s->maxdata / 2);
- s->readback[i] = s->maxdata / 2;
- }
-
- /* 2 channel ad8402 potentiometer */
- s = &dev->subdevices[7];
- if (board->layout == LAYOUT_64XX) {
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 2;
- s->maxdata = 0xff;
- s->insn_write = cb_pcidas64_ad8402_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++) {
- ad8402_write(dev, i, s->maxdata / 2);
- s->readback[i] = s->maxdata / 2;
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* serial EEPROM, if present */
- s = &dev->subdevices[8];
- if (readl(devpriv->plx9080_iobase + PLX_REG_CNTRL) &
- PLX_CNTRL_EEPRESENT) {
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->n_chan = 128;
- s->maxdata = 0xffff;
- s->insn_read = eeprom_read_insn;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* user counter subd XXX */
- s = &dev->subdevices[9];
- s->type = COMEDI_SUBD_UNUSED;
-
- return 0;
-}
-
-static int auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct pcidas64_board *board = NULL;
- struct pcidas64_private *devpriv;
- u32 local_range, local_decode;
- int retval;
-
- if (context < ARRAY_SIZE(pcidas64_boards))
- board = &pcidas64_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- retval = comedi_pci_enable(dev);
- if (retval)
- return retval;
- pci_set_master(pcidev);
-
- /* Initialize dev->board_name */
- dev->board_name = board->name;
-
- devpriv->main_phys_iobase = pci_resource_start(pcidev, 2);
- devpriv->dio_counter_phys_iobase = pci_resource_start(pcidev, 3);
-
- devpriv->plx9080_iobase = pci_ioremap_bar(pcidev, 0);
- devpriv->main_iobase = pci_ioremap_bar(pcidev, 2);
- dev->mmio = pci_ioremap_bar(pcidev, 3);
-
- if (!devpriv->plx9080_iobase || !devpriv->main_iobase || !dev->mmio) {
- dev_warn(dev->class_dev, "failed to remap io memory\n");
- return -ENOMEM;
- }
-
- /* figure out what local addresses are */
- local_range = readl(devpriv->plx9080_iobase + PLX_REG_LAS0RR) &
- PLX_LASRR_MEM_MASK;
- local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS0BA) &
- local_range & PLX_LASBA_MEM_MASK;
- devpriv->local0_iobase = ((u32)devpriv->main_phys_iobase &
- ~local_range) | local_decode;
- local_range = readl(devpriv->plx9080_iobase + PLX_REG_LAS1RR) &
- PLX_LASRR_MEM_MASK;
- local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS1BA) &
- local_range & PLX_LASBA_MEM_MASK;
- devpriv->local1_iobase = ((u32)devpriv->dio_counter_phys_iobase &
- ~local_range) | local_decode;
-
- retval = alloc_and_init_dma_members(dev);
- if (retval < 0)
- return retval;
-
- devpriv->hw_revision =
- hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG));
- dev_dbg(dev->class_dev, "stc hardware revision %i\n",
- devpriv->hw_revision);
- init_plx9080(dev);
- init_stc_registers(dev);
-
- retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
- "cb_pcidas64", dev);
- if (retval) {
- dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
- pcidev->irq);
- return retval;
- }
- dev->irq = pcidev->irq;
- dev_dbg(dev->class_dev, "irq %u\n", dev->irq);
-
- retval = setup_subdevices(dev);
- if (retval < 0)
- return retval;
-
- return 0;
-}
-
-static void detach(struct comedi_device *dev)
-{
- struct pcidas64_private *devpriv = dev->private;
-
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (devpriv) {
- if (devpriv->plx9080_iobase) {
- disable_plx_interrupts(dev);
- iounmap(devpriv->plx9080_iobase);
- }
- if (devpriv->main_iobase)
- iounmap(devpriv->main_iobase);
- if (dev->mmio)
- iounmap(dev->mmio);
- }
- comedi_pci_disable(dev);
- cb_pcidas64_free_dma(dev);
-}
-
-static struct comedi_driver cb_pcidas64_driver = {
- .driver_name = "cb_pcidas64",
- .module = THIS_MODULE,
- .auto_attach = auto_attach,
- .detach = detach,
-};
-
-static int cb_pcidas64_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &cb_pcidas64_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id cb_pcidas64_pci_table[] = {
- { PCI_VDEVICE(CB, 0x001d), BOARD_PCIDAS6402_16 },
- { PCI_VDEVICE(CB, 0x001e), BOARD_PCIDAS6402_12 },
- { PCI_VDEVICE(CB, 0x0035), BOARD_PCIDAS64_M1_16 },
- { PCI_VDEVICE(CB, 0x0036), BOARD_PCIDAS64_M2_16 },
- { PCI_VDEVICE(CB, 0x0037), BOARD_PCIDAS64_M3_16 },
- { PCI_VDEVICE(CB, 0x0052), BOARD_PCIDAS4020_12 },
- { PCI_VDEVICE(CB, 0x005d), BOARD_PCIDAS6023 },
- { PCI_VDEVICE(CB, 0x005e), BOARD_PCIDAS6025 },
- { PCI_VDEVICE(CB, 0x005f), BOARD_PCIDAS6030 },
- { PCI_VDEVICE(CB, 0x0060), BOARD_PCIDAS6031 },
- { PCI_VDEVICE(CB, 0x0061), BOARD_PCIDAS6032 },
- { PCI_VDEVICE(CB, 0x0062), BOARD_PCIDAS6033 },
- { PCI_VDEVICE(CB, 0x0063), BOARD_PCIDAS6034 },
- { PCI_VDEVICE(CB, 0x0064), BOARD_PCIDAS6035 },
- { PCI_VDEVICE(CB, 0x0065), BOARD_PCIDAS6040 },
- { PCI_VDEVICE(CB, 0x0066), BOARD_PCIDAS6052 },
- { PCI_VDEVICE(CB, 0x0067), BOARD_PCIDAS6070 },
- { PCI_VDEVICE(CB, 0x0068), BOARD_PCIDAS6071 },
- { PCI_VDEVICE(CB, 0x006f), BOARD_PCIDAS6036 },
- { PCI_VDEVICE(CB, 0x0078), BOARD_PCIDAS6013 },
- { PCI_VDEVICE(CB, 0x0079), BOARD_PCIDAS6014 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table);
-
-static struct pci_driver cb_pcidas64_pci_driver = {
- .name = "cb_pcidas64",
- .id_table = cb_pcidas64_pci_table,
- .probe = cb_pcidas64_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(cb_pcidas64_driver, cb_pcidas64_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
deleted file mode 100644
index 78cf1603638c..000000000000
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ /dev/null
@@ -1,421 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/cb_pcidda.c
- * Driver for the ComputerBoards / MeasurementComputing PCI-DDA series.
- *
- * Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
- * Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: cb_pcidda
- * Description: MeasurementComputing PCI-DDA series
- * Devices: [Measurement Computing] PCI-DDA08/12 (pci-dda08/12),
- * PCI-DDA04/12 (pci-dda04/12), PCI-DDA02/12 (pci-dda02/12),
- * PCI-DDA08/16 (pci-dda08/16), PCI-DDA04/16 (pci-dda04/16),
- * PCI-DDA02/16 (pci-dda02/16)
- * Author: Ivan Martinez <ivanmr@altavista.com>
- * Frank Mori Hess <fmhess@users.sourceforge.net>
- * Status: works
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * Only simple analog output writing is supported.
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-#include "8255.h"
-
-#define EEPROM_SIZE 128 /* number of entries in eeprom */
-/* maximum number of ao channels for supported boards */
-#define MAX_AO_CHANNELS 8
-
-/* Digital I/O registers */
-#define CB_DDA_DIO0_8255_BASE 0x00
-#define CB_DDA_DIO1_8255_BASE 0x04
-
-/* DAC registers */
-#define CB_DDA_DA_CTRL_REG 0x00 /* D/A Control Register */
-#define CB_DDA_DA_CTRL_SU BIT(0) /* Simultaneous update */
-#define CB_DDA_DA_CTRL_EN BIT(1) /* Enable specified DAC */
-#define CB_DDA_DA_CTRL_DAC(x) ((x) << 2) /* Specify DAC channel */
-#define CB_DDA_DA_CTRL_RANGE2V5 (0 << 6) /* 2.5V range */
-#define CB_DDA_DA_CTRL_RANGE5V (2 << 6) /* 5V range */
-#define CB_DDA_DA_CTRL_RANGE10V (3 << 6) /* 10V range */
-#define CB_DDA_DA_CTRL_UNIP BIT(8) /* Unipolar range */
-
-#define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */
-/* write bits */
-/* serial data input for eeprom, caldacs, reference dac */
-#define SERIAL_IN_BIT 0x1
-#define CAL_CHANNEL_MASK (0x7 << 1)
-#define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK)
-/* read bits */
-#define CAL_COUNTER_MASK 0x1f
-/* calibration counter overflow status bit */
-#define CAL_COUNTER_OVERFLOW_BIT 0x20
-/* analog output is less than reference dac voltage */
-#define AO_BELOW_REF_BIT 0x40
-#define SERIAL_OUT_BIT 0x80 /* serial data out, for reading from eeprom */
-
-#define DACALIBRATION2 6 /* D/A CALIBRATION REGISTER 2 */
-#define SELECT_EEPROM_BIT 0x1 /* send serial data in to eeprom */
-/* don't send serial data to MAX542 reference dac */
-#define DESELECT_REF_DAC_BIT 0x2
-/* don't send serial data to caldac n */
-#define DESELECT_CALDAC_BIT(n) (0x4 << (n))
-/* manual says to set this bit with no explanation */
-#define DUMMY_BIT 0x40
-
-#define CB_DDA_DA_DATA_REG(x) (0x08 + ((x) * 2))
-
-/* Offsets for the caldac channels */
-#define CB_DDA_CALDAC_FINE_GAIN 0
-#define CB_DDA_CALDAC_COURSE_GAIN 1
-#define CB_DDA_CALDAC_COURSE_OFFSET 2
-#define CB_DDA_CALDAC_FINE_OFFSET 3
-
-static const struct comedi_lrange cb_pcidda_ranges = {
- 6, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5)
- }
-};
-
-enum cb_pcidda_boardid {
- BOARD_DDA02_12,
- BOARD_DDA04_12,
- BOARD_DDA08_12,
- BOARD_DDA02_16,
- BOARD_DDA04_16,
- BOARD_DDA08_16,
-};
-
-struct cb_pcidda_board {
- const char *name;
- int ao_chans;
- int ao_bits;
-};
-
-static const struct cb_pcidda_board cb_pcidda_boards[] = {
- [BOARD_DDA02_12] = {
- .name = "pci-dda02/12",
- .ao_chans = 2,
- .ao_bits = 12,
- },
- [BOARD_DDA04_12] = {
- .name = "pci-dda04/12",
- .ao_chans = 4,
- .ao_bits = 12,
- },
- [BOARD_DDA08_12] = {
- .name = "pci-dda08/12",
- .ao_chans = 8,
- .ao_bits = 12,
- },
- [BOARD_DDA02_16] = {
- .name = "pci-dda02/16",
- .ao_chans = 2,
- .ao_bits = 16,
- },
- [BOARD_DDA04_16] = {
- .name = "pci-dda04/16",
- .ao_chans = 4,
- .ao_bits = 16,
- },
- [BOARD_DDA08_16] = {
- .name = "pci-dda08/16",
- .ao_chans = 8,
- .ao_bits = 16,
- },
-};
-
-struct cb_pcidda_private {
- unsigned long daqio;
- /* bits last written to da calibration register 1 */
- unsigned int dac_cal1_bits;
- /* current range settings for output channels */
- unsigned int ao_range[MAX_AO_CHANNELS];
- u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */
-};
-
-/* lowlevel read from eeprom */
-static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
-{
- struct cb_pcidda_private *devpriv = dev->private;
- unsigned int value = 0;
- int i;
- const int value_width = 16; /* number of bits wide values are */
-
- for (i = 1; i <= value_width; i++) {
- /* read bits most significant bit first */
- if (inw_p(devpriv->daqio + DACALIBRATION1) & SERIAL_OUT_BIT)
- value |= 1 << (value_width - i);
- }
-
- return value;
-}
-
-/* lowlevel write to eeprom/dac */
-static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
- unsigned int num_bits)
-{
- struct cb_pcidda_private *devpriv = dev->private;
- int i;
-
- for (i = 1; i <= num_bits; i++) {
- /* send bits most significant bit first */
- if (value & (1 << (num_bits - i)))
- devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
- else
- devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
- outw_p(devpriv->dac_cal1_bits, devpriv->daqio + DACALIBRATION1);
- }
-}
-
-/* reads a 16 bit value from board's eeprom */
-static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
- unsigned int address)
-{
- struct cb_pcidda_private *devpriv = dev->private;
- unsigned int i;
- unsigned int cal2_bits;
- unsigned int value;
- /* one caldac for every two dac channels */
- const int max_num_caldacs = 4;
- /* bits to send to tell eeprom we want to read */
- const int read_instruction = 0x6;
- const int instruction_length = 3;
- const int address_length = 8;
-
- /* send serial output stream to eeprom */
- cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
- /* deactivate caldacs (one caldac for every two channels) */
- for (i = 0; i < max_num_caldacs; i++)
- cal2_bits |= DESELECT_CALDAC_BIT(i);
- outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2);
-
- /* tell eeprom we want to read */
- cb_pcidda_serial_out(dev, read_instruction, instruction_length);
- /* send address we want to read from */
- cb_pcidda_serial_out(dev, address, address_length);
-
- value = cb_pcidda_serial_in(dev);
-
- /* deactivate eeprom */
- cal2_bits &= ~SELECT_EEPROM_BIT;
- outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2);
-
- return value;
-}
-
-/* writes to 8 bit calibration dacs */
-static void cb_pcidda_write_caldac(struct comedi_device *dev,
- unsigned int caldac, unsigned int channel,
- unsigned int value)
-{
- struct cb_pcidda_private *devpriv = dev->private;
- unsigned int cal2_bits;
- unsigned int i;
- /* caldacs use 3 bit channel specification */
- const int num_channel_bits = 3;
- const int num_caldac_bits = 8; /* 8 bit calibration dacs */
- /* one caldac for every two dac channels */
- const int max_num_caldacs = 4;
-
- /* write 3 bit channel */
- cb_pcidda_serial_out(dev, channel, num_channel_bits);
- /* write 8 bit caldac value */
- cb_pcidda_serial_out(dev, value, num_caldac_bits);
-
-/*
- * latch stream into appropriate caldac deselect reference dac
- */
- cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
- /* deactivate caldacs (one caldac for every two channels) */
- for (i = 0; i < max_num_caldacs; i++)
- cal2_bits |= DESELECT_CALDAC_BIT(i);
- /* activate the caldac we want */
- cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
- outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2);
- /* deactivate caldac */
- cal2_bits |= DESELECT_CALDAC_BIT(caldac);
- outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2);
-}
-
-/* set caldacs to eeprom values for given channel and range */
-static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
- unsigned int range)
-{
- struct cb_pcidda_private *devpriv = dev->private;
- unsigned int caldac = channel / 2; /* two caldacs per channel */
- unsigned int chan = 4 * (channel % 2); /* caldac channel base */
- unsigned int index = 2 * range + 12 * channel;
- unsigned int offset;
- unsigned int gain;
-
- /* save range so we can tell when we need to readjust calibration */
- devpriv->ao_range[channel] = range;
-
- /* get values from eeprom data */
- offset = devpriv->eeprom_data[0x7 + index];
- gain = devpriv->eeprom_data[0x8 + index];
-
- /* set caldacs */
- cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_COURSE_OFFSET,
- (offset >> 8) & 0xff);
- cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_FINE_OFFSET,
- offset & 0xff);
- cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_COURSE_GAIN,
- (gain >> 8) & 0xff);
- cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_FINE_GAIN,
- gain & 0xff);
-}
-
-static int cb_pcidda_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcidda_private *devpriv = dev->private;
- unsigned int channel = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int ctrl;
- unsigned int i;
-
- if (range != devpriv->ao_range[channel])
- cb_pcidda_calibrate(dev, channel, range);
-
- ctrl = CB_DDA_DA_CTRL_EN | CB_DDA_DA_CTRL_DAC(channel);
-
- switch (range) {
- case 0:
- case 3:
- ctrl |= CB_DDA_DA_CTRL_RANGE10V;
- break;
- case 1:
- case 4:
- ctrl |= CB_DDA_DA_CTRL_RANGE5V;
- break;
- case 2:
- case 5:
- ctrl |= CB_DDA_DA_CTRL_RANGE2V5;
- break;
- }
-
- if (range > 2)
- ctrl |= CB_DDA_DA_CTRL_UNIP;
-
- outw(ctrl, devpriv->daqio + CB_DDA_DA_CTRL_REG);
-
- for (i = 0; i < insn->n; i++)
- outw(data[i], devpriv->daqio + CB_DDA_DA_DATA_REG(channel));
-
- return insn->n;
-}
-
-static int cb_pcidda_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct cb_pcidda_board *board = NULL;
- struct cb_pcidda_private *devpriv;
- struct comedi_subdevice *s;
- int i;
- int ret;
-
- if (context < ARRAY_SIZE(cb_pcidda_boards))
- board = &cb_pcidda_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
- devpriv->daqio = pci_resource_start(pcidev, 3);
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->ao_chans;
- s->maxdata = (1 << board->ao_bits) - 1;
- s->range_table = &cb_pcidda_ranges;
- s->insn_write = cb_pcidda_ao_insn_write;
-
- /* two 8255 digital io subdevices */
- for (i = 0; i < 2; i++) {
- s = &dev->subdevices[1 + i];
- ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
- if (ret)
- return ret;
- }
-
- /* Read the caldac eeprom data */
- for (i = 0; i < EEPROM_SIZE; i++)
- devpriv->eeprom_data[i] = cb_pcidda_read_eeprom(dev, i);
-
- /* set calibrations dacs */
- for (i = 0; i < board->ao_chans; i++)
- cb_pcidda_calibrate(dev, i, devpriv->ao_range[i]);
-
- return 0;
-}
-
-static struct comedi_driver cb_pcidda_driver = {
- .driver_name = "cb_pcidda",
- .module = THIS_MODULE,
- .auto_attach = cb_pcidda_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int cb_pcidda_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &cb_pcidda_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id cb_pcidda_pci_table[] = {
- { PCI_VDEVICE(CB, 0x0020), BOARD_DDA02_12 },
- { PCI_VDEVICE(CB, 0x0021), BOARD_DDA04_12 },
- { PCI_VDEVICE(CB, 0x0022), BOARD_DDA08_12 },
- { PCI_VDEVICE(CB, 0x0023), BOARD_DDA02_16 },
- { PCI_VDEVICE(CB, 0x0024), BOARD_DDA04_16 },
- { PCI_VDEVICE(CB, 0x0025), BOARD_DDA08_16 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
-
-static struct pci_driver cb_pcidda_pci_driver = {
- .name = "cb_pcidda",
- .id_table = cb_pcidda_pci_table,
- .probe = cb_pcidda_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
deleted file mode 100644
index 2292f69da4f4..000000000000
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ /dev/null
@@ -1,475 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/cb_pcimdas.c
- * Comedi driver for Computer Boards PCIM-DAS1602/16 and PCIe-DAS1602/16
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: cb_pcimdas
- * Description: Measurement Computing PCI Migration series boards
- * Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas), PCIe-DAS1602/16
- * Author: Richard Bytheway
- * Updated: Mon, 13 Oct 2014 11:57:39 +0000
- * Status: experimental
- *
- * Written to support the PCIM-DAS1602/16 and PCIe-DAS1602/16.
- *
- * Configuration Options:
- * none
- *
- * Manual configuration of PCI(e) cards is not supported; they are configured
- * automatically.
- *
- * Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org).
- * Only supports DIO, AO and simple AI in it's present form.
- * No interrupts, multi channel or FIFO AI,
- * although the card looks like it could support this.
- *
- * https://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf
- * https://www.mccdaq.com/PDFs/Manuals/pcie-das1602-16.pdf
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "comedi_8254.h"
-#include "plx9052.h"
-#include "8255.h"
-
-/*
- * PCI Bar 1 Register map
- * see plx9052.h for register and bit defines
- */
-
-/*
- * PCI Bar 2 Register map (devpriv->daqio)
- */
-#define PCIMDAS_AI_REG 0x00
-#define PCIMDAS_AI_SOFTTRIG_REG 0x00
-#define PCIMDAS_AO_REG(x) (0x02 + ((x) * 2))
-
-/*
- * PCI Bar 3 Register map (devpriv->BADR3)
- */
-#define PCIMDAS_MUX_REG 0x00
-#define PCIMDAS_MUX(_lo, _hi) ((_lo) | ((_hi) << 4))
-#define PCIMDAS_DI_DO_REG 0x01
-#define PCIMDAS_STATUS_REG 0x02
-#define PCIMDAS_STATUS_EOC BIT(7)
-#define PCIMDAS_STATUS_UB BIT(6)
-#define PCIMDAS_STATUS_MUX BIT(5)
-#define PCIMDAS_STATUS_CLK BIT(4)
-#define PCIMDAS_STATUS_TO_CURR_MUX(x) ((x) & 0xf)
-#define PCIMDAS_CONV_STATUS_REG 0x03
-#define PCIMDAS_CONV_STATUS_EOC BIT(7)
-#define PCIMDAS_CONV_STATUS_EOB BIT(6)
-#define PCIMDAS_CONV_STATUS_EOA BIT(5)
-#define PCIMDAS_CONV_STATUS_FNE BIT(4)
-#define PCIMDAS_CONV_STATUS_FHF BIT(3)
-#define PCIMDAS_CONV_STATUS_OVERRUN BIT(2)
-#define PCIMDAS_IRQ_REG 0x04
-#define PCIMDAS_IRQ_INTE BIT(7)
-#define PCIMDAS_IRQ_INT BIT(6)
-#define PCIMDAS_IRQ_OVERRUN BIT(4)
-#define PCIMDAS_IRQ_EOA BIT(3)
-#define PCIMDAS_IRQ_EOA_INT_SEL BIT(2)
-#define PCIMDAS_IRQ_INTSEL(x) ((x) << 0)
-#define PCIMDAS_IRQ_INTSEL_EOC PCIMDAS_IRQ_INTSEL(0)
-#define PCIMDAS_IRQ_INTSEL_FNE PCIMDAS_IRQ_INTSEL(1)
-#define PCIMDAS_IRQ_INTSEL_EOB PCIMDAS_IRQ_INTSEL(2)
-#define PCIMDAS_IRQ_INTSEL_FHF_EOA PCIMDAS_IRQ_INTSEL(3)
-#define PCIMDAS_PACER_REG 0x05
-#define PCIMDAS_PACER_GATE_STATUS BIT(6)
-#define PCIMDAS_PACER_GATE_POL BIT(5)
-#define PCIMDAS_PACER_GATE_LATCH BIT(4)
-#define PCIMDAS_PACER_GATE_EN BIT(3)
-#define PCIMDAS_PACER_EXT_PACER_POL BIT(2)
-#define PCIMDAS_PACER_SRC(x) ((x) << 0)
-#define PCIMDAS_PACER_SRC_POLLED PCIMDAS_PACER_SRC(0)
-#define PCIMDAS_PACER_SRC_EXT PCIMDAS_PACER_SRC(2)
-#define PCIMDAS_PACER_SRC_INT PCIMDAS_PACER_SRC(3)
-#define PCIMDAS_PACER_SRC_MASK (3 << 0)
-#define PCIMDAS_BURST_REG 0x06
-#define PCIMDAS_BURST_BME BIT(1)
-#define PCIMDAS_BURST_CONV_EN BIT(0)
-#define PCIMDAS_GAIN_REG 0x07
-#define PCIMDAS_8254_BASE 0x08
-#define PCIMDAS_USER_CNTR_REG 0x0c
-#define PCIMDAS_USER_CNTR_CTR1_CLK_SEL BIT(0)
-#define PCIMDAS_RESIDUE_MSB_REG 0x0d
-#define PCIMDAS_RESIDUE_LSB_REG 0x0e
-
-/*
- * PCI Bar 4 Register map (dev->iobase)
- */
-#define PCIMDAS_8255_BASE 0x00
-
-static const struct comedi_lrange cb_pcimdas_ai_bip_range = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange cb_pcimdas_ai_uni_range = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-/*
- * The Analog Output range is not programmable. The DAC ranges are
- * jumper-settable on the board. The settings are not software-readable.
- */
-static const struct comedi_lrange cb_pcimdas_ao_range = {
- 6, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- UNI_RANGE(10),
- UNI_RANGE(5),
- RANGE_ext(-1, 1),
- RANGE_ext(0, 1)
- }
-};
-
-/*
- * this structure is for data unique to this hardware driver. If
- * several hardware drivers keep similar information in this structure,
- * feel free to suggest moving the variable to the struct comedi_device
- * struct.
- */
-struct cb_pcimdas_private {
- /* base addresses */
- unsigned long daqio;
- unsigned long BADR3;
-};
-
-static int cb_pcimdas_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int status;
-
- status = inb(devpriv->BADR3 + PCIMDAS_STATUS_REG);
- if ((status & PCIMDAS_STATUS_EOC) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int cb_pcimdas_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int n;
- unsigned int d;
- int ret;
-
- /* only support sw initiated reads from a single channel */
-
- /* configure for sw initiated read */
- d = inb(devpriv->BADR3 + PCIMDAS_PACER_REG);
- if ((d & PCIMDAS_PACER_SRC_MASK) != PCIMDAS_PACER_SRC_POLLED) {
- d &= ~PCIMDAS_PACER_SRC_MASK;
- d |= PCIMDAS_PACER_SRC_POLLED;
- outb(d, devpriv->BADR3 + PCIMDAS_PACER_REG);
- }
-
- /* set bursting off, conversions on */
- outb(PCIMDAS_BURST_CONV_EN, devpriv->BADR3 + PCIMDAS_BURST_REG);
-
- /* set range */
- outb(range, devpriv->BADR3 + PCIMDAS_GAIN_REG);
-
- /* set mux for single channel scan */
- outb(PCIMDAS_MUX(chan, chan), devpriv->BADR3 + PCIMDAS_MUX_REG);
-
- /* convert n samples */
- for (n = 0; n < insn->n; n++) {
- /* trigger conversion */
- outw(0, devpriv->daqio + PCIMDAS_AI_SOFTTRIG_REG);
-
- /* wait for conversion to end */
- ret = comedi_timeout(dev, s, insn, cb_pcimdas_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* read data */
- data[n] = inw(devpriv->daqio + PCIMDAS_AI_REG);
- }
-
- /* return the number of samples read/written */
- return n;
-}
-
-static int cb_pcimdas_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outw(val, devpriv->daqio + PCIMDAS_AO_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int cb_pcimdas_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int val;
-
- val = inb(devpriv->BADR3 + PCIMDAS_DI_DO_REG);
-
- data[1] = val & 0x0f;
-
- return insn->n;
-}
-
-static int cb_pcimdas_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
-
- if (comedi_dio_update_state(s, data))
- outb(s->state, devpriv->BADR3 + PCIMDAS_DI_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int cb_pcimdas_counter_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int ctrl;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_CLOCK_SRC:
- switch (data[1]) {
- case 0: /* internal 100 kHz clock */
- ctrl = PCIMDAS_USER_CNTR_CTR1_CLK_SEL;
- break;
- case 1: /* external clk on pin 21 */
- ctrl = 0;
- break;
- default:
- return -EINVAL;
- }
- outb(ctrl, devpriv->BADR3 + PCIMDAS_USER_CNTR_REG);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- ctrl = inb(devpriv->BADR3 + PCIMDAS_USER_CNTR_REG);
- if (ctrl & PCIMDAS_USER_CNTR_CTR1_CLK_SEL) {
- data[1] = 0;
- data[2] = I8254_OSC_BASE_100KHZ;
- } else {
- data[1] = 1;
- data[2] = 0;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static unsigned int cb_pcimdas_pacer_clk(struct comedi_device *dev)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int status;
-
- /* The Pacer Clock jumper selects a 10 MHz or 1 MHz clock */
- status = inb(devpriv->BADR3 + PCIMDAS_STATUS_REG);
- if (status & PCIMDAS_STATUS_CLK)
- return I8254_OSC_BASE_10MHZ;
- return I8254_OSC_BASE_1MHZ;
-}
-
-static bool cb_pcimdas_is_ai_se(struct comedi_device *dev)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int status;
-
- /*
- * The number of Analog Input channels is set with the
- * Analog Input Mode Switch on the board. The board can
- * have 16 single-ended or 8 differential channels.
- */
- status = inb(devpriv->BADR3 + PCIMDAS_STATUS_REG);
- return status & PCIMDAS_STATUS_MUX;
-}
-
-static bool cb_pcimdas_is_ai_uni(struct comedi_device *dev)
-{
- struct cb_pcimdas_private *devpriv = dev->private;
- unsigned int status;
-
- /*
- * The Analog Input range polarity is set with the
- * Analog Input Polarity Switch on the board. The
- * inputs can be set to Unipolar or Bipolar ranges.
- */
- status = inb(devpriv->BADR3 + PCIMDAS_STATUS_REG);
- return status & PCIMDAS_STATUS_UB;
-}
-
-static int cb_pcimdas_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct cb_pcimdas_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv->daqio = pci_resource_start(pcidev, 2);
- devpriv->BADR3 = pci_resource_start(pcidev, 3);
- dev->iobase = pci_resource_start(pcidev, 4);
-
- dev->pacer = comedi_8254_init(devpriv->BADR3 + PCIMDAS_8254_BASE,
- cb_pcimdas_pacer_clk(dev),
- I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 6);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE;
- if (cb_pcimdas_is_ai_se(dev)) {
- s->subdev_flags |= SDF_GROUND;
- s->n_chan = 16;
- } else {
- s->subdev_flags |= SDF_DIFF;
- s->n_chan = 8;
- }
- s->maxdata = 0xffff;
- s->range_table = cb_pcimdas_is_ai_uni(dev) ? &cb_pcimdas_ai_uni_range
- : &cb_pcimdas_ai_bip_range;
- s->insn_read = cb_pcimdas_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0xfff;
- s->range_table = &cb_pcimdas_ao_range;
- s->insn_write = cb_pcimdas_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- ret = subdev_8255_init(dev, s, NULL, PCIMDAS_8255_BASE);
- if (ret)
- return ret;
-
- /* Digital Input subdevice (main connector) */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = cb_pcimdas_di_insn_bits;
-
- /* Digital Output subdevice (main connector) */
- s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = cb_pcimdas_do_insn_bits;
-
- /* Counter subdevice (8254) */
- s = &dev->subdevices[5];
- comedi_8254_subdevice_init(s, dev->pacer);
-
- dev->pacer->insn_config = cb_pcimdas_counter_insn_config;
-
- /* counters 1 and 2 are used internally for the pacer */
- comedi_8254_set_busy(dev->pacer, 1, true);
- comedi_8254_set_busy(dev->pacer, 2, true);
-
- return 0;
-}
-
-static struct comedi_driver cb_pcimdas_driver = {
- .driver_name = "cb_pcimdas",
- .module = THIS_MODULE,
- .auto_attach = cb_pcimdas_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int cb_pcimdas_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &cb_pcimdas_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id cb_pcimdas_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, /* PCIM-DAS1602/16 */
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0115) }, /* PCIe-DAS1602/16 */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
-
-static struct pci_driver cb_pcimdas_pci_driver = {
- .name = "cb_pcimdas",
- .id_table = cb_pcimdas_pci_table,
- .probe = cb_pcimdas_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(cb_pcimdas_driver, cb_pcimdas_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for PCIM-DAS1602/16 and PCIe-DAS1602/16");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
deleted file mode 100644
index 21fc7b3c5f60..000000000000
--- a/drivers/staging/comedi/drivers/cb_pcimdda.c
+++ /dev/null
@@ -1,192 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/cb_pcimdda.c
- * Computer Boards PCIM-DDA06-16 Comedi driver
- * Author: Calin Culianu <calin@ajvar.org>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-/*
- * Driver: cb_pcimdda
- * Description: Measurement Computing PCIM-DDA06-16
- * Devices: [Measurement Computing] PCIM-DDA06-16 (cb_pcimdda)
- * Author: Calin Culianu <calin@ajvar.org>
- * Updated: Mon, 14 Apr 2008 15:15:51 +0100
- * Status: works
- *
- * All features of the PCIM-DDA06-16 board are supported.
- * This board has 6 16-bit AO channels, and the usual 8255 DIO setup.
- * (24 channels, configurable in banks of 8 and 4, etc.).
- * This board does not support commands.
- *
- * The board has a peculiar way of specifying AO gain/range settings -- You have
- * 1 jumper bank on the card, which either makes all 6 AO channels either
- * 5 Volt unipolar, 5V bipolar, 10 Volt unipolar or 10V bipolar.
- *
- * Since there is absolutely _no_ way to tell in software how this jumper is set
- * (well, at least according to the rather thin spec. from Measurement Computing
- * that comes with the board), the driver assumes the jumper is at its factory
- * default setting of +/-5V.
- *
- * Also of note is the fact that this board features another jumper, whose
- * state is also completely invisible to software. It toggles two possible AO
- * output modes on the board:
- *
- * - Update Mode: Writing to an AO channel instantaneously updates the actual
- * signal output by the DAC on the board (this is the factory default).
- * - Simultaneous XFER Mode: Writing to an AO channel has no effect until
- * you read from any one of the AO channels. This is useful for loading
- * all 6 AO values, and then reading from any one of the AO channels on the
- * device to instantly update all 6 AO values in unison. Useful for some
- * control apps, I would assume? If your jumper is in this setting, then you
- * need to issue your comedi_data_write()s to load all the values you want,
- * then issue one comedi_data_read() on any channel on the AO subdevice
- * to initiate the simultaneous XFER.
- *
- * Configuration Options: not applicable, uses PCI auto config
- */
-
-/*
- * This is a driver for the Computer Boards PCIM-DDA06-16 Analog Output
- * card. This board has a unique register layout and as such probably
- * deserves its own driver file.
- *
- * It is theoretically possible to integrate this board into the cb_pcidda
- * file, but since that isn't my code, I didn't want to significantly
- * modify that file to support this board (I thought it impolite to do so).
- *
- * At any rate, if you feel ambitious, please feel free to take
- * the code out of this file and combine it with a more unified driver
- * file.
- *
- * I would like to thank Timothy Curry <Timothy.Curry@rdec.redstone.army.mil>
- * for lending me a board so that I could write this driver.
- *
- * -Calin Culianu <calin@ajvar.org>
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-#include "8255.h"
-
-/* device ids of the cards we support -- currently only 1 card supported */
-#define PCI_ID_PCIM_DDA06_16 0x0053
-
-/*
- * Register map, 8-bit access only
- */
-#define PCIMDDA_DA_CHAN(x) (0x00 + (x) * 2)
-#define PCIMDDA_8255_BASE_REG 0x0c
-
-static int cb_pcimdda_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned long offset = dev->iobase + PCIMDDA_DA_CHAN(chan);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- /*
- * Write the LSB then MSB.
- *
- * If the simultaneous xfer mode is selected by the
- * jumper on the card, a read instruction is needed
- * in order to initiate the simultaneous transfer.
- * Otherwise, the DAC will be updated when the MSB
- * is written.
- */
- outb(val & 0x00ff, offset);
- outb((val >> 8) & 0x00ff, offset + 1);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int cb_pcimdda_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /* Initiate the simultaneous transfer */
- inw(dev->iobase + PCIMDDA_DA_CHAN(chan));
-
- return comedi_readback_insn_read(dev, s, insn, data);
-}
-
-static int cb_pcimdda_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 3);
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 6;
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar5;
- s->insn_write = cb_pcimdda_ao_insn_write;
- s->insn_read = cb_pcimdda_ao_insn_read;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s = &dev->subdevices[1];
- /* digital i/o subdevice */
- return subdev_8255_init(dev, s, NULL, PCIMDDA_8255_BASE_REG);
-}
-
-static struct comedi_driver cb_pcimdda_driver = {
- .driver_name = "cb_pcimdda",
- .module = THIS_MODULE,
- .auto_attach = cb_pcimdda_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int cb_pcimdda_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &cb_pcimdda_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id cb_pcimdda_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_ID_PCIM_DDA06_16) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, cb_pcimdda_pci_table);
-
-static struct pci_driver cb_pcimdda_driver_pci_driver = {
- .name = "cb_pcimdda",
- .id_table = cb_pcimdda_pci_table,
- .probe = cb_pcimdda_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(cb_pcimdda_driver, cb_pcimdda_driver_pci_driver);
-
-MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
-MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA series. Currently only supports PCIM-DDA06-16 (which also happens to be the only board in this series. :) ) ");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_8254.c b/drivers/staging/comedi/drivers/comedi_8254.c
deleted file mode 100644
index d1d509e9add9..000000000000
--- a/drivers/staging/comedi/drivers/comedi_8254.c
+++ /dev/null
@@ -1,655 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_8254.c
- * Generic 8254 timer/counter support
- * Copyright (C) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Based on 8253.h and various subdevice implementations in comedi drivers.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Module: comedi_8254
- * Description: Generic 8254 timer/counter support
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Thu Jan 8 16:45:45 MST 2015
- * Status: works
- *
- * This module is not used directly by end-users. Rather, it is used by other
- * drivers to provide support for an 8254 Programmable Interval Timer. These
- * counters are typically used to generate the pacer clock used for data
- * acquisition. Some drivers also expose the counters for general purpose use.
- *
- * This module provides the following basic functions:
- *
- * comedi_8254_init() / comedi_8254_mm_init()
- * Initializes this module to access the 8254 registers. The _mm version
- * sets up the module for MMIO register access the other for PIO access.
- * The pointer returned from these functions is normally stored in the
- * comedi_device dev->pacer and will be freed by the comedi core during
- * the driver (*detach). If a driver has multiple 8254 devices, they need
- * to be stored in the drivers private data and freed when the driver is
- * detached.
- *
- * NOTE: The counters are reset by setting them to I8254_MODE0 as part of
- * this initialization.
- *
- * comedi_8254_set_mode()
- * Sets a counters operation mode:
- * I8254_MODE0 Interrupt on terminal count
- * I8254_MODE1 Hardware retriggerable one-shot
- * I8254_MODE2 Rate generator
- * I8254_MODE3 Square wave mode
- * I8254_MODE4 Software triggered strobe
- * I8254_MODE5 Hardware triggered strobe (retriggerable)
- *
- * In addition I8254_BCD and I8254_BINARY specify the counting mode:
- * I8254_BCD BCD counting
- * I8254_BINARY Binary counting
- *
- * comedi_8254_write()
- * Writes an initial value to a counter.
- *
- * The largest possible initial count is 0; this is equivalent to 2^16
- * for binary counting and 10^4 for BCD counting.
- *
- * NOTE: The counter does not stop when it reaches zero. In Mode 0, 1, 4,
- * and 5 the counter "wraps around" to the highest count, either 0xffff
- * for binary counting or 9999 for BCD counting, and continues counting.
- * Modes 2 and 3 are periodic; the counter reloads itself with the initial
- * count and continues counting from there.
- *
- * comedi_8254_read()
- * Reads the current value from a counter.
- *
- * comedi_8254_status()
- * Reads the status of a counter.
- *
- * comedi_8254_load()
- * Sets a counters operation mode and writes the initial value.
- *
- * Typically the pacer clock is created by cascading two of the 16-bit counters
- * to create a 32-bit rate generator (I8254_MODE2). These functions are
- * provided to handle the cascaded counters:
- *
- * comedi_8254_ns_to_timer()
- * Calculates the divisor value needed for a single counter to generate
- * ns timing.
- *
- * comedi_8254_cascade_ns_to_timer()
- * Calculates the two divisor values needed to the generate the pacer
- * clock (in ns).
- *
- * comedi_8254_update_divisors()
- * Transfers the intermediate divisor values to the current divisors.
- *
- * comedi_8254_pacer_enable()
- * Programs the mode of the cascaded counters and writes the current
- * divisor values.
- *
- * To expose the counters as a subdevice for general purpose use the following
- * functions a provided:
- *
- * comedi_8254_subdevice_init()
- * Initializes a comedi_subdevice to use the 8254 timer.
- *
- * comedi_8254_set_busy()
- * Internally flags a counter as "busy". This is done to protect the
- * counters that are used for the cascaded 32-bit pacer.
- *
- * The subdevice provides (*insn_read) and (*insn_write) operations to read
- * the current value and write an initial value to a counter. A (*insn_config)
- * operation is also provided to handle the following comedi instructions:
- *
- * INSN_CONFIG_SET_COUNTER_MODE calls comedi_8254_set_mode()
- * INSN_CONFIG_8254_READ_STATUS calls comedi_8254_status()
- *
- * The (*insn_config) member of comedi_8254 can be initialized by the external
- * driver to handle any additional instructions.
- *
- * NOTE: Gate control, clock routing, and any interrupt handling for the
- * counters is not handled by this module. These features are driver dependent.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include "../comedidev.h"
-
-#include "comedi_8254.h"
-
-static unsigned int __i8254_read(struct comedi_8254 *i8254, unsigned int reg)
-{
- unsigned int reg_offset = (reg * i8254->iosize) << i8254->regshift;
- unsigned int val;
-
- switch (i8254->iosize) {
- default:
- case I8254_IO8:
- if (i8254->mmio)
- val = readb(i8254->mmio + reg_offset);
- else
- val = inb(i8254->iobase + reg_offset);
- break;
- case I8254_IO16:
- if (i8254->mmio)
- val = readw(i8254->mmio + reg_offset);
- else
- val = inw(i8254->iobase + reg_offset);
- break;
- case I8254_IO32:
- if (i8254->mmio)
- val = readl(i8254->mmio + reg_offset);
- else
- val = inl(i8254->iobase + reg_offset);
- break;
- }
- return val & 0xff;
-}
-
-static void __i8254_write(struct comedi_8254 *i8254,
- unsigned int val, unsigned int reg)
-{
- unsigned int reg_offset = (reg * i8254->iosize) << i8254->regshift;
-
- switch (i8254->iosize) {
- default:
- case I8254_IO8:
- if (i8254->mmio)
- writeb(val, i8254->mmio + reg_offset);
- else
- outb(val, i8254->iobase + reg_offset);
- break;
- case I8254_IO16:
- if (i8254->mmio)
- writew(val, i8254->mmio + reg_offset);
- else
- outw(val, i8254->iobase + reg_offset);
- break;
- case I8254_IO32:
- if (i8254->mmio)
- writel(val, i8254->mmio + reg_offset);
- else
- outl(val, i8254->iobase + reg_offset);
- break;
- }
-}
-
-/**
- * comedi_8254_status - return the status of a counter
- * @i8254: comedi_8254 struct for the timer
- * @counter: the counter number
- */
-unsigned int comedi_8254_status(struct comedi_8254 *i8254, unsigned int counter)
-{
- unsigned int cmd;
-
- if (counter > 2)
- return 0;
-
- cmd = I8254_CTRL_READBACK_STATUS | I8254_CTRL_READBACK_SEL_CTR(counter);
- __i8254_write(i8254, cmd, I8254_CTRL_REG);
-
- return __i8254_read(i8254, counter);
-}
-EXPORT_SYMBOL_GPL(comedi_8254_status);
-
-/**
- * comedi_8254_read - read the current counter value
- * @i8254: comedi_8254 struct for the timer
- * @counter: the counter number
- */
-unsigned int comedi_8254_read(struct comedi_8254 *i8254, unsigned int counter)
-{
- unsigned int val;
-
- if (counter > 2)
- return 0;
-
- /* latch counter */
- __i8254_write(i8254, I8254_CTRL_SEL_CTR(counter) | I8254_CTRL_LATCH,
- I8254_CTRL_REG);
-
- /* read LSB then MSB */
- val = __i8254_read(i8254, counter);
- val |= (__i8254_read(i8254, counter) << 8);
-
- return val;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_read);
-
-/**
- * comedi_8254_write - load a 16-bit initial counter value
- * @i8254: comedi_8254 struct for the timer
- * @counter: the counter number
- * @val: the initial value
- */
-void comedi_8254_write(struct comedi_8254 *i8254,
- unsigned int counter, unsigned int val)
-{
- unsigned int byte;
-
- if (counter > 2)
- return;
- if (val > 0xffff)
- return;
-
- /* load LSB then MSB */
- byte = val & 0xff;
- __i8254_write(i8254, byte, counter);
- byte = (val >> 8) & 0xff;
- __i8254_write(i8254, byte, counter);
-}
-EXPORT_SYMBOL_GPL(comedi_8254_write);
-
-/**
- * comedi_8254_set_mode - set the mode of a counter
- * @i8254: comedi_8254 struct for the timer
- * @counter: the counter number
- * @mode: the I8254_MODEx and I8254_BCD|I8254_BINARY
- */
-int comedi_8254_set_mode(struct comedi_8254 *i8254, unsigned int counter,
- unsigned int mode)
-{
- unsigned int byte;
-
- if (counter > 2)
- return -EINVAL;
- if (mode > (I8254_MODE5 | I8254_BCD))
- return -EINVAL;
-
- byte = I8254_CTRL_SEL_CTR(counter) | /* select counter */
- I8254_CTRL_LSB_MSB | /* load LSB then MSB */
- mode; /* mode and BCD|binary */
- __i8254_write(i8254, byte, I8254_CTRL_REG);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_set_mode);
-
-/**
- * comedi_8254_load - program the mode and initial count of a counter
- * @i8254: comedi_8254 struct for the timer
- * @counter: the counter number
- * @mode: the I8254_MODEx and I8254_BCD|I8254_BINARY
- * @val: the initial value
- */
-int comedi_8254_load(struct comedi_8254 *i8254, unsigned int counter,
- unsigned int val, unsigned int mode)
-{
- if (counter > 2)
- return -EINVAL;
- if (val > 0xffff)
- return -EINVAL;
- if (mode > (I8254_MODE5 | I8254_BCD))
- return -EINVAL;
-
- comedi_8254_set_mode(i8254, counter, mode);
- comedi_8254_write(i8254, counter, val);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_load);
-
-/**
- * comedi_8254_pacer_enable - set the mode and load the cascaded counters
- * @i8254: comedi_8254 struct for the timer
- * @counter1: the counter number for the first divisor
- * @counter2: the counter number for the second divisor
- * @enable: flag to enable (load) the counters
- */
-void comedi_8254_pacer_enable(struct comedi_8254 *i8254,
- unsigned int counter1,
- unsigned int counter2,
- bool enable)
-{
- unsigned int mode;
-
- if (counter1 > 2 || counter2 > 2 || counter1 == counter2)
- return;
-
- if (enable)
- mode = I8254_MODE2 | I8254_BINARY;
- else
- mode = I8254_MODE0 | I8254_BINARY;
-
- comedi_8254_set_mode(i8254, counter1, mode);
- comedi_8254_set_mode(i8254, counter2, mode);
-
- if (enable) {
- /*
- * Divisors are loaded second counter then first counter to
- * avoid possible issues with the first counter expiring
- * before the second counter is loaded.
- */
- comedi_8254_write(i8254, counter2, i8254->divisor2);
- comedi_8254_write(i8254, counter1, i8254->divisor1);
- }
-}
-EXPORT_SYMBOL_GPL(comedi_8254_pacer_enable);
-
-/**
- * comedi_8254_update_divisors - update the divisors for the cascaded counters
- * @i8254: comedi_8254 struct for the timer
- */
-void comedi_8254_update_divisors(struct comedi_8254 *i8254)
-{
- /* masking is done since counter maps zero to 0x10000 */
- i8254->divisor = i8254->next_div & 0xffff;
- i8254->divisor1 = i8254->next_div1 & 0xffff;
- i8254->divisor2 = i8254->next_div2 & 0xffff;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_update_divisors);
-
-/**
- * comedi_8254_cascade_ns_to_timer - calculate the cascaded divisor values
- * @i8254: comedi_8254 struct for the timer
- * @nanosec: the desired ns time
- * @flags: comedi_cmd flags
- */
-void comedi_8254_cascade_ns_to_timer(struct comedi_8254 *i8254,
- unsigned int *nanosec,
- unsigned int flags)
-{
- unsigned int d1 = i8254->next_div1 ? i8254->next_div1 : I8254_MAX_COUNT;
- unsigned int d2 = i8254->next_div2 ? i8254->next_div2 : I8254_MAX_COUNT;
- unsigned int div = d1 * d2;
- unsigned int ns_lub = 0xffffffff;
- unsigned int ns_glb = 0;
- unsigned int d1_lub = 0;
- unsigned int d1_glb = 0;
- unsigned int d2_lub = 0;
- unsigned int d2_glb = 0;
- unsigned int start;
- unsigned int ns;
- unsigned int ns_low;
- unsigned int ns_high;
-
- /* exit early if everything is already correct */
- if (div * i8254->osc_base == *nanosec &&
- d1 > 1 && d1 <= I8254_MAX_COUNT &&
- d2 > 1 && d2 <= I8254_MAX_COUNT &&
- /* check for overflow */
- div > d1 && div > d2 &&
- div * i8254->osc_base > div &&
- div * i8254->osc_base > i8254->osc_base)
- return;
-
- div = *nanosec / i8254->osc_base;
- d2 = I8254_MAX_COUNT;
- start = div / d2;
- if (start < 2)
- start = 2;
- for (d1 = start; d1 <= div / d1 + 1 && d1 <= I8254_MAX_COUNT; d1++) {
- for (d2 = div / d1;
- d1 * d2 <= div + d1 + 1 && d2 <= I8254_MAX_COUNT; d2++) {
- ns = i8254->osc_base * d1 * d2;
- if (ns <= *nanosec && ns > ns_glb) {
- ns_glb = ns;
- d1_glb = d1;
- d2_glb = d2;
- }
- if (ns >= *nanosec && ns < ns_lub) {
- ns_lub = ns;
- d1_lub = d1;
- d2_lub = d2;
- }
- }
- }
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- ns_high = d1_lub * d2_lub * i8254->osc_base;
- ns_low = d1_glb * d2_glb * i8254->osc_base;
- if (ns_high - *nanosec < *nanosec - ns_low) {
- d1 = d1_lub;
- d2 = d2_lub;
- } else {
- d1 = d1_glb;
- d2 = d2_glb;
- }
- break;
- case CMDF_ROUND_UP:
- d1 = d1_lub;
- d2 = d2_lub;
- break;
- case CMDF_ROUND_DOWN:
- d1 = d1_glb;
- d2 = d2_glb;
- break;
- }
-
- *nanosec = d1 * d2 * i8254->osc_base;
- i8254->next_div1 = d1;
- i8254->next_div2 = d2;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_cascade_ns_to_timer);
-
-/**
- * comedi_8254_ns_to_timer - calculate the divisor value for nanosec timing
- * @i8254: comedi_8254 struct for the timer
- * @nanosec: the desired ns time
- * @flags: comedi_cmd flags
- */
-void comedi_8254_ns_to_timer(struct comedi_8254 *i8254,
- unsigned int *nanosec, unsigned int flags)
-{
- unsigned int divisor;
-
- switch (flags & CMDF_ROUND_MASK) {
- default:
- case CMDF_ROUND_NEAREST:
- divisor = DIV_ROUND_CLOSEST(*nanosec, i8254->osc_base);
- break;
- case CMDF_ROUND_UP:
- divisor = DIV_ROUND_UP(*nanosec, i8254->osc_base);
- break;
- case CMDF_ROUND_DOWN:
- divisor = *nanosec / i8254->osc_base;
- break;
- }
- if (divisor < 2)
- divisor = 2;
- if (divisor > I8254_MAX_COUNT)
- divisor = I8254_MAX_COUNT;
-
- *nanosec = divisor * i8254->osc_base;
- i8254->next_div = divisor;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_ns_to_timer);
-
-/**
- * comedi_8254_set_busy - set/clear the "busy" flag for a given counter
- * @i8254: comedi_8254 struct for the timer
- * @counter: the counter number
- * @busy: set/clear flag
- */
-void comedi_8254_set_busy(struct comedi_8254 *i8254,
- unsigned int counter, bool busy)
-{
- if (counter < 3)
- i8254->busy[counter] = busy;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_set_busy);
-
-static int comedi_8254_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct comedi_8254 *i8254 = s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- if (i8254->busy[chan])
- return -EBUSY;
-
- for (i = 0; i < insn->n; i++)
- data[i] = comedi_8254_read(i8254, chan);
-
- return insn->n;
-}
-
-static int comedi_8254_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct comedi_8254 *i8254 = s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- if (i8254->busy[chan])
- return -EBUSY;
-
- if (insn->n)
- comedi_8254_write(i8254, chan, data[insn->n - 1]);
-
- return insn->n;
-}
-
-static int comedi_8254_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct comedi_8254 *i8254 = s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret;
-
- if (i8254->busy[chan])
- return -EBUSY;
-
- switch (data[0]) {
- case INSN_CONFIG_RESET:
- ret = comedi_8254_set_mode(i8254, chan,
- I8254_MODE0 | I8254_BINARY);
- if (ret)
- return ret;
- break;
- case INSN_CONFIG_SET_COUNTER_MODE:
- ret = comedi_8254_set_mode(i8254, chan, data[1]);
- if (ret)
- return ret;
- break;
- case INSN_CONFIG_8254_READ_STATUS:
- data[1] = comedi_8254_status(i8254, chan);
- break;
- default:
- /*
- * If available, call the driver provided (*insn_config)
- * to handle any driver implemented instructions.
- */
- if (i8254->insn_config)
- return i8254->insn_config(dev, s, insn, data);
-
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-/**
- * comedi_8254_subdevice_init - initialize a comedi_subdevice for the 8254 timer
- * @s: comedi_subdevice struct
- */
-void comedi_8254_subdevice_init(struct comedi_subdevice *s,
- struct comedi_8254 *i8254)
-{
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 3;
- s->maxdata = 0xffff;
- s->range_table = &range_unknown;
- s->insn_read = comedi_8254_insn_read;
- s->insn_write = comedi_8254_insn_write;
- s->insn_config = comedi_8254_insn_config;
-
- s->private = i8254;
-}
-EXPORT_SYMBOL_GPL(comedi_8254_subdevice_init);
-
-static struct comedi_8254 *__i8254_init(unsigned long iobase,
- void __iomem *mmio,
- unsigned int osc_base,
- unsigned int iosize,
- unsigned int regshift)
-{
- struct comedi_8254 *i8254;
- int i;
-
- /* sanity check that the iosize is valid */
- if (!(iosize == I8254_IO8 || iosize == I8254_IO16 ||
- iosize == I8254_IO32))
- return NULL;
-
- i8254 = kzalloc(sizeof(*i8254), GFP_KERNEL);
- if (!i8254)
- return NULL;
-
- i8254->iobase = iobase;
- i8254->mmio = mmio;
- i8254->iosize = iosize;
- i8254->regshift = regshift;
-
- /* default osc_base to the max speed of a generic 8254 timer */
- i8254->osc_base = osc_base ? osc_base : I8254_OSC_BASE_10MHZ;
-
- /* reset all the counters by setting them to I8254_MODE0 */
- for (i = 0; i < 3; i++)
- comedi_8254_set_mode(i8254, i, I8254_MODE0 | I8254_BINARY);
-
- return i8254;
-}
-
-/**
- * comedi_8254_init - allocate and initialize the 8254 device for pio access
- * @mmio: port I/O base address
- * @osc_base: base time of the counter in ns
- * OPTIONAL - only used by comedi_8254_cascade_ns_to_timer()
- * @iosize: I/O register size
- * @regshift: register gap shift
- */
-struct comedi_8254 *comedi_8254_init(unsigned long iobase,
- unsigned int osc_base,
- unsigned int iosize,
- unsigned int regshift)
-{
- return __i8254_init(iobase, NULL, osc_base, iosize, regshift);
-}
-EXPORT_SYMBOL_GPL(comedi_8254_init);
-
-/**
- * comedi_8254_mm_init - allocate and initialize the 8254 device for mmio access
- * @mmio: memory mapped I/O base address
- * @osc_base: base time of the counter in ns
- * OPTIONAL - only used by comedi_8254_cascade_ns_to_timer()
- * @iosize: I/O register size
- * @regshift: register gap shift
- */
-struct comedi_8254 *comedi_8254_mm_init(void __iomem *mmio,
- unsigned int osc_base,
- unsigned int iosize,
- unsigned int regshift)
-{
- return __i8254_init(0, mmio, osc_base, iosize, regshift);
-}
-EXPORT_SYMBOL_GPL(comedi_8254_mm_init);
-
-static int __init comedi_8254_module_init(void)
-{
- return 0;
-}
-module_init(comedi_8254_module_init);
-
-static void __exit comedi_8254_module_exit(void)
-{
-}
-module_exit(comedi_8254_module_exit);
-
-MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_DESCRIPTION("Comedi: Generic 8254 timer/counter support");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_8254.h b/drivers/staging/comedi/drivers/comedi_8254.h
deleted file mode 100644
index d8264417e53c..000000000000
--- a/drivers/staging/comedi/drivers/comedi_8254.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedi_8254.h
- * Generic 8254 timer/counter support
- * Copyright (C) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _COMEDI_8254_H
-#define _COMEDI_8254_H
-
-#include <linux/types.h>
-
-struct comedi_device;
-struct comedi_insn;
-struct comedi_subdevice;
-
-/*
- * Common oscillator base values in nanoseconds
- */
-#define I8254_OSC_BASE_10MHZ 100
-#define I8254_OSC_BASE_5MHZ 200
-#define I8254_OSC_BASE_4MHZ 250
-#define I8254_OSC_BASE_2MHZ 500
-#define I8254_OSC_BASE_1MHZ 1000
-#define I8254_OSC_BASE_100KHZ 10000
-#define I8254_OSC_BASE_10KHZ 100000
-#define I8254_OSC_BASE_1KHZ 1000000
-
-/*
- * I/O access size used to read/write registers
- */
-#define I8254_IO8 1
-#define I8254_IO16 2
-#define I8254_IO32 4
-
-/*
- * Register map for generic 8254 timer (I8254_IO8 with 0 regshift)
- */
-#define I8254_COUNTER0_REG 0x00
-#define I8254_COUNTER1_REG 0x01
-#define I8254_COUNTER2_REG 0x02
-#define I8254_CTRL_REG 0x03
-#define I8254_CTRL_SEL_CTR(x) ((x) << 6)
-#define I8254_CTRL_READBACK(x) (I8254_CTRL_SEL_CTR(3) | BIT(x))
-#define I8254_CTRL_READBACK_COUNT I8254_CTRL_READBACK(4)
-#define I8254_CTRL_READBACK_STATUS I8254_CTRL_READBACK(5)
-#define I8254_CTRL_READBACK_SEL_CTR(x) (2 << (x))
-#define I8254_CTRL_RW(x) (((x) & 0x3) << 4)
-#define I8254_CTRL_LATCH I8254_CTRL_RW(0)
-#define I8254_CTRL_LSB_ONLY I8254_CTRL_RW(1)
-#define I8254_CTRL_MSB_ONLY I8254_CTRL_RW(2)
-#define I8254_CTRL_LSB_MSB I8254_CTRL_RW(3)
-
-/* counter maps zero to 0x10000 */
-#define I8254_MAX_COUNT 0x10000
-
-/**
- * struct comedi_8254 - private data used by this module
- * @iobase: PIO base address of the registers (in/out)
- * @mmio: MMIO base address of the registers (read/write)
- * @iosize: I/O size used to access the registers (b/w/l)
- * @regshift: register gap shift
- * @osc_base: cascaded oscillator speed in ns
- * @divisor: divisor for single counter
- * @divisor1: divisor loaded into first cascaded counter
- * @divisor2: divisor loaded into second cascaded counter
- * #next_div: next divisor for single counter
- * @next_div1: next divisor to use for first cascaded counter
- * @next_div2: next divisor to use for second cascaded counter
- * @clock_src; current clock source for each counter (driver specific)
- * @gate_src; current gate source for each counter (driver specific)
- * @busy: flags used to indicate that a counter is "busy"
- * @insn_config: driver specific (*insn_config) callback
- */
-struct comedi_8254 {
- unsigned long iobase;
- void __iomem *mmio;
- unsigned int iosize;
- unsigned int regshift;
- unsigned int osc_base;
- unsigned int divisor;
- unsigned int divisor1;
- unsigned int divisor2;
- unsigned int next_div;
- unsigned int next_div1;
- unsigned int next_div2;
- unsigned int clock_src[3];
- unsigned int gate_src[3];
- bool busy[3];
-
- int (*insn_config)(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-};
-
-unsigned int comedi_8254_status(struct comedi_8254 *i8254,
- unsigned int counter);
-unsigned int comedi_8254_read(struct comedi_8254 *i8254, unsigned int counter);
-void comedi_8254_write(struct comedi_8254 *i8254,
- unsigned int counter, unsigned int val);
-
-int comedi_8254_set_mode(struct comedi_8254 *i8254,
- unsigned int counter, unsigned int mode);
-int comedi_8254_load(struct comedi_8254 *i8254,
- unsigned int counter, unsigned int val, unsigned int mode);
-
-void comedi_8254_pacer_enable(struct comedi_8254 *i8254,
- unsigned int counter1, unsigned int counter2,
- bool enable);
-void comedi_8254_update_divisors(struct comedi_8254 *i8254);
-void comedi_8254_cascade_ns_to_timer(struct comedi_8254 *i8254,
- unsigned int *nanosec, unsigned int flags);
-void comedi_8254_ns_to_timer(struct comedi_8254 *i8254,
- unsigned int *nanosec, unsigned int flags);
-
-void comedi_8254_set_busy(struct comedi_8254 *i8254,
- unsigned int counter, bool busy);
-
-void comedi_8254_subdevice_init(struct comedi_subdevice *s,
- struct comedi_8254 *i8254);
-
-struct comedi_8254 *comedi_8254_init(unsigned long iobase,
- unsigned int osc_base,
- unsigned int iosize,
- unsigned int regshift);
-struct comedi_8254 *comedi_8254_mm_init(void __iomem *mmio,
- unsigned int osc_base,
- unsigned int iosize,
- unsigned int regshift);
-
-#endif /* _COMEDI_8254_H */
diff --git a/drivers/staging/comedi/drivers/comedi_8255.c b/drivers/staging/comedi/drivers/comedi_8255.c
deleted file mode 100644
index b7ca465933ee..000000000000
--- a/drivers/staging/comedi/drivers/comedi_8255.c
+++ /dev/null
@@ -1,276 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_8255.c
- * Generic 8255 digital I/O support
- *
- * Split from the Comedi "8255" driver module.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Module: comedi_8255
- * Description: Generic 8255 support
- * Author: ds
- * Updated: Fri, 22 May 2015 12:14:17 +0000
- * Status: works
- *
- * This module is not used directly by end-users. Rather, it is used by
- * other drivers to provide support for an 8255 "Programmable Peripheral
- * Interface" (PPI) chip.
- *
- * The classic in digital I/O. The 8255 appears in Comedi as a single
- * digital I/O subdevice with 24 channels. The channel 0 corresponds to
- * the 8255's port A, bit 0; channel 23 corresponds to port C, bit 7.
- * Direction configuration is done in blocks, with channels 0-7, 8-15,
- * 16-19, and 20-23 making up the 4 blocks. The only 8255 mode
- * supported is mode 0.
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include "8255.h"
-
-struct subdev_8255_private {
- unsigned long regbase;
- int (*io)(struct comedi_device *dev, int dir, int port, int data,
- unsigned long regbase);
-};
-
-static int subdev_8255_io(struct comedi_device *dev,
- int dir, int port, int data, unsigned long regbase)
-{
- if (dir) {
- outb(data, dev->iobase + regbase + port);
- return 0;
- }
- return inb(dev->iobase + regbase + port);
-}
-
-static int subdev_8255_mmio(struct comedi_device *dev,
- int dir, int port, int data, unsigned long regbase)
-{
- if (dir) {
- writeb(data, dev->mmio + regbase + port);
- return 0;
- }
- return readb(dev->mmio + regbase + port);
-}
-
-static int subdev_8255_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct subdev_8255_private *spriv = s->private;
- unsigned long regbase = spriv->regbase;
- unsigned int mask;
- unsigned int v;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0xff)
- spriv->io(dev, 1, I8255_DATA_A_REG,
- s->state & 0xff, regbase);
- if (mask & 0xff00)
- spriv->io(dev, 1, I8255_DATA_B_REG,
- (s->state >> 8) & 0xff, regbase);
- if (mask & 0xff0000)
- spriv->io(dev, 1, I8255_DATA_C_REG,
- (s->state >> 16) & 0xff, regbase);
- }
-
- v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, regbase);
- v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, regbase) << 8);
- v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, regbase) << 16);
-
- data[1] = v;
-
- return insn->n;
-}
-
-static void subdev_8255_do_config(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct subdev_8255_private *spriv = s->private;
- unsigned long regbase = spriv->regbase;
- int config;
-
- config = I8255_CTRL_CW;
- /* 1 in io_bits indicates output, 1 in config indicates input */
- if (!(s->io_bits & 0x0000ff))
- config |= I8255_CTRL_A_IO;
- if (!(s->io_bits & 0x00ff00))
- config |= I8255_CTRL_B_IO;
- if (!(s->io_bits & 0x0f0000))
- config |= I8255_CTRL_C_LO_IO;
- if (!(s->io_bits & 0xf00000))
- config |= I8255_CTRL_C_HI_IO;
-
- spriv->io(dev, 1, I8255_CTRL_REG, config, regbase);
-}
-
-static int subdev_8255_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x0000ff;
- else if (chan < 16)
- mask = 0x00ff00;
- else if (chan < 20)
- mask = 0x0f0000;
- else
- mask = 0xf00000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- subdev_8255_do_config(dev, s);
-
- return insn->n;
-}
-
-static int __subdev_8255_init(struct comedi_device *dev,
- struct comedi_subdevice *s,
- int (*io)(struct comedi_device *dev,
- int dir, int port, int data,
- unsigned long regbase),
- unsigned long regbase,
- bool is_mmio)
-{
- struct subdev_8255_private *spriv;
-
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
-
- if (io)
- spriv->io = io;
- else if (is_mmio)
- spriv->io = subdev_8255_mmio;
- else
- spriv->io = subdev_8255_io;
- spriv->regbase = regbase;
-
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = subdev_8255_insn;
- s->insn_config = subdev_8255_insn_config;
-
- subdev_8255_do_config(dev, s);
-
- return 0;
-}
-
-/**
- * subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255
- * @dev: comedi device owning subdevice
- * @s: comedi subdevice to initialize
- * @io: (optional) register I/O call-back function
- * @regbase: offset of 8255 registers from dev->iobase, or call-back context
- *
- * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
- *
- * If the optional I/O call-back function is provided, its prototype is of
- * the following form:
- *
- * int my_8255_callback(struct comedi_device *dev, int dir, int port,
- * int data, unsigned long regbase);
- *
- * where 'dev', and 'regbase' match the values passed to this function,
- * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
- * is the direction (0 for read, 1 for write) and 'data' is the value to be
- * written. It should return 0 if writing or the value read if reading.
- *
- * If the optional I/O call-back function is not provided, an internal
- * call-back function is used which uses consecutive I/O port addresses
- * starting at dev->iobase + regbase.
- *
- * Return: -ENOMEM if failed to allocate memory, zero on success.
- */
-int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
- int (*io)(struct comedi_device *dev, int dir, int port,
- int data, unsigned long regbase),
- unsigned long regbase)
-{
- return __subdev_8255_init(dev, s, io, regbase, false);
-}
-EXPORT_SYMBOL_GPL(subdev_8255_init);
-
-/**
- * subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255
- * @dev: comedi device owning subdevice
- * @s: comedi subdevice to initialize
- * @io: (optional) register I/O call-back function
- * @regbase: offset of 8255 registers from dev->mmio, or call-back context
- *
- * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
- *
- * If the optional I/O call-back function is provided, its prototype is of
- * the following form:
- *
- * int my_8255_callback(struct comedi_device *dev, int dir, int port,
- * int data, unsigned long regbase);
- *
- * where 'dev', and 'regbase' match the values passed to this function,
- * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
- * is the direction (0 for read, 1 for write) and 'data' is the value to be
- * written. It should return 0 if writing or the value read if reading.
- *
- * If the optional I/O call-back function is not provided, an internal
- * call-back function is used which uses consecutive MMIO virtual addresses
- * starting at dev->mmio + regbase.
- *
- * Return: -ENOMEM if failed to allocate memory, zero on success.
- */
-int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s,
- int (*io)(struct comedi_device *dev, int dir, int port,
- int data, unsigned long regbase),
- unsigned long regbase)
-{
- return __subdev_8255_init(dev, s, io, regbase, true);
-}
-EXPORT_SYMBOL_GPL(subdev_8255_mm_init);
-
-/**
- * subdev_8255_regbase - get offset of 8255 registers or call-back context
- * @s: comedi subdevice
- *
- * Returns the 'regbase' parameter that was previously passed to
- * subdev_8255_init() or subdev_8255_mm_init() to set up the subdevice.
- * Only valid if the subdevice was set up successfully.
- */
-unsigned long subdev_8255_regbase(struct comedi_subdevice *s)
-{
- struct subdev_8255_private *spriv = s->private;
-
- return spriv->regbase;
-}
-EXPORT_SYMBOL_GPL(subdev_8255_regbase);
-
-static int __init comedi_8255_module_init(void)
-{
- return 0;
-}
-module_init(comedi_8255_module_init);
-
-static void __exit comedi_8255_module_exit(void)
-{
-}
-module_exit(comedi_8255_module_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi: Generic 8255 digital I/O support");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
deleted file mode 100644
index 4392b5927a99..000000000000
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ /dev/null
@@ -1,347 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_bond.c
- * A Comedi driver to 'bond' or merge multiple drivers and devices as one.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2005 Calin A. Culianu <calin@ajvar.org>
- */
-
-/*
- * Driver: comedi_bond
- * Description: A driver to 'bond' (merge) multiple subdevices from multiple
- * devices together as one.
- * Devices:
- * Author: ds
- * Updated: Mon, 10 Oct 00:18:25 -0500
- * Status: works
- *
- * This driver allows you to 'bond' (merge) multiple comedi subdevices
- * (coming from possibly difference boards and/or drivers) together. For
- * example, if you had a board with 2 different DIO subdevices, and
- * another with 1 DIO subdevice, you could 'bond' them with this driver
- * so that they look like one big fat DIO subdevice. This makes writing
- * applications slightly easier as you don't have to worry about managing
- * different subdevices in the application -- you just worry about
- * indexing one linear array of channel id's.
- *
- * Right now only DIO subdevices are supported as that's the personal itch
- * I am scratching with this driver. If you want to add support for AI and AO
- * subdevs, go right on ahead and do so!
- *
- * Commands aren't supported -- although it would be cool if they were.
- *
- * Configuration Options:
- * List of comedi-minors to bond. All subdevices of the same type
- * within each minor will be concatenated together in the order given here.
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "../comedi.h"
-#include "../comedilib.h"
-#include "../comedidev.h"
-
-struct bonded_device {
- struct comedi_device *dev;
- unsigned int minor;
- unsigned int subdev;
- unsigned int nchans;
-};
-
-struct comedi_bond_private {
- char name[256];
- struct bonded_device **devs;
- unsigned int ndevs;
- unsigned int nchans;
-};
-
-static int bonding_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct comedi_bond_private *devpriv = dev->private;
- unsigned int n_left, n_done, base_chan;
- unsigned int write_mask, data_bits;
- struct bonded_device **devs;
-
- write_mask = data[0];
- data_bits = data[1];
- base_chan = CR_CHAN(insn->chanspec);
- /* do a maximum of 32 channels, starting from base_chan. */
- n_left = devpriv->nchans - base_chan;
- if (n_left > 32)
- n_left = 32;
-
- n_done = 0;
- devs = devpriv->devs;
- do {
- struct bonded_device *bdev = *devs++;
-
- if (base_chan < bdev->nchans) {
- /* base channel falls within bonded device */
- unsigned int b_chans, b_mask, b_write_mask, b_data_bits;
- int ret;
-
- /*
- * Get num channels to do for bonded device and set
- * up mask and data bits for bonded device.
- */
- b_chans = bdev->nchans - base_chan;
- if (b_chans > n_left)
- b_chans = n_left;
- b_mask = (b_chans < 32) ? ((1 << b_chans) - 1)
- : 0xffffffff;
- b_write_mask = (write_mask >> n_done) & b_mask;
- b_data_bits = (data_bits >> n_done) & b_mask;
- /* Read/Write the new digital lines. */
- ret = comedi_dio_bitfield2(bdev->dev, bdev->subdev,
- b_write_mask, &b_data_bits,
- base_chan);
- if (ret < 0)
- return ret;
- /* Place read bits into data[1]. */
- data[1] &= ~(b_mask << n_done);
- data[1] |= (b_data_bits & b_mask) << n_done;
- /*
- * Set up for following bonded device (if still have
- * channels to read/write).
- */
- base_chan = 0;
- n_done += b_chans;
- n_left -= b_chans;
- } else {
- /* Skip bonded devices before base channel. */
- base_chan -= bdev->nchans;
- }
- } while (n_left);
-
- return insn->n;
-}
-
-static int bonding_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct comedi_bond_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret;
- struct bonded_device *bdev;
- struct bonded_device **devs;
-
- /*
- * Locate bonded subdevice and adjust channel.
- */
- devs = devpriv->devs;
- for (bdev = *devs++; chan >= bdev->nchans; bdev = *devs++)
- chan -= bdev->nchans;
-
- /*
- * The input or output configuration of each digital line is
- * configured by a special insn_config instruction. chanspec
- * contains the channel to be changed, and data[0] contains the
- * configuration instruction INSN_CONFIG_DIO_OUTPUT,
- * INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_QUERY.
- *
- * Note that INSN_CONFIG_DIO_OUTPUT == COMEDI_OUTPUT,
- * and INSN_CONFIG_DIO_INPUT == COMEDI_INPUT. This is deliberate ;)
- */
- switch (data[0]) {
- case INSN_CONFIG_DIO_OUTPUT:
- case INSN_CONFIG_DIO_INPUT:
- ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, data[0]);
- break;
- case INSN_CONFIG_DIO_QUERY:
- ret = comedi_dio_get_config(bdev->dev, bdev->subdev, chan,
- &data[1]);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- if (ret >= 0)
- ret = insn->n;
- return ret;
-}
-
-static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct comedi_bond_private *devpriv = dev->private;
- DECLARE_BITMAP(devs_opened, COMEDI_NUM_BOARD_MINORS);
- int i;
-
- memset(&devs_opened, 0, sizeof(devs_opened));
- devpriv->name[0] = 0;
- /*
- * Loop through all comedi devices specified on the command-line,
- * building our device list.
- */
- for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) {
- char file[sizeof("/dev/comediXXXXXX")];
- int minor = it->options[i];
- struct comedi_device *d;
- int sdev = -1, nchans;
- struct bonded_device *bdev;
- struct bonded_device **devs;
-
- if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) {
- dev_err(dev->class_dev,
- "Minor %d is invalid!\n", minor);
- return -EINVAL;
- }
- if (minor == dev->minor) {
- dev_err(dev->class_dev,
- "Cannot bond this driver to itself!\n");
- return -EINVAL;
- }
- if (test_and_set_bit(minor, devs_opened)) {
- dev_err(dev->class_dev,
- "Minor %d specified more than once!\n", minor);
- return -EINVAL;
- }
-
- snprintf(file, sizeof(file), "/dev/comedi%d", minor);
- file[sizeof(file) - 1] = 0;
-
- d = comedi_open(file);
-
- if (!d) {
- dev_err(dev->class_dev,
- "Minor %u could not be opened\n", minor);
- return -ENODEV;
- }
-
- /* Do DIO, as that's all we support now.. */
- while ((sdev = comedi_find_subdevice_by_type(d, COMEDI_SUBD_DIO,
- sdev + 1)) > -1) {
- nchans = comedi_get_n_channels(d, sdev);
- if (nchans <= 0) {
- dev_err(dev->class_dev,
- "comedi_get_n_channels() returned %d on minor %u subdev %d!\n",
- nchans, minor, sdev);
- return -EINVAL;
- }
- bdev = kmalloc(sizeof(*bdev), GFP_KERNEL);
- if (!bdev)
- return -ENOMEM;
-
- bdev->dev = d;
- bdev->minor = minor;
- bdev->subdev = sdev;
- bdev->nchans = nchans;
- devpriv->nchans += nchans;
-
- /*
- * Now put bdev pointer at end of devpriv->devs array
- * list..
- */
-
- /* ergh.. ugly.. we need to realloc :( */
- devs = krealloc(devpriv->devs,
- (devpriv->ndevs + 1) * sizeof(*devs),
- GFP_KERNEL);
- if (!devs) {
- dev_err(dev->class_dev,
- "Could not allocate memory. Out of memory?\n");
- kfree(bdev);
- return -ENOMEM;
- }
- devpriv->devs = devs;
- devpriv->devs[devpriv->ndevs++] = bdev;
- {
- /* Append dev:subdev to devpriv->name */
- char buf[20];
-
- snprintf(buf, sizeof(buf), "%u:%u ",
- bdev->minor, bdev->subdev);
- strlcat(devpriv->name, buf,
- sizeof(devpriv->name));
- }
- }
- }
-
- if (!devpriv->nchans) {
- dev_err(dev->class_dev, "No channels found!\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int bonding_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_bond_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- /*
- * Setup our bonding from config params.. sets up our private struct..
- */
- ret = do_dev_config(dev, it);
- if (ret)
- return ret;
-
- dev->board_name = devpriv->name;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = devpriv->nchans;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = bonding_dio_insn_bits;
- s->insn_config = bonding_dio_insn_config;
-
- dev_info(dev->class_dev,
- "%s: %s attached, %u channels from %u devices\n",
- dev->driver->driver_name, dev->board_name,
- devpriv->nchans, devpriv->ndevs);
-
- return 0;
-}
-
-static void bonding_detach(struct comedi_device *dev)
-{
- struct comedi_bond_private *devpriv = dev->private;
-
- if (devpriv && devpriv->devs) {
- DECLARE_BITMAP(devs_closed, COMEDI_NUM_BOARD_MINORS);
-
- memset(&devs_closed, 0, sizeof(devs_closed));
- while (devpriv->ndevs--) {
- struct bonded_device *bdev;
-
- bdev = devpriv->devs[devpriv->ndevs];
- if (!bdev)
- continue;
- if (!test_and_set_bit(bdev->minor, devs_closed))
- comedi_close(bdev->dev);
- kfree(bdev);
- }
- kfree(devpriv->devs);
- devpriv->devs = NULL;
- }
-}
-
-static struct comedi_driver bonding_driver = {
- .driver_name = "comedi_bond",
- .module = THIS_MODULE,
- .attach = bonding_attach,
- .detach = bonding_detach,
-};
-module_comedi_driver(bonding_driver);
-
-MODULE_AUTHOR("Calin A. Culianu");
-MODULE_DESCRIPTION("comedi_bond: A driver for COMEDI to bond multiple COMEDI devices together as one.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.c b/drivers/staging/comedi/drivers/comedi_isadma.c
deleted file mode 100644
index c729094298c2..000000000000
--- a/drivers/staging/comedi/drivers/comedi_isadma.c
+++ /dev/null
@@ -1,267 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * COMEDI ISA DMA support functions
- * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <asm/dma.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-
-/**
- * comedi_isadma_program - program and enable an ISA DMA transfer
- * @desc: the ISA DMA cookie to program and enable
- */
-void comedi_isadma_program(struct comedi_isadma_desc *desc)
-{
- unsigned long flags;
-
- flags = claim_dma_lock();
- clear_dma_ff(desc->chan);
- set_dma_mode(desc->chan, desc->mode);
- set_dma_addr(desc->chan, desc->hw_addr);
- set_dma_count(desc->chan, desc->size);
- enable_dma(desc->chan);
- release_dma_lock(flags);
-}
-EXPORT_SYMBOL_GPL(comedi_isadma_program);
-
-/**
- * comedi_isadma_disable - disable the ISA DMA channel
- * @dma_chan: the DMA channel to disable
- *
- * Returns the residue (remaining bytes) left in the DMA transfer.
- */
-unsigned int comedi_isadma_disable(unsigned int dma_chan)
-{
- unsigned long flags;
- unsigned int residue;
-
- flags = claim_dma_lock();
- disable_dma(dma_chan);
- residue = get_dma_residue(dma_chan);
- release_dma_lock(flags);
-
- return residue;
-}
-EXPORT_SYMBOL_GPL(comedi_isadma_disable);
-
-/**
- * comedi_isadma_disable_on_sample - disable the ISA DMA channel
- * @dma_chan: the DMA channel to disable
- * @size: the sample size (in bytes)
- *
- * Returns the residue (remaining bytes) left in the DMA transfer.
- */
-unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan,
- unsigned int size)
-{
- int stalled = 0;
- unsigned long flags;
- unsigned int residue;
- unsigned int new_residue;
-
- residue = comedi_isadma_disable(dma_chan);
- while (residue % size) {
- /* residue is a partial sample, enable DMA to allow more data */
- flags = claim_dma_lock();
- enable_dma(dma_chan);
- release_dma_lock(flags);
-
- udelay(2);
- new_residue = comedi_isadma_disable(dma_chan);
-
- /* is DMA stalled? */
- if (new_residue == residue) {
- stalled++;
- if (stalled > 10)
- break;
- } else {
- residue = new_residue;
- stalled = 0;
- }
- }
- return residue;
-}
-EXPORT_SYMBOL_GPL(comedi_isadma_disable_on_sample);
-
-/**
- * comedi_isadma_poll - poll the current DMA transfer
- * @dma: the ISA DMA to poll
- *
- * Returns the position (in bytes) of the current DMA transfer.
- */
-unsigned int comedi_isadma_poll(struct comedi_isadma *dma)
-{
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned long flags;
- unsigned int result;
- unsigned int result1;
-
- flags = claim_dma_lock();
- clear_dma_ff(desc->chan);
- if (!isa_dma_bridge_buggy)
- disable_dma(desc->chan);
- result = get_dma_residue(desc->chan);
- /*
- * Read the counter again and choose higher value in order to
- * avoid reading during counter lower byte roll over if the
- * isa_dma_bridge_buggy is set.
- */
- result1 = get_dma_residue(desc->chan);
- if (!isa_dma_bridge_buggy)
- enable_dma(desc->chan);
- release_dma_lock(flags);
-
- if (result < result1)
- result = result1;
- if (result >= desc->size || result == 0)
- return 0;
- return desc->size - result;
-}
-EXPORT_SYMBOL_GPL(comedi_isadma_poll);
-
-/**
- * comedi_isadma_set_mode - set the ISA DMA transfer direction
- * @desc: the ISA DMA cookie to set
- * @dma_dir: the DMA direction
- */
-void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir)
-{
- desc->mode = (dma_dir == COMEDI_ISADMA_READ) ? DMA_MODE_READ
- : DMA_MODE_WRITE;
-}
-EXPORT_SYMBOL_GPL(comedi_isadma_set_mode);
-
-/**
- * comedi_isadma_alloc - allocate and initialize the ISA DMA
- * @dev: comedi_device struct
- * @n_desc: the number of cookies to allocate
- * @dma_chan: DMA channel for the first cookie
- * @dma_chan2: DMA channel for the second cookie
- * @maxsize: the size of the buffer to allocate for each cookie
- * @dma_dir: the DMA direction
- *
- * Returns the allocated and initialized ISA DMA or NULL if anything fails.
- */
-struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev,
- int n_desc, unsigned int dma_chan1,
- unsigned int dma_chan2,
- unsigned int maxsize, char dma_dir)
-{
- struct comedi_isadma *dma = NULL;
- struct comedi_isadma_desc *desc;
- unsigned int dma_chans[2];
- int i;
-
- if (n_desc < 1 || n_desc > 2)
- goto no_dma;
-
- dma = kzalloc(sizeof(*dma), GFP_KERNEL);
- if (!dma)
- goto no_dma;
-
- desc = kcalloc(n_desc, sizeof(*desc), GFP_KERNEL);
- if (!desc)
- goto no_dma;
- dma->desc = desc;
- dma->n_desc = n_desc;
- if (dev->hw_dev) {
- dma->dev = dev->hw_dev;
- } else {
- /* Fall back to using the "class" device. */
- if (!dev->class_dev)
- goto no_dma;
- /* Need 24-bit mask for ISA DMA. */
- if (dma_coerce_mask_and_coherent(dev->class_dev,
- DMA_BIT_MASK(24))) {
- goto no_dma;
- }
- dma->dev = dev->class_dev;
- }
-
- dma_chans[0] = dma_chan1;
- if (dma_chan2 == 0 || dma_chan2 == dma_chan1)
- dma_chans[1] = dma_chan1;
- else
- dma_chans[1] = dma_chan2;
-
- if (request_dma(dma_chans[0], dev->board_name))
- goto no_dma;
- dma->chan = dma_chans[0];
- if (dma_chans[1] != dma_chans[0]) {
- if (request_dma(dma_chans[1], dev->board_name))
- goto no_dma;
- }
- dma->chan2 = dma_chans[1];
-
- for (i = 0; i < n_desc; i++) {
- desc = &dma->desc[i];
- desc->chan = dma_chans[i];
- desc->maxsize = maxsize;
- desc->virt_addr = dma_alloc_coherent(dma->dev, desc->maxsize,
- &desc->hw_addr,
- GFP_KERNEL);
- if (!desc->virt_addr)
- goto no_dma;
- comedi_isadma_set_mode(desc, dma_dir);
- }
-
- return dma;
-
-no_dma:
- comedi_isadma_free(dma);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(comedi_isadma_alloc);
-
-/**
- * comedi_isadma_free - free the ISA DMA
- * @dma: the ISA DMA to free
- */
-void comedi_isadma_free(struct comedi_isadma *dma)
-{
- struct comedi_isadma_desc *desc;
- int i;
-
- if (!dma)
- return;
-
- if (dma->desc) {
- for (i = 0; i < dma->n_desc; i++) {
- desc = &dma->desc[i];
- if (desc->virt_addr)
- dma_free_coherent(dma->dev, desc->maxsize,
- desc->virt_addr,
- desc->hw_addr);
- }
- kfree(dma->desc);
- }
- if (dma->chan2 && dma->chan2 != dma->chan)
- free_dma(dma->chan2);
- if (dma->chan)
- free_dma(dma->chan);
- kfree(dma);
-}
-EXPORT_SYMBOL_GPL(comedi_isadma_free);
-
-static int __init comedi_isadma_init(void)
-{
- return 0;
-}
-module_init(comedi_isadma_init);
-
-static void __exit comedi_isadma_exit(void)
-{
-}
-module_exit(comedi_isadma_exit);
-
-MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_DESCRIPTION("Comedi ISA DMA support");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.h b/drivers/staging/comedi/drivers/comedi_isadma.h
deleted file mode 100644
index 9d2b12db7e6e..000000000000
--- a/drivers/staging/comedi/drivers/comedi_isadma.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * COMEDI ISA DMA support functions
- * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
- */
-
-#ifndef _COMEDI_ISADMA_H
-#define _COMEDI_ISADMA_H
-
-#include <linux/types.h>
-
-struct comedi_device;
-struct device;
-
-/*
- * These are used to avoid issues when <asm/dma.h> and the DMA_MODE_
- * defines are not available.
- */
-#define COMEDI_ISADMA_READ 0
-#define COMEDI_ISADMA_WRITE 1
-
-/**
- * struct comedi_isadma_desc - cookie for ISA DMA
- * @virt_addr: virtual address of buffer
- * @hw_addr: hardware (bus) address of buffer
- * @chan: DMA channel
- * @maxsize: allocated size of buffer (in bytes)
- * @size: transfer size (in bytes)
- * @mode: DMA_MODE_READ or DMA_MODE_WRITE
- */
-struct comedi_isadma_desc {
- void *virt_addr;
- dma_addr_t hw_addr;
- unsigned int chan;
- unsigned int maxsize;
- unsigned int size;
- char mode;
-};
-
-/**
- * struct comedi_isadma - ISA DMA data
- * @dev: device to allocate non-coherent memory for
- * @desc: cookie for each DMA buffer
- * @n_desc: the number of cookies
- * @cur_dma: the current cookie in use
- * @chan: the first DMA channel requested
- * @chan2: the second DMA channel requested
- */
-struct comedi_isadma {
- struct device *dev;
- struct comedi_isadma_desc *desc;
- int n_desc;
- int cur_dma;
- unsigned int chan;
- unsigned int chan2;
-};
-
-#if IS_ENABLED(CONFIG_ISA_DMA_API)
-
-void comedi_isadma_program(struct comedi_isadma_desc *desc);
-unsigned int comedi_isadma_disable(unsigned int dma_chan);
-unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan,
- unsigned int size);
-unsigned int comedi_isadma_poll(struct comedi_isadma *dma);
-void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir);
-
-struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev,
- int n_desc, unsigned int dma_chan1,
- unsigned int dma_chan2,
- unsigned int maxsize, char dma_dir);
-void comedi_isadma_free(struct comedi_isadma *dma);
-
-#else /* !IS_ENABLED(CONFIG_ISA_DMA_API) */
-
-static inline void comedi_isadma_program(struct comedi_isadma_desc *desc)
-{
-}
-
-static inline unsigned int comedi_isadma_disable(unsigned int dma_chan)
-{
- return 0;
-}
-
-static inline unsigned int
-comedi_isadma_disable_on_sample(unsigned int dma_chan, unsigned int size)
-{
- return 0;
-}
-
-static inline unsigned int comedi_isadma_poll(struct comedi_isadma *dma)
-{
- return 0;
-}
-
-static inline void comedi_isadma_set_mode(struct comedi_isadma_desc *desc,
- char dma_dir)
-{
-}
-
-static inline struct comedi_isadma *
-comedi_isadma_alloc(struct comedi_device *dev, int n_desc,
- unsigned int dma_chan1, unsigned int dma_chan2,
- unsigned int maxsize, char dma_dir)
-{
- return NULL;
-}
-
-static inline void comedi_isadma_free(struct comedi_isadma *dma)
-{
-}
-
-#endif /* !IS_ENABLED(CONFIG_ISA_DMA_API) */
-
-#endif /* #ifndef _COMEDI_ISADMA_H */
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
deleted file mode 100644
index 5338b5eea440..000000000000
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ /dev/null
@@ -1,306 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi_parport.c
- * Comedi driver for standard parallel port
- *
- * For more information see:
- * http://retired.beyondlogic.org/spp/parallel.htm
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998,2001 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: comedi_parport
- * Description: Standard PC parallel port
- * Author: ds
- * Status: works in immediate mode
- * Devices: [standard] parallel port (comedi_parport)
- * Updated: Tue, 30 Apr 2002 21:11:45 -0700
- *
- * A cheap and easy way to get a few more digital I/O lines. Steal
- * additional parallel ports from old computers or your neighbors'
- * computers.
- *
- * Option list:
- * 0: I/O port base for the parallel port.
- * 1: IRQ (optional)
- *
- * Parallel Port Lines:
- *
- * pin subdev chan type name
- * ----- ------ ---- ---- --------------
- * 1 2 0 DO strobe
- * 2 0 0 DIO data 0
- * 3 0 1 DIO data 1
- * 4 0 2 DIO data 2
- * 5 0 3 DIO data 3
- * 6 0 4 DIO data 4
- * 7 0 5 DIO data 5
- * 8 0 6 DIO data 6
- * 9 0 7 DIO data 7
- * 10 1 3 DI ack
- * 11 1 4 DI busy
- * 12 1 2 DI paper out
- * 13 1 1 DI select in
- * 14 2 1 DO auto LF
- * 15 1 0 DI error
- * 16 2 2 DO init
- * 17 2 3 DO select printer
- * 18-25 ground
- *
- * When an IRQ is configured subdevice 3 pretends to be a digital
- * input subdevice, but it always returns 0 when read. However, if
- * you run a command with scan_begin_src=TRIG_EXT, it uses pin 10
- * as a external trigger, which can be used to wake up tasks.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-/*
- * Register map
- */
-#define PARPORT_DATA_REG 0x00
-#define PARPORT_STATUS_REG 0x01
-#define PARPORT_CTRL_REG 0x02
-#define PARPORT_CTRL_IRQ_ENA BIT(4)
-#define PARPORT_CTRL_BIDIR_ENA BIT(5)
-
-static int parport_data_reg_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + PARPORT_DATA_REG);
-
- data[1] = inb(dev->iobase + PARPORT_DATA_REG);
-
- return insn->n;
-}
-
-static int parport_data_reg_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int ctrl;
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
- if (ret)
- return ret;
-
- ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
- if (s->io_bits)
- ctrl &= ~PARPORT_CTRL_BIDIR_ENA;
- else
- ctrl |= PARPORT_CTRL_BIDIR_ENA;
- outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
-
- return insn->n;
-}
-
-static int parport_status_reg_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + PARPORT_STATUS_REG) >> 3;
-
- return insn->n;
-}
-
-static int parport_ctrl_reg_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int ctrl;
-
- if (comedi_dio_update_state(s, data)) {
- ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
- ctrl &= (PARPORT_CTRL_IRQ_ENA | PARPORT_CTRL_BIDIR_ENA);
- ctrl |= s->state;
- outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int parport_intr_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = 0;
- return insn->n;
-}
-
-static int parport_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int parport_intr_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int ctrl;
-
- ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
- ctrl |= PARPORT_CTRL_IRQ_ENA;
- outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
-
- return 0;
-}
-
-static int parport_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int ctrl;
-
- ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
- ctrl &= ~PARPORT_CTRL_IRQ_ENA;
- outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
-
- return 0;
-}
-
-static irqreturn_t parport_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int ctrl;
- unsigned short val = 0;
-
- ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
- if (!(ctrl & PARPORT_CTRL_IRQ_ENA))
- return IRQ_NONE;
-
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int parport_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x03);
- if (ret)
- return ret;
-
- if (it->options[1]) {
- ret = request_irq(it->options[1], parport_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- ret = comedi_alloc_subdevices(dev, dev->irq ? 4 : 3);
- if (ret)
- return ret;
-
- /* Digial I/O subdevice - Parallel port DATA register */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = parport_data_reg_insn_bits;
- s->insn_config = parport_data_reg_insn_config;
-
- /* Digial Input subdevice - Parallel port STATUS register */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 5;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = parport_status_reg_insn_bits;
-
- /* Digial Output subdevice - Parallel port CONTROL register */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = parport_ctrl_reg_insn_bits;
-
- if (dev->irq) {
- /* Digial Input subdevice - Interrupt support */
- s = &dev->subdevices[3];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = parport_intr_insn_bits;
- s->len_chanlist = 1;
- s->do_cmdtest = parport_intr_cmdtest;
- s->do_cmd = parport_intr_cmd;
- s->cancel = parport_intr_cancel;
- }
-
- outb(0, dev->iobase + PARPORT_DATA_REG);
- outb(0, dev->iobase + PARPORT_CTRL_REG);
-
- return 0;
-}
-
-static struct comedi_driver parport_driver = {
- .driver_name = "comedi_parport",
- .module = THIS_MODULE,
- .attach = parport_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(parport_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi: Standard parallel port driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
deleted file mode 100644
index cbc225eb1991..000000000000
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ /dev/null
@@ -1,849 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/comedi_test.c
- *
- * Generates fake waveform signals that can be read through
- * the command interface. It does _not_ read from any board;
- * it just generates deterministic waveforms.
- * Useful for various testing purposes.
- *
- * Copyright (C) 2002 Joachim Wuttke <Joachim.Wuttke@icn.siemens.de>
- * Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: comedi_test
- * Description: generates fake waveforms
- * Author: Joachim Wuttke <Joachim.Wuttke@icn.siemens.de>, Frank Mori Hess
- * <fmhess@users.sourceforge.net>, ds
- * Devices:
- * Status: works
- * Updated: Sat, 16 Mar 2002 17:34:48 -0800
- *
- * This driver is mainly for testing purposes, but can also be used to
- * generate sample waveforms on systems that don't have data acquisition
- * hardware.
- *
- * Auto-configuration is the default mode if no parameter is supplied during
- * module loading. Manual configuration requires COMEDI userspace tool.
- * To disable auto-configuration mode, pass "noauto=1" parameter for module
- * loading. Refer modinfo or MODULE_PARM_DESC description below for details.
- *
- * Auto-configuration options:
- * Refer modinfo or MODULE_PARM_DESC description below for details.
- *
- * Manual configuration options:
- * [0] - Amplitude in microvolts for fake waveforms (default 1 volt)
- * [1] - Period in microseconds for fake waveforms (default 0.1 sec)
- *
- * Generates a sawtooth wave on channel 0, square wave on channel 1, additional
- * waveforms could be added to other channels (currently they return flatline
- * zero volts).
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include <asm/div64.h>
-
-#include <linux/timer.h>
-#include <linux/ktime.h>
-#include <linux/jiffies.h>
-#include <linux/device.h>
-#include <linux/kdev_t.h>
-
-#define N_CHANS 8
-#define DEV_NAME "comedi_testd"
-#define CLASS_NAME "comedi_test"
-
-static bool config_mode;
-static unsigned int set_amplitude;
-static unsigned int set_period;
-static struct class *ctcls;
-static struct device *ctdev;
-
-module_param_named(noauto, config_mode, bool, 0444);
-MODULE_PARM_DESC(noauto, "Disable auto-configuration: (1=disable [defaults to enable])");
-
-module_param_named(amplitude, set_amplitude, uint, 0444);
-MODULE_PARM_DESC(amplitude, "Set auto mode wave amplitude in microvolts: (defaults to 1 volt)");
-
-module_param_named(period, set_period, uint, 0444);
-MODULE_PARM_DESC(period, "Set auto mode wave period in microseconds: (defaults to 0.1 sec)");
-
-/* Data unique to this driver */
-struct waveform_private {
- struct timer_list ai_timer; /* timer for AI commands */
- u64 ai_convert_time; /* time of next AI conversion in usec */
- unsigned int wf_amplitude; /* waveform amplitude in microvolts */
- unsigned int wf_period; /* waveform period in microseconds */
- unsigned int wf_current; /* current time in waveform period */
- unsigned int ai_scan_period; /* AI scan period in usec */
- unsigned int ai_convert_period; /* AI conversion period in usec */
- struct timer_list ao_timer; /* timer for AO commands */
- struct comedi_device *dev; /* parent comedi device */
- u64 ao_last_scan_time; /* time of previous AO scan in usec */
- unsigned int ao_scan_period; /* AO scan period in usec */
- unsigned short ao_loopbacks[N_CHANS];
-};
-
-/* fake analog input ranges */
-static const struct comedi_lrange waveform_ai_ranges = {
- 2, {
- BIP_RANGE(10),
- BIP_RANGE(5)
- }
-};
-
-static unsigned short fake_sawtooth(struct comedi_device *dev,
- unsigned int range_index,
- unsigned int current_time)
-{
- struct waveform_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int offset = s->maxdata / 2;
- u64 value;
- const struct comedi_krange *krange =
- &s->range_table->range[range_index];
- u64 binary_amplitude;
-
- binary_amplitude = s->maxdata;
- binary_amplitude *= devpriv->wf_amplitude;
- do_div(binary_amplitude, krange->max - krange->min);
-
- value = current_time;
- value *= binary_amplitude * 2;
- do_div(value, devpriv->wf_period);
- value += offset;
- /* get rid of sawtooth's dc offset and clamp value */
- if (value < binary_amplitude) {
- value = 0; /* negative saturation */
- } else {
- value -= binary_amplitude;
- if (value > s->maxdata)
- value = s->maxdata; /* positive saturation */
- }
-
- return value;
-}
-
-static unsigned short fake_squarewave(struct comedi_device *dev,
- unsigned int range_index,
- unsigned int current_time)
-{
- struct waveform_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int offset = s->maxdata / 2;
- u64 value;
- const struct comedi_krange *krange =
- &s->range_table->range[range_index];
-
- value = s->maxdata;
- value *= devpriv->wf_amplitude;
- do_div(value, krange->max - krange->min);
-
- /* get one of two values for square-wave and clamp */
- if (current_time < devpriv->wf_period / 2) {
- if (offset < value)
- value = 0; /* negative saturation */
- else
- value = offset - value;
- } else {
- value += offset;
- if (value > s->maxdata)
- value = s->maxdata; /* positive saturation */
- }
-
- return value;
-}
-
-static unsigned short fake_flatline(struct comedi_device *dev,
- unsigned int range_index,
- unsigned int current_time)
-{
- return dev->read_subdev->maxdata / 2;
-}
-
-/* generates a different waveform depending on what channel is read */
-static unsigned short fake_waveform(struct comedi_device *dev,
- unsigned int channel, unsigned int range,
- unsigned int current_time)
-{
- enum {
- SAWTOOTH_CHAN,
- SQUARE_CHAN,
- };
- switch (channel) {
- case SAWTOOTH_CHAN:
- return fake_sawtooth(dev, range, current_time);
- case SQUARE_CHAN:
- return fake_squarewave(dev, range, current_time);
- default:
- break;
- }
-
- return fake_flatline(dev, range, current_time);
-}
-
-/*
- * This is the background routine used to generate arbitrary data.
- * It should run in the background; therefore it is scheduled by
- * a timer mechanism.
- */
-static void waveform_ai_timer(struct timer_list *t)
-{
- struct waveform_private *devpriv = from_timer(devpriv, t, ai_timer);
- struct comedi_device *dev = devpriv->dev;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u64 now;
- unsigned int nsamples;
- unsigned int time_increment;
-
- now = ktime_to_us(ktime_get());
- nsamples = comedi_nsamples_left(s, UINT_MAX);
-
- while (nsamples && devpriv->ai_convert_time < now) {
- unsigned int chanspec = cmd->chanlist[async->cur_chan];
- unsigned short sample;
-
- sample = fake_waveform(dev, CR_CHAN(chanspec),
- CR_RANGE(chanspec), devpriv->wf_current);
- if (comedi_buf_write_samples(s, &sample, 1) == 0)
- goto overrun;
- time_increment = devpriv->ai_convert_period;
- if (async->scan_progress == 0) {
- /* done last conversion in scan, so add dead time */
- time_increment += devpriv->ai_scan_period -
- devpriv->ai_convert_period *
- cmd->scan_end_arg;
- }
- devpriv->wf_current += time_increment;
- if (devpriv->wf_current >= devpriv->wf_period)
- devpriv->wf_current %= devpriv->wf_period;
- devpriv->ai_convert_time += time_increment;
- nsamples--;
- }
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- } else {
- if (devpriv->ai_convert_time > now)
- time_increment = devpriv->ai_convert_time - now;
- else
- time_increment = 1;
- mod_timer(&devpriv->ai_timer,
- jiffies + usecs_to_jiffies(time_increment));
- }
-
-overrun:
- comedi_handle_events(dev, s);
-}
-
-static int waveform_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg, limit;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_FOLLOW | TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_NOW | TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
- err |= -EINVAL; /* scan period would be 0 */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->convert_src == TRIG_NOW) {
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- } else { /* cmd->convert_src == TRIG_TIMER */
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- NSEC_PER_USEC);
- }
- }
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- } else { /* cmd->scan_begin_src == TRIG_TIMER */
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- NSEC_PER_USEC);
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* cmd->stop_src == TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- /* round convert_arg to nearest microsecond */
- arg = cmd->convert_arg;
- arg = min(arg,
- rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC));
- arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC);
- if (cmd->scan_begin_arg == TRIG_TIMER) {
- /* limit convert_arg to keep scan_begin_arg in range */
- limit = UINT_MAX / cmd->scan_end_arg;
- limit = rounddown(limit, (unsigned int)NSEC_PER_SEC);
- arg = min(arg, limit);
- }
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* round scan_begin_arg to nearest microsecond */
- arg = cmd->scan_begin_arg;
- arg = min(arg,
- rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC));
- arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC);
- if (cmd->convert_src == TRIG_TIMER) {
- /* but ensure scan_begin_arg is large enough */
- arg = max(arg, cmd->convert_arg * cmd->scan_end_arg);
- }
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int waveform_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct waveform_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int first_convert_time;
- u64 wf_current;
-
- if (cmd->flags & CMDF_PRIORITY) {
- dev_err(dev->class_dev,
- "commands at RT priority not supported in this driver\n");
- return -1;
- }
-
- if (cmd->convert_src == TRIG_NOW)
- devpriv->ai_convert_period = 0;
- else /* cmd->convert_src == TRIG_TIMER */
- devpriv->ai_convert_period = cmd->convert_arg / NSEC_PER_USEC;
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- devpriv->ai_scan_period = devpriv->ai_convert_period *
- cmd->scan_end_arg;
- } else { /* cmd->scan_begin_src == TRIG_TIMER */
- devpriv->ai_scan_period = cmd->scan_begin_arg / NSEC_PER_USEC;
- }
-
- /*
- * Simulate first conversion to occur at convert period after
- * conversion timer starts. If scan_begin_src is TRIG_FOLLOW, assume
- * the conversion timer starts immediately. If scan_begin_src is
- * TRIG_TIMER, assume the conversion timer starts after the scan
- * period.
- */
- first_convert_time = devpriv->ai_convert_period;
- if (cmd->scan_begin_src == TRIG_TIMER)
- first_convert_time += devpriv->ai_scan_period;
- devpriv->ai_convert_time = ktime_to_us(ktime_get()) +
- first_convert_time;
-
- /* Determine time within waveform period at time of conversion. */
- wf_current = devpriv->ai_convert_time;
- devpriv->wf_current = do_div(wf_current, devpriv->wf_period);
-
- /*
- * Schedule timer to expire just after first conversion time.
- * Seem to need an extra jiffy here, otherwise timer expires slightly
- * early!
- */
- devpriv->ai_timer.expires =
- jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1;
- add_timer(&devpriv->ai_timer);
- return 0;
-}
-
-static int waveform_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct waveform_private *devpriv = dev->private;
-
- if (in_softirq()) {
- /* Assume we were called from the timer routine itself. */
- del_timer(&devpriv->ai_timer);
- } else {
- del_timer_sync(&devpriv->ai_timer);
- }
- return 0;
-}
-
-static int waveform_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct waveform_private *devpriv = dev->private;
- int i, chan = CR_CHAN(insn->chanspec);
-
- for (i = 0; i < insn->n; i++)
- data[i] = devpriv->ao_loopbacks[chan];
-
- return insn->n;
-}
-
-/*
- * This is the background routine to handle AO commands, scheduled by
- * a timer mechanism.
- */
-static void waveform_ao_timer(struct timer_list *t)
-{
- struct waveform_private *devpriv = from_timer(devpriv, t, ao_timer);
- struct comedi_device *dev = devpriv->dev;
- struct comedi_subdevice *s = dev->write_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u64 now;
- u64 scans_since;
- unsigned int scans_avail = 0;
-
- /* determine number of scan periods since last time */
- now = ktime_to_us(ktime_get());
- scans_since = now - devpriv->ao_last_scan_time;
- do_div(scans_since, devpriv->ao_scan_period);
- if (scans_since) {
- unsigned int i;
-
- /* determine scans in buffer, limit to scans to do this time */
- scans_avail = comedi_nscans_left(s, 0);
- if (scans_avail > scans_since)
- scans_avail = scans_since;
- if (scans_avail) {
- /* skip all but the last scan to save processing time */
- if (scans_avail > 1) {
- unsigned int skip_bytes, nbytes;
-
- skip_bytes =
- comedi_samples_to_bytes(s, cmd->scan_end_arg *
- (scans_avail - 1));
- nbytes = comedi_buf_read_alloc(s, skip_bytes);
- comedi_buf_read_free(s, nbytes);
- comedi_inc_scan_progress(s, nbytes);
- if (nbytes < skip_bytes) {
- /* unexpected underrun! (cancelled?) */
- async->events |= COMEDI_CB_OVERFLOW;
- goto underrun;
- }
- }
- /* output the last scan */
- for (i = 0; i < cmd->scan_end_arg; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned short *pd;
-
- pd = &devpriv->ao_loopbacks[chan];
-
- if (!comedi_buf_read_samples(s, pd, 1)) {
- /* unexpected underrun! (cancelled?) */
- async->events |= COMEDI_CB_OVERFLOW;
- goto underrun;
- }
- }
- /* advance time of last scan */
- devpriv->ao_last_scan_time +=
- (u64)scans_avail * devpriv->ao_scan_period;
- }
- }
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- } else if (scans_avail < scans_since) {
- async->events |= COMEDI_CB_OVERFLOW;
- } else {
- unsigned int time_inc = devpriv->ao_last_scan_time +
- devpriv->ao_scan_period - now;
-
- mod_timer(&devpriv->ao_timer,
- jiffies + usecs_to_jiffies(time_inc));
- }
-
-underrun:
- comedi_handle_events(dev, s);
-}
-
-static int waveform_ao_inttrig_start(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct waveform_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- async->inttrig = NULL;
-
- devpriv->ao_last_scan_time = ktime_to_us(ktime_get());
- devpriv->ao_timer.expires =
- jiffies + usecs_to_jiffies(devpriv->ao_scan_period);
- add_timer(&devpriv->ao_timer);
-
- return 1;
-}
-
-static int waveform_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- NSEC_PER_USEC);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* cmd->stop_src == TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- /* round scan_begin_arg to nearest microsecond */
- arg = cmd->scan_begin_arg;
- arg = min(arg, rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC));
- arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int waveform_ao_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct waveform_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (cmd->flags & CMDF_PRIORITY) {
- dev_err(dev->class_dev,
- "commands at RT priority not supported in this driver\n");
- return -1;
- }
-
- devpriv->ao_scan_period = cmd->scan_begin_arg / NSEC_PER_USEC;
- s->async->inttrig = waveform_ao_inttrig_start;
- return 0;
-}
-
-static int waveform_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct waveform_private *devpriv = dev->private;
-
- s->async->inttrig = NULL;
- if (in_softirq()) {
- /* Assume we were called from the timer routine itself. */
- del_timer(&devpriv->ao_timer);
- } else {
- del_timer_sync(&devpriv->ao_timer);
- }
- return 0;
-}
-
-static int waveform_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct waveform_private *devpriv = dev->private;
- int i, chan = CR_CHAN(insn->chanspec);
-
- for (i = 0; i < insn->n; i++)
- devpriv->ao_loopbacks[chan] = data[i];
-
- return insn->n;
-}
-
-static int waveform_ai_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
- /*
- * input: data[1], data[2] : scan_begin_src, convert_src
- * output: data[1], data[2] : scan_begin_min, convert_min
- */
- if (data[1] == TRIG_FOLLOW) {
- /* exactly TRIG_FOLLOW case */
- data[1] = 0;
- data[2] = NSEC_PER_USEC;
- } else {
- data[1] = NSEC_PER_USEC;
- if (data[2] & TRIG_TIMER)
- data[2] = NSEC_PER_USEC;
- else
- data[2] = 0;
- }
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int waveform_ao_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
- /* we don't care about actual channels */
- data[1] = NSEC_PER_USEC; /* scan_begin_min */
- data[2] = 0; /* convert_min */
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int waveform_common_attach(struct comedi_device *dev,
- int amplitude, int period)
-{
- struct waveform_private *devpriv;
- struct comedi_subdevice *s;
- int i;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- devpriv->wf_amplitude = amplitude;
- devpriv->wf_period = period;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- /* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
- s->n_chan = N_CHANS;
- s->maxdata = 0xffff;
- s->range_table = &waveform_ai_ranges;
- s->len_chanlist = s->n_chan * 2;
- s->insn_read = waveform_ai_insn_read;
- s->do_cmd = waveform_ai_cmd;
- s->do_cmdtest = waveform_ai_cmdtest;
- s->cancel = waveform_ai_cancel;
- s->insn_config = waveform_ai_insn_config;
-
- s = &dev->subdevices[1];
- dev->write_subdev = s;
- /* analog output subdevice (loopback) */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
- s->n_chan = N_CHANS;
- s->maxdata = 0xffff;
- s->range_table = &waveform_ai_ranges;
- s->len_chanlist = s->n_chan;
- s->insn_write = waveform_ao_insn_write;
- s->insn_read = waveform_ai_insn_read; /* do same as AI insn_read */
- s->do_cmd = waveform_ao_cmd;
- s->do_cmdtest = waveform_ao_cmdtest;
- s->cancel = waveform_ao_cancel;
- s->insn_config = waveform_ao_insn_config;
-
- /* Our default loopback value is just a 0V flatline */
- for (i = 0; i < s->n_chan; i++)
- devpriv->ao_loopbacks[i] = s->maxdata / 2;
-
- devpriv->dev = dev;
- timer_setup(&devpriv->ai_timer, waveform_ai_timer, 0);
- timer_setup(&devpriv->ao_timer, waveform_ao_timer, 0);
-
- dev_info(dev->class_dev,
- "%s: %u microvolt, %u microsecond waveform attached\n",
- dev->board_name,
- devpriv->wf_amplitude, devpriv->wf_period);
-
- return 0;
-}
-
-static int waveform_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- int amplitude = it->options[0];
- int period = it->options[1];
-
- /* set default amplitude and period */
- if (amplitude <= 0)
- amplitude = 1000000; /* 1 volt */
- if (period <= 0)
- period = 100000; /* 0.1 sec */
-
- return waveform_common_attach(dev, amplitude, period);
-}
-
-static int waveform_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- int amplitude = set_amplitude;
- int period = set_period;
-
- /* set default amplitude and period */
- if (!amplitude)
- amplitude = 1000000; /* 1 volt */
- if (!period)
- period = 100000; /* 0.1 sec */
-
- return waveform_common_attach(dev, amplitude, period);
-}
-
-static void waveform_detach(struct comedi_device *dev)
-{
- struct waveform_private *devpriv = dev->private;
-
- if (devpriv) {
- del_timer_sync(&devpriv->ai_timer);
- del_timer_sync(&devpriv->ao_timer);
- }
-}
-
-static struct comedi_driver waveform_driver = {
- .driver_name = "comedi_test",
- .module = THIS_MODULE,
- .attach = waveform_attach,
- .auto_attach = waveform_auto_attach,
- .detach = waveform_detach,
-};
-
-/*
- * For auto-configuration, a device is created to stand in for a
- * real hardware device.
- */
-static int __init comedi_test_init(void)
-{
- int ret;
-
- ret = comedi_driver_register(&waveform_driver);
- if (ret) {
- pr_err("comedi_test: unable to register driver\n");
- return ret;
- }
-
- if (!config_mode) {
- ctcls = class_create(THIS_MODULE, CLASS_NAME);
- if (IS_ERR(ctcls)) {
- pr_warn("comedi_test: unable to create class\n");
- goto clean3;
- }
-
- ctdev = device_create(ctcls, NULL, MKDEV(0, 0), NULL, DEV_NAME);
- if (IS_ERR(ctdev)) {
- pr_warn("comedi_test: unable to create device\n");
- goto clean2;
- }
-
- ret = comedi_auto_config(ctdev, &waveform_driver, 0);
- if (ret) {
- pr_warn("comedi_test: unable to auto-configure device\n");
- goto clean;
- }
- }
-
- return 0;
-
-clean:
- device_destroy(ctcls, MKDEV(0, 0));
-clean2:
- class_destroy(ctcls);
- ctdev = NULL;
-clean3:
- ctcls = NULL;
-
- return 0;
-}
-module_init(comedi_test_init);
-
-static void __exit comedi_test_exit(void)
-{
- if (ctdev)
- comedi_auto_unconfig(ctdev);
-
- if (ctcls) {
- device_destroy(ctcls, MKDEV(0, 0));
- class_destroy(ctcls);
- }
-
- comedi_driver_unregister(&waveform_driver);
-}
-module_exit(comedi_test_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
deleted file mode 100644
index b8fdd9c1f166..000000000000
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ /dev/null
@@ -1,117 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/contec_pci_dio.c
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: contec_pci_dio
- * Description: Contec PIO1616L digital I/O board
- * Devices: [Contec] PIO1616L (contec_pci_dio)
- * Author: Stefano Rivoir <s.rivoir@gts.it>
- * Updated: Wed, 27 Jun 2007 13:00:06 +0100
- * Status: works
- *
- * Configuration Options: not applicable, uses comedi PCI auto config
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-/*
- * Register map
- */
-#define PIO1616L_DI_REG 0x00
-#define PIO1616L_DO_REG 0x02
-
-static int contec_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + PIO1616L_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int contec_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[1] = inw(dev->iobase + PIO1616L_DI_REG);
-
- return insn->n;
-}
-
-static int contec_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 0);
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = contec_di_insn_bits;
-
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = contec_do_insn_bits;
-
- return 0;
-}
-
-static struct comedi_driver contec_pci_dio_driver = {
- .driver_name = "contec_pci_dio",
- .module = THIS_MODULE,
- .auto_attach = contec_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int contec_pci_dio_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &contec_pci_dio_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id contec_pci_dio_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, 0x8172) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table);
-
-static struct pci_driver contec_pci_dio_pci_driver = {
- .name = "contec_pci_dio",
- .id_table = contec_pci_dio_pci_table,
- .probe = contec_pci_dio_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dac02.c b/drivers/staging/comedi/drivers/dac02.c
deleted file mode 100644
index 5ef8114c2c85..000000000000
--- a/drivers/staging/comedi/drivers/dac02.c
+++ /dev/null
@@ -1,137 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * dac02.c
- * Comedi driver for DAC02 compatible boards
- * Copyright (C) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Based on the poc driver
- * Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
- * Copyright (C) 2001 David A. Schleef <ds@schleef.org>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: dac02
- * Description: Comedi driver for DAC02 compatible boards
- * Devices: [Keithley Metrabyte] DAC-02 (dac02)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Tue, 11 Mar 2014 11:27:19 -0700
- * Status: unknown
- *
- * Configuration options:
- * [0] - I/O port base
- */
-
-#include <linux/module.h>
-
-#include "../comedidev.h"
-
-/*
- * The output range is selected by jumpering pins on the I/O connector.
- *
- * Range Chan # Jumper pins Output
- * ------------- ------ ------------- -----------------
- * 0 to 5V 0 21 to 22 24
- * 1 15 to 16 18
- * 0 to 10V 0 20 to 22 24
- * 1 14 to 16 18
- * +/-5V 0 21 to 22 23
- * 1 15 to 16 17
- * +/-10V 0 20 to 22 23
- * 1 14 to 16 17
- * 4 to 20mA 0 21 to 22 25
- * 1 15 to 16 19
- * AC reference 0 In on pin 22 24 (2-quadrant)
- * In on pin 22 23 (4-quadrant)
- * 1 In on pin 16 18 (2-quadrant)
- * In on pin 16 17 (4-quadrant)
- */
-static const struct comedi_lrange das02_ao_ranges = {
- 6, {
- UNI_RANGE(5),
- UNI_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(10),
- RANGE_mA(4, 20),
- RANGE_ext(0, 1)
- }
-};
-
-/*
- * Register I/O map
- */
-#define DAC02_AO_LSB(x) (0x00 + ((x) * 2))
-#define DAC02_AO_MSB(x) (0x01 + ((x) * 2))
-
-static int dac02_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- s->readback[chan] = val;
-
- /*
- * Unipolar outputs are true binary encoding.
- * Bipolar outputs are complementary offset binary
- * (that is, 0 = +full scale, maxdata = -full scale).
- */
- if (comedi_range_is_bipolar(s, range))
- val = s->maxdata - val;
-
- /*
- * DACs are double-buffered.
- * Write LSB then MSB to latch output.
- */
- outb((val << 4) & 0xf0, dev->iobase + DAC02_AO_LSB(chan));
- outb((val >> 4) & 0xff, dev->iobase + DAC02_AO_MSB(chan));
- }
-
- return insn->n;
-}
-
-static int dac02_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x08);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &das02_ao_ranges;
- s->insn_write = dac02_ao_insn_write;
-
- return comedi_alloc_subdev_readback(s);
-}
-
-static struct comedi_driver dac02_driver = {
- .driver_name = "dac02",
- .module = THIS_MODULE,
- .attach = dac02_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(dac02_driver);
-
-MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_DESCRIPTION("Comedi driver for DAC02 compatible boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
deleted file mode 100644
index f64e747078bd..000000000000
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ /dev/null
@@ -1,787 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/daqboard2000.c
- * hardware driver for IOtech DAQboard/2000
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
- */
-/*
- * Driver: daqboard2000
- * Description: IOTech DAQBoard/2000
- * Author: Anders Blomdell <anders.blomdell@control.lth.se>
- * Status: works
- * Updated: Mon, 14 Apr 2008 15:28:52 +0100
- * Devices: [IOTech] DAQBoard/2000 (daqboard2000)
- *
- * Much of the functionality of this driver was determined from reading
- * the source code for the Windows driver.
- *
- * The FPGA on the board requires firmware, which is available from
- * https://www.comedi.org in the comedi_nonfree_firmware tarball.
- *
- * Configuration options: not applicable, uses PCI auto config
- */
-/*
- * This card was obviously never intended to leave the Windows world,
- * since it lacked all kind of hardware documentation (except for cable
- * pinouts, plug and pray has something to catch up with yet).
- *
- * With some help from our swedish distributor, we got the Windows sourcecode
- * for the card, and here are the findings so far.
- *
- * 1. A good document that describes the PCI interface chip is 9080db-106.pdf
- * available from http://www.plxtech.com/products/io/pci9080
- *
- * 2. The initialization done so far is:
- * a. program the FPGA (windows code sans a lot of error messages)
- * b.
- *
- * 3. Analog out seems to work OK with DAC's disabled, if DAC's are enabled,
- * you have to output values to all enabled DAC's until result appears, I
- * guess that it has something to do with pacer clocks, but the source
- * gives me no clues. I'll keep it simple so far.
- *
- * 4. Analog in.
- * Each channel in the scanlist seems to be controlled by four
- * control words:
- *
- * Word0:
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! | | | ! | | | ! | | | ! | | | !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Word1:
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! | | | ! | | | ! | | | ! | | | !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | |
- * +------+------+ | | | | +-- Digital input (??)
- * | | | | +---- 10 us settling time
- * | | | +------ Suspend acquisition (last to scan)
- * | | +-------- Simultaneous sample and hold
- * | +---------- Signed data format
- * +------------------------- Correction offset low
- *
- * Word2:
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! | | | ! | | | ! | | | ! | | | !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | |
- * +-----+ +--+--+ +++ +++ +--+--+
- * | | | | +----- Expansion channel
- * | | | +----------- Expansion gain
- * | | +--------------- Channel (low)
- * | +--------------------- Correction offset high
- * +----------------------------- Correction gain low
- * Word3:
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * ! | | | ! | | | ! | | | ! | | | !
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | |
- * +------+------+ | | +-+-+ | | +-- Low bank enable
- * | | | | | +---- High bank enable
- * | | | | +------ Hi/low select
- * | | | +---------- Gain (1,?,2,4,8,16,32,64)
- * | | +-------------- differential/single ended
- * | +---------------- Unipolar
- * +------------------------- Correction gain high
- *
- * 999. The card seems to have an incredible amount of capabilities, but
- * trying to reverse engineer them from the Windows source is beyond my
- * patience.
- *
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "8255.h"
-#include "plx9080.h"
-
-#define DB2K_FIRMWARE "daqboard2000_firmware.bin"
-
-static const struct comedi_lrange db2k_ai_range = {
- 13, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- BIP_RANGE(0.3125),
- BIP_RANGE(0.156),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- UNI_RANGE(0.625),
- UNI_RANGE(0.3125)
- }
-};
-
-/*
- * Register Memory Map
- */
-#define DB2K_REG_ACQ_CONTROL 0x00 /* u16 (w) */
-#define DB2K_REG_ACQ_STATUS 0x00 /* u16 (r) */
-#define DB2K_REG_ACQ_SCAN_LIST_FIFO 0x02 /* u16 */
-#define DB2K_REG_ACQ_PACER_CLOCK_DIV_LOW 0x04 /* u32 */
-#define DB2K_REG_ACQ_SCAN_COUNTER 0x08 /* u16 */
-#define DB2K_REG_ACQ_PACER_CLOCK_DIV_HIGH 0x0a /* u16 */
-#define DB2K_REG_ACQ_TRIGGER_COUNT 0x0c /* u16 */
-#define DB2K_REG_ACQ_RESULTS_FIFO 0x10 /* u16 */
-#define DB2K_REG_ACQ_RESULTS_SHADOW 0x14 /* u16 */
-#define DB2K_REG_ACQ_ADC_RESULT 0x18 /* u16 */
-#define DB2K_REG_DAC_SCAN_COUNTER 0x1c /* u16 */
-#define DB2K_REG_DAC_CONTROL 0x20 /* u16 (w) */
-#define DB2K_REG_DAC_STATUS 0x20 /* u16 (r) */
-#define DB2K_REG_DAC_FIFO 0x24 /* s16 */
-#define DB2K_REG_DAC_PACER_CLOCK_DIV 0x2a /* u16 */
-#define DB2K_REG_REF_DACS 0x2c /* u16 */
-#define DB2K_REG_DIO_CONTROL 0x30 /* u16 */
-#define DB2K_REG_P3_HSIO_DATA 0x32 /* s16 */
-#define DB2K_REG_P3_CONTROL 0x34 /* u16 */
-#define DB2K_REG_CAL_EEPROM_CONTROL 0x36 /* u16 */
-#define DB2K_REG_DAC_SETTING(x) (0x38 + (x) * 2) /* s16 */
-#define DB2K_REG_DIO_P2_EXP_IO_8_BIT 0x40 /* s16 */
-#define DB2K_REG_COUNTER_TIMER_CONTROL 0x80 /* u16 */
-#define DB2K_REG_COUNTER_INPUT(x) (0x88 + (x) * 2) /* s16 */
-#define DB2K_REG_TIMER_DIV(x) (0xa0 + (x) * 2) /* u16 */
-#define DB2K_REG_DMA_CONTROL 0xb0 /* u16 */
-#define DB2K_REG_TRIG_CONTROL 0xb2 /* u16 */
-#define DB2K_REG_CAL_EEPROM 0xb8 /* u16 */
-#define DB2K_REG_ACQ_DIGITAL_MARK 0xba /* u16 */
-#define DB2K_REG_TRIG_DACS 0xbc /* u16 */
-#define DB2K_REG_DIO_P2_EXP_IO_16_BIT(x) (0xc0 + (x) * 2) /* s16 */
-
-/* CPLD registers */
-#define DB2K_REG_CPLD_STATUS 0x1000 /* u16 (r) */
-#define DB2K_REG_CPLD_WDATA 0x1000 /* u16 (w) */
-
-/* Scan Sequencer programming */
-#define DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST 0x0011
-#define DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST 0x0010
-
-/* Prepare for acquisition */
-#define DB2K_ACQ_CONTROL_RESET_SCAN_LIST_FIFO 0x0004
-#define DB2K_ACQ_CONTROL_RESET_RESULTS_FIFO 0x0002
-#define DB2K_ACQ_CONTROL_RESET_CONFIG_PIPE 0x0001
-
-/* Pacer Clock Control */
-#define DB2K_ACQ_CONTROL_ADC_PACER_INTERNAL 0x0030
-#define DB2K_ACQ_CONTROL_ADC_PACER_EXTERNAL 0x0032
-#define DB2K_ACQ_CONTROL_ADC_PACER_ENABLE 0x0031
-#define DB2K_ACQ_CONTROL_ADC_PACER_ENABLE_DAC_PACER 0x0034
-#define DB2K_ACQ_CONTROL_ADC_PACER_DISABLE 0x0030
-#define DB2K_ACQ_CONTROL_ADC_PACER_NORMAL_MODE 0x0060
-#define DB2K_ACQ_CONTROL_ADC_PACER_COMPATIBILITY_MODE 0x0061
-#define DB2K_ACQ_CONTROL_ADC_PACER_INTERNAL_OUT_ENABLE 0x0008
-#define DB2K_ACQ_CONTROL_ADC_PACER_EXTERNAL_RISING 0x0100
-
-/* Acquisition status bits */
-#define DB2K_ACQ_STATUS_RESULTS_FIFO_MORE_1_SAMPLE 0x0001
-#define DB2K_ACQ_STATUS_RESULTS_FIFO_HAS_DATA 0x0002
-#define DB2K_ACQ_STATUS_RESULTS_FIFO_OVERRUN 0x0004
-#define DB2K_ACQ_STATUS_LOGIC_SCANNING 0x0008
-#define DB2K_ACQ_STATUS_CONFIG_PIPE_FULL 0x0010
-#define DB2K_ACQ_STATUS_SCAN_LIST_FIFO_EMPTY 0x0020
-#define DB2K_ACQ_STATUS_ADC_NOT_READY 0x0040
-#define DB2K_ACQ_STATUS_ARBITRATION_FAILURE 0x0080
-#define DB2K_ACQ_STATUS_ADC_PACER_OVERRUN 0x0100
-#define DB2K_ACQ_STATUS_DAC_PACER_OVERRUN 0x0200
-
-/* DAC status */
-#define DB2K_DAC_STATUS_DAC_FULL 0x0001
-#define DB2K_DAC_STATUS_REF_BUSY 0x0002
-#define DB2K_DAC_STATUS_TRIG_BUSY 0x0004
-#define DB2K_DAC_STATUS_CAL_BUSY 0x0008
-#define DB2K_DAC_STATUS_DAC_BUSY(x) (0x0010 << (x))
-
-/* DAC control */
-#define DB2K_DAC_CONTROL_ENABLE_BIT 0x0001
-#define DB2K_DAC_CONTROL_DATA_IS_SIGNED 0x0002
-#define DB2K_DAC_CONTROL_RESET_FIFO 0x0004
-#define DB2K_DAC_CONTROL_DAC_DISABLE(x) (0x0020 + ((x) << 4))
-#define DB2K_DAC_CONTROL_DAC_ENABLE(x) (0x0021 + ((x) << 4))
-#define DB2K_DAC_CONTROL_PATTERN_DISABLE 0x0060
-#define DB2K_DAC_CONTROL_PATTERN_ENABLE 0x0061
-
-/* Trigger Control */
-#define DB2K_TRIG_CONTROL_TYPE_ANALOG 0x0000
-#define DB2K_TRIG_CONTROL_TYPE_TTL 0x0010
-#define DB2K_TRIG_CONTROL_EDGE_HI_LO 0x0004
-#define DB2K_TRIG_CONTROL_EDGE_LO_HI 0x0000
-#define DB2K_TRIG_CONTROL_LEVEL_ABOVE 0x0000
-#define DB2K_TRIG_CONTROL_LEVEL_BELOW 0x0004
-#define DB2K_TRIG_CONTROL_SENSE_LEVEL 0x0002
-#define DB2K_TRIG_CONTROL_SENSE_EDGE 0x0000
-#define DB2K_TRIG_CONTROL_ENABLE 0x0001
-#define DB2K_TRIG_CONTROL_DISABLE 0x0000
-
-/* Reference Dac Selection */
-#define DB2K_REF_DACS_SET 0x0080
-#define DB2K_REF_DACS_SELECT_POS_REF 0x0100
-#define DB2K_REF_DACS_SELECT_NEG_REF 0x0000
-
-/* CPLD status bits */
-#define DB2K_CPLD_STATUS_INIT 0x0002
-#define DB2K_CPLD_STATUS_TXREADY 0x0004
-#define DB2K_CPLD_VERSION_MASK 0xf000
-/* "New CPLD" signature. */
-#define DB2K_CPLD_VERSION_NEW 0x5000
-
-enum db2k_boardid {
- BOARD_DAQBOARD2000,
- BOARD_DAQBOARD2001
-};
-
-struct db2k_boardtype {
- const char *name;
- unsigned int has_2_ao:1;/* false: 4 AO chans; true: 2 AO chans */
-};
-
-static const struct db2k_boardtype db2k_boardtypes[] = {
- [BOARD_DAQBOARD2000] = {
- .name = "daqboard2000",
- .has_2_ao = true,
- },
- [BOARD_DAQBOARD2001] = {
- .name = "daqboard2001",
- },
-};
-
-struct db2k_private {
- void __iomem *plx;
-};
-
-static void db2k_write_acq_scan_list_entry(struct comedi_device *dev, u16 entry)
-{
- writew(entry & 0x00ff, dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO);
- writew((entry >> 8) & 0x00ff,
- dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO);
-}
-
-static void db2k_setup_sampling(struct comedi_device *dev, int chan, int gain)
-{
- u16 word0, word1, word2, word3;
-
- /* Channel 0-7 diff, channel 8-23 single ended */
- word0 = 0;
- word1 = 0x0004; /* Last scan */
- word2 = (chan << 6) & 0x00c0;
- switch (chan / 4) {
- case 0:
- word3 = 0x0001;
- break;
- case 1:
- word3 = 0x0002;
- break;
- case 2:
- word3 = 0x0005;
- break;
- case 3:
- word3 = 0x0006;
- break;
- case 4:
- word3 = 0x0041;
- break;
- case 5:
- word3 = 0x0042;
- break;
- default:
- word3 = 0;
- break;
- }
- /* These should be read from EEPROM */
- word2 |= 0x0800; /* offset */
- word3 |= 0xc000; /* gain */
- db2k_write_acq_scan_list_entry(dev, word0);
- db2k_write_acq_scan_list_entry(dev, word1);
- db2k_write_acq_scan_list_entry(dev, word2);
- db2k_write_acq_scan_list_entry(dev, word3);
-}
-
-static int db2k_ai_status(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned long context)
-{
- unsigned int status;
-
- status = readw(dev->mmio + DB2K_REG_ACQ_STATUS);
- if (status & context)
- return 0;
- return -EBUSY;
-}
-
-static int db2k_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int gain, chan;
- int ret;
- int i;
-
- writew(DB2K_ACQ_CONTROL_RESET_SCAN_LIST_FIFO |
- DB2K_ACQ_CONTROL_RESET_RESULTS_FIFO |
- DB2K_ACQ_CONTROL_RESET_CONFIG_PIPE,
- dev->mmio + DB2K_REG_ACQ_CONTROL);
-
- /*
- * If pacer clock is not set to some high value (> 10 us), we
- * risk multiple samples to be put into the result FIFO.
- */
- /* 1 second, should be long enough */
- writel(1000000, dev->mmio + DB2K_REG_ACQ_PACER_CLOCK_DIV_LOW);
- writew(0, dev->mmio + DB2K_REG_ACQ_PACER_CLOCK_DIV_HIGH);
-
- gain = CR_RANGE(insn->chanspec);
- chan = CR_CHAN(insn->chanspec);
-
- /*
- * This doesn't look efficient. I decided to take the conservative
- * approach when I did the insn conversion. Perhaps it would be
- * better to have broken it completely, then someone would have been
- * forced to fix it. --ds
- */
- for (i = 0; i < insn->n; i++) {
- db2k_setup_sampling(dev, chan, gain);
- /* Enable reading from the scanlist FIFO */
- writew(DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST,
- dev->mmio + DB2K_REG_ACQ_CONTROL);
-
- ret = comedi_timeout(dev, s, insn, db2k_ai_status,
- DB2K_ACQ_STATUS_CONFIG_PIPE_FULL);
- if (ret)
- return ret;
-
- writew(DB2K_ACQ_CONTROL_ADC_PACER_ENABLE,
- dev->mmio + DB2K_REG_ACQ_CONTROL);
-
- ret = comedi_timeout(dev, s, insn, db2k_ai_status,
- DB2K_ACQ_STATUS_LOGIC_SCANNING);
- if (ret)
- return ret;
-
- ret =
- comedi_timeout(dev, s, insn, db2k_ai_status,
- DB2K_ACQ_STATUS_RESULTS_FIFO_HAS_DATA);
- if (ret)
- return ret;
-
- data[i] = readw(dev->mmio + DB2K_REG_ACQ_RESULTS_FIFO);
- writew(DB2K_ACQ_CONTROL_ADC_PACER_DISABLE,
- dev->mmio + DB2K_REG_ACQ_CONTROL);
- writew(DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST,
- dev->mmio + DB2K_REG_ACQ_CONTROL);
- }
-
- return i;
-}
-
-static int db2k_ao_eoc(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned long context)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int status;
-
- status = readw(dev->mmio + DB2K_REG_DAC_STATUS);
- if ((status & DB2K_DAC_STATUS_DAC_BUSY(chan)) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int db2k_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
- int ret;
-
- writew(val, dev->mmio + DB2K_REG_DAC_SETTING(chan));
-
- ret = comedi_timeout(dev, s, insn, db2k_ao_eoc, 0);
- if (ret)
- return ret;
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static void db2k_reset_local_bus(struct comedi_device *dev)
-{
- struct db2k_private *devpriv = dev->private;
- u32 cntrl;
-
- cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
- cntrl |= PLX_CNTRL_RESET;
- writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
- mdelay(10);
- cntrl &= ~PLX_CNTRL_RESET;
- writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
- mdelay(10);
-}
-
-static void db2k_reload_plx(struct comedi_device *dev)
-{
- struct db2k_private *devpriv = dev->private;
- u32 cntrl;
-
- cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
- cntrl &= ~PLX_CNTRL_EERELOAD;
- writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
- mdelay(10);
- cntrl |= PLX_CNTRL_EERELOAD;
- writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
- mdelay(10);
- cntrl &= ~PLX_CNTRL_EERELOAD;
- writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
- mdelay(10);
-}
-
-static void db2k_pulse_prog_pin(struct comedi_device *dev)
-{
- struct db2k_private *devpriv = dev->private;
- u32 cntrl;
-
- cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
- cntrl |= PLX_CNTRL_USERO;
- writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
- mdelay(10);
- cntrl &= ~PLX_CNTRL_USERO;
- writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
- mdelay(10); /* Not in the original code, but I like symmetry... */
-}
-
-static int db2k_wait_cpld_init(struct comedi_device *dev)
-{
- int result = -ETIMEDOUT;
- int i;
- u16 cpld;
-
- /* timeout after 50 tries -> 5ms */
- for (i = 0; i < 50; i++) {
- cpld = readw(dev->mmio + DB2K_REG_CPLD_STATUS);
- if (cpld & DB2K_CPLD_STATUS_INIT) {
- result = 0;
- break;
- }
- usleep_range(100, 1000);
- }
- udelay(5);
- return result;
-}
-
-static int db2k_wait_cpld_txready(struct comedi_device *dev)
-{
- int i;
-
- for (i = 0; i < 100; i++) {
- if (readw(dev->mmio + DB2K_REG_CPLD_STATUS) &
- DB2K_CPLD_STATUS_TXREADY) {
- return 0;
- }
- udelay(1);
- }
- return -ETIMEDOUT;
-}
-
-static int db2k_write_cpld(struct comedi_device *dev, u16 data, bool new_cpld)
-{
- int result = 0;
-
- if (new_cpld) {
- result = db2k_wait_cpld_txready(dev);
- if (result)
- return result;
- } else {
- usleep_range(10, 20);
- }
- writew(data, dev->mmio + DB2K_REG_CPLD_WDATA);
- if (!(readw(dev->mmio + DB2K_REG_CPLD_STATUS) & DB2K_CPLD_STATUS_INIT))
- result = -EIO;
-
- return result;
-}
-
-static int db2k_wait_fpga_programmed(struct comedi_device *dev)
-{
- struct db2k_private *devpriv = dev->private;
- int i;
-
- /* Time out after 200 tries -> 20ms */
- for (i = 0; i < 200; i++) {
- u32 cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
- /* General Purpose Input (USERI) set on FPGA "DONE". */
- if (cntrl & PLX_CNTRL_USERI)
- return 0;
-
- usleep_range(100, 1000);
- }
- return -ETIMEDOUT;
-}
-
-static int db2k_load_firmware(struct comedi_device *dev, const u8 *cpld_array,
- size_t len, unsigned long context)
-{
- struct db2k_private *devpriv = dev->private;
- int result = -EIO;
- u32 cntrl;
- int retry;
- size_t i;
- bool new_cpld;
-
- /* Look for FPGA start sequence in firmware. */
- for (i = 0; i + 1 < len; i++) {
- if (cpld_array[i] == 0xff && cpld_array[i + 1] == 0x20)
- break;
- }
- if (i + 1 >= len) {
- dev_err(dev->class_dev, "bad firmware - no start sequence\n");
- return -EINVAL;
- }
- /* Check length is even. */
- if ((len - i) & 1) {
- dev_err(dev->class_dev,
- "bad firmware - odd length (%zu = %zu - %zu)\n",
- len - i, len, i);
- return -EINVAL;
- }
- /* Strip firmware header. */
- cpld_array += i;
- len -= i;
-
- /* Check to make sure the serial eeprom is present on the board */
- cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
- if (!(cntrl & PLX_CNTRL_EEPRESENT))
- return -EIO;
-
- for (retry = 0; retry < 3; retry++) {
- db2k_reset_local_bus(dev);
- db2k_reload_plx(dev);
- db2k_pulse_prog_pin(dev);
- result = db2k_wait_cpld_init(dev);
- if (result)
- continue;
-
- new_cpld = (readw(dev->mmio + DB2K_REG_CPLD_STATUS) &
- DB2K_CPLD_VERSION_MASK) == DB2K_CPLD_VERSION_NEW;
- for (; i < len; i += 2) {
- u16 data = (cpld_array[i] << 8) + cpld_array[i + 1];
-
- result = db2k_write_cpld(dev, data, new_cpld);
- if (result)
- break;
- }
- if (result == 0)
- result = db2k_wait_fpga_programmed(dev);
- if (result == 0) {
- db2k_reset_local_bus(dev);
- db2k_reload_plx(dev);
- break;
- }
- }
- return result;
-}
-
-static void db2k_adc_stop_dma_transfer(struct comedi_device *dev)
-{
-}
-
-static void db2k_adc_disarm(struct comedi_device *dev)
-{
- /* Disable hardware triggers */
- udelay(2);
- writew(DB2K_TRIG_CONTROL_TYPE_ANALOG | DB2K_TRIG_CONTROL_DISABLE,
- dev->mmio + DB2K_REG_TRIG_CONTROL);
- udelay(2);
- writew(DB2K_TRIG_CONTROL_TYPE_TTL | DB2K_TRIG_CONTROL_DISABLE,
- dev->mmio + DB2K_REG_TRIG_CONTROL);
-
- /* Stop the scan list FIFO from loading the configuration pipe */
- udelay(2);
- writew(DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST,
- dev->mmio + DB2K_REG_ACQ_CONTROL);
-
- /* Stop the pacer clock */
- udelay(2);
- writew(DB2K_ACQ_CONTROL_ADC_PACER_DISABLE,
- dev->mmio + DB2K_REG_ACQ_CONTROL);
-
- /* Stop the input dma (abort channel 1) */
- db2k_adc_stop_dma_transfer(dev);
-}
-
-static void db2k_activate_reference_dacs(struct comedi_device *dev)
-{
- unsigned int val;
- int timeout;
-
- /* Set the + reference dac value in the FPGA */
- writew(DB2K_REF_DACS_SET | DB2K_REF_DACS_SELECT_POS_REF,
- dev->mmio + DB2K_REG_REF_DACS);
- for (timeout = 0; timeout < 20; timeout++) {
- val = readw(dev->mmio + DB2K_REG_DAC_STATUS);
- if ((val & DB2K_DAC_STATUS_REF_BUSY) == 0)
- break;
- udelay(2);
- }
-
- /* Set the - reference dac value in the FPGA */
- writew(DB2K_REF_DACS_SET | DB2K_REF_DACS_SELECT_NEG_REF,
- dev->mmio + DB2K_REG_REF_DACS);
- for (timeout = 0; timeout < 20; timeout++) {
- val = readw(dev->mmio + DB2K_REG_DAC_STATUS);
- if ((val & DB2K_DAC_STATUS_REF_BUSY) == 0)
- break;
- udelay(2);
- }
-}
-
-static void db2k_initialize_ctrs(struct comedi_device *dev)
-{
-}
-
-static void db2k_initialize_tmrs(struct comedi_device *dev)
-{
-}
-
-static void db2k_dac_disarm(struct comedi_device *dev)
-{
-}
-
-static void db2k_initialize_adc(struct comedi_device *dev)
-{
- db2k_adc_disarm(dev);
- db2k_activate_reference_dacs(dev);
- db2k_initialize_ctrs(dev);
- db2k_initialize_tmrs(dev);
-}
-
-static int db2k_8255_cb(struct comedi_device *dev, int dir, int port, int data,
- unsigned long iobase)
-{
- if (dir) {
- writew(data, dev->mmio + iobase + port * 2);
- return 0;
- }
- return readw(dev->mmio + iobase + port * 2);
-}
-
-static int db2k_auto_attach(struct comedi_device *dev, unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct db2k_boardtype *board;
- struct db2k_private *devpriv;
- struct comedi_subdevice *s;
- int result;
-
- if (context >= ARRAY_SIZE(db2k_boardtypes))
- return -ENODEV;
- board = &db2k_boardtypes[context];
- if (!board->name)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- result = comedi_pci_enable(dev);
- if (result)
- return result;
-
- devpriv->plx = pci_ioremap_bar(pcidev, 0);
- dev->mmio = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->plx || !dev->mmio)
- return -ENOMEM;
-
- result = comedi_alloc_subdevices(dev, 3);
- if (result)
- return result;
-
- result = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
- DB2K_FIRMWARE, db2k_load_firmware, 0);
- if (result < 0)
- return result;
-
- db2k_initialize_adc(dev);
- db2k_dac_disarm(dev);
-
- s = &dev->subdevices[0];
- /* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 24;
- s->maxdata = 0xffff;
- s->insn_read = db2k_ai_insn_read;
- s->range_table = &db2k_ai_range;
-
- s = &dev->subdevices[1];
- /* ao subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->has_2_ao ? 2 : 4;
- s->maxdata = 0xffff;
- s->insn_write = db2k_ao_insn_write;
- s->range_table = &range_bipolar10;
-
- result = comedi_alloc_subdev_readback(s);
- if (result)
- return result;
-
- s = &dev->subdevices[2];
- return subdev_8255_init(dev, s, db2k_8255_cb,
- DB2K_REG_DIO_P2_EXP_IO_8_BIT);
-}
-
-static void db2k_detach(struct comedi_device *dev)
-{
- struct db2k_private *devpriv = dev->private;
-
- if (devpriv && devpriv->plx)
- iounmap(devpriv->plx);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver db2k_driver = {
- .driver_name = "daqboard2000",
- .module = THIS_MODULE,
- .auto_attach = db2k_auto_attach,
- .detach = db2k_detach,
-};
-
-static int db2k_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &db2k_driver, id->driver_data);
-}
-
-static const struct pci_device_id db2k_pci_table[] = {
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_IOTECH, 0x0409, PCI_VENDOR_ID_IOTECH,
- 0x0002), .driver_data = BOARD_DAQBOARD2000, },
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_IOTECH, 0x0409, PCI_VENDOR_ID_IOTECH,
- 0x0004), .driver_data = BOARD_DAQBOARD2001, },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, db2k_pci_table);
-
-static struct pci_driver db2k_pci_driver = {
- .name = "daqboard2000",
- .id_table = db2k_pci_table,
- .probe = db2k_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(db2k_driver, db2k_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(DB2K_FIRMWARE);
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
deleted file mode 100644
index b50743c5b822..000000000000
--- a/drivers/staging/comedi/drivers/das08.c
+++ /dev/null
@@ -1,470 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/das08.c
- * comedi module for common DAS08 support (used by ISA/PCI/PCMCIA drivers)
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- * Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org>
- */
-
-#include <linux/module.h>
-
-#include "../comedidev.h"
-
-#include "8255.h"
-#include "comedi_8254.h"
-#include "das08.h"
-
-/*
- * Data format of DAS08_AI_LSB_REG and DAS08_AI_MSB_REG depends on
- * 'ai_encoding' member of board structure:
- *
- * das08_encode12 : DATA[11..4] = MSB[7..0], DATA[3..0] = LSB[7..4].
- * das08_pcm_encode12 : DATA[11..8] = MSB[3..0], DATA[7..9] = LSB[7..0].
- * das08_encode16 : SIGN = MSB[7], MAGNITUDE[14..8] = MSB[6..0],
- * MAGNITUDE[7..0] = LSB[7..0].
- * SIGN==0 for negative input, SIGN==1 for positive input.
- * Note: when read a second time after conversion
- * complete, MSB[7] is an "over-range" bit.
- */
-#define DAS08_AI_LSB_REG 0x00 /* (R) AI least significant bits */
-#define DAS08_AI_MSB_REG 0x01 /* (R) AI most significant bits */
-#define DAS08_AI_TRIG_REG 0x01 /* (W) AI software trigger */
-#define DAS08_STATUS_REG 0x02 /* (R) status */
-#define DAS08_STATUS_AI_BUSY BIT(7) /* AI conversion in progress */
-/*
- * The IRQ status bit is set to 1 by a rising edge on the external interrupt
- * input (which may be jumpered to the pacer output). It is cleared by
- * setting the INTE control bit to 0. Not present on "JR" boards.
- */
-#define DAS08_STATUS_IRQ BIT(3) /* latched interrupt input */
-/* digital inputs (not "JR" boards) */
-#define DAS08_STATUS_DI(x) (((x) & 0x70) >> 4)
-#define DAS08_CONTROL_REG 0x02 /* (W) control */
-/*
- * Note: The AI multiplexor channel can also be read from status register using
- * the same mask.
- */
-#define DAS08_CONTROL_MUX_MASK 0x7 /* multiplexor channel mask */
-#define DAS08_CONTROL_MUX(x) ((x) & DAS08_CONTROL_MUX_MASK) /* mux channel */
-#define DAS08_CONTROL_INTE BIT(3) /* interrupt enable (not "JR" boards) */
-#define DAS08_CONTROL_DO_MASK 0xf0 /* digital outputs mask (not "JR") */
-/* digital outputs (not "JR" boards) */
-#define DAS08_CONTROL_DO(x) (((x) << 4) & DAS08_CONTROL_DO_MASK)
-/*
- * (R/W) programmable AI gain ("PGx" and "AOx" boards):
- * + bits 3..0 (R/W) show/set the gain for the current AI mux channel
- * + bits 6..4 (R) show the current AI mux channel
- * + bit 7 (R) not unused
- */
-#define DAS08_GAIN_REG 0x03
-
-#define DAS08JR_DI_REG 0x03 /* (R) digital inputs ("JR" boards) */
-#define DAS08JR_DO_REG 0x03 /* (W) digital outputs ("JR" boards) */
-/* (W) analog output l.s.b. registers for 2 channels ("JR" boards) */
-#define DAS08JR_AO_LSB_REG(x) ((x) ? 0x06 : 0x04)
-/* (W) analog output m.s.b. registers for 2 channels ("JR" boards) */
-#define DAS08JR_AO_MSB_REG(x) ((x) ? 0x07 : 0x05)
-/*
- * (R) update analog outputs ("JR" boards set for simultaneous output)
- * (same register as digital inputs)
- */
-#define DAS08JR_AO_UPDATE_REG 0x03
-
-/* (W) analog output l.s.b. registers for 2 channels ("AOx" boards) */
-#define DAS08AOX_AO_LSB_REG(x) ((x) ? 0x0a : 0x08)
-/* (W) analog output m.s.b. registers for 2 channels ("AOx" boards) */
-#define DAS08AOX_AO_MSB_REG(x) ((x) ? 0x0b : 0x09)
-/*
- * (R) update analog outputs ("AOx" boards set for simultaneous output)
- * (any of the analog output registers could be used for this)
- */
-#define DAS08AOX_AO_UPDATE_REG 0x08
-
-/* gainlist same as _pgx_ below */
-
-static const struct comedi_lrange das08_pgl_ai_range = {
- 9, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange das08_pgh_ai_range = {
- 12, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.1),
- BIP_RANGE(0.05),
- BIP_RANGE(0.01),
- BIP_RANGE(0.005),
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange das08_pgm_ai_range = {
- 9, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.01),
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange *const das08_ai_lranges[] = {
- [das08_pg_none] = &range_unknown,
- [das08_bipolar5] = &range_bipolar5,
- [das08_pgh] = &das08_pgh_ai_range,
- [das08_pgl] = &das08_pgl_ai_range,
- [das08_pgm] = &das08_pgm_ai_range,
-};
-
-static const int das08_pgh_ai_gainlist[] = {
- 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7
-};
-static const int das08_pgl_ai_gainlist[] = { 8, 0, 2, 4, 6, 1, 3, 5, 7 };
-static const int das08_pgm_ai_gainlist[] = { 8, 0, 10, 12, 14, 9, 11, 13, 15 };
-
-static const int *const das08_ai_gainlists[] = {
- [das08_pg_none] = NULL,
- [das08_bipolar5] = NULL,
- [das08_pgh] = das08_pgh_ai_gainlist,
- [das08_pgl] = das08_pgl_ai_gainlist,
- [das08_pgm] = das08_pgm_ai_gainlist,
-};
-
-static int das08_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DAS08_STATUS_REG);
- if ((status & DAS08_STATUS_AI_BUSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int das08_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- const struct das08_board_struct *board = dev->board_ptr;
- struct das08_private_struct *devpriv = dev->private;
- int n;
- int chan;
- int range;
- int lsb, msb;
- int ret;
-
- chan = CR_CHAN(insn->chanspec);
- range = CR_RANGE(insn->chanspec);
-
- /* clear crap */
- inb(dev->iobase + DAS08_AI_LSB_REG);
- inb(dev->iobase + DAS08_AI_MSB_REG);
-
- /* set multiplexer */
- /* lock to prevent race with digital output */
- spin_lock(&dev->spinlock);
- devpriv->do_mux_bits &= ~DAS08_CONTROL_MUX_MASK;
- devpriv->do_mux_bits |= DAS08_CONTROL_MUX(chan);
- outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL_REG);
- spin_unlock(&dev->spinlock);
-
- if (devpriv->pg_gainlist) {
- /* set gain/range */
- range = CR_RANGE(insn->chanspec);
- outb(devpriv->pg_gainlist[range],
- dev->iobase + DAS08_GAIN_REG);
- }
-
- for (n = 0; n < insn->n; n++) {
- /* clear over-range bits for 16-bit boards */
- if (board->ai_nbits == 16)
- if (inb(dev->iobase + DAS08_AI_MSB_REG) & 0x80)
- dev_info(dev->class_dev, "over-range\n");
-
- /* trigger conversion */
- outb_p(0, dev->iobase + DAS08_AI_TRIG_REG);
-
- ret = comedi_timeout(dev, s, insn, das08_ai_eoc, 0);
- if (ret)
- return ret;
-
- msb = inb(dev->iobase + DAS08_AI_MSB_REG);
- lsb = inb(dev->iobase + DAS08_AI_LSB_REG);
- if (board->ai_encoding == das08_encode12) {
- data[n] = (lsb >> 4) | (msb << 4);
- } else if (board->ai_encoding == das08_pcm_encode12) {
- data[n] = (msb << 8) + lsb;
- } else if (board->ai_encoding == das08_encode16) {
- /*
- * "JR" 16-bit boards are sign-magnitude.
- *
- * XXX The manual seems to imply that 0 is full-scale
- * negative and 65535 is full-scale positive, but the
- * original COMEDI patch to add support for the
- * DAS08/JR/16 and DAS08/JR/16-AO boards have it
- * encoded as sign-magnitude. Assume the original
- * COMEDI code is correct for now.
- */
- unsigned int magnitude = lsb | ((msb & 0x7f) << 8);
-
- /*
- * MSB bit 7 is 0 for negative, 1 for positive voltage.
- * COMEDI 16-bit bipolar data value for 0V is 0x8000.
- */
- if (msb & 0x80)
- data[n] = BIT(15) + magnitude;
- else
- data[n] = BIT(15) - magnitude;
- } else {
- dev_err(dev->class_dev, "bug! unknown ai encoding\n");
- return -1;
- }
- }
-
- return n;
-}
-
-static int das08_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[0] = 0;
- data[1] = DAS08_STATUS_DI(inb(dev->iobase + DAS08_STATUS_REG));
-
- return insn->n;
-}
-
-static int das08_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct das08_private_struct *devpriv = dev->private;
-
- if (comedi_dio_update_state(s, data)) {
- /* prevent race with setting of analog input mux */
- spin_lock(&dev->spinlock);
- devpriv->do_mux_bits &= ~DAS08_CONTROL_DO_MASK;
- devpriv->do_mux_bits |= DAS08_CONTROL_DO(s->state);
- outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL_REG);
- spin_unlock(&dev->spinlock);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int das08jr_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[0] = 0;
- data[1] = inb(dev->iobase + DAS08JR_DI_REG);
-
- return insn->n;
-}
-
-static int das08jr_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DAS08JR_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void das08_ao_set_data(struct comedi_device *dev,
- unsigned int chan, unsigned int data)
-{
- const struct das08_board_struct *board = dev->board_ptr;
- unsigned char lsb;
- unsigned char msb;
-
- lsb = data & 0xff;
- msb = (data >> 8) & 0xff;
- if (board->is_jr) {
- outb(lsb, dev->iobase + DAS08JR_AO_LSB_REG(chan));
- outb(msb, dev->iobase + DAS08JR_AO_MSB_REG(chan));
- /* load DACs */
- inb(dev->iobase + DAS08JR_AO_UPDATE_REG);
- } else {
- outb(lsb, dev->iobase + DAS08AOX_AO_LSB_REG(chan));
- outb(msb, dev->iobase + DAS08AOX_AO_MSB_REG(chan));
- /* load DACs */
- inb(dev->iobase + DAS08AOX_AO_UPDATE_REG);
- }
-}
-
-static int das08_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- das08_ao_set_data(dev, chan, val);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
-{
- const struct das08_board_struct *board = dev->board_ptr;
- struct das08_private_struct *devpriv = dev->private;
- struct comedi_subdevice *s;
- int ret;
- int i;
-
- dev->iobase = iobase;
-
- dev->board_name = board->name;
-
- ret = comedi_alloc_subdevices(dev, 6);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* ai */
- if (board->ai_nbits) {
- s->type = COMEDI_SUBD_AI;
- /*
- * XXX some boards actually have differential
- * inputs instead of single ended.
- * The driver does nothing with arefs though,
- * so it's no big deal.
- */
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 8;
- s->maxdata = (1 << board->ai_nbits) - 1;
- s->range_table = das08_ai_lranges[board->ai_pg];
- s->insn_read = das08_ai_insn_read;
- devpriv->pg_gainlist = das08_ai_gainlists[board->ai_pg];
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[1];
- /* ao */
- if (board->ao_nbits) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = (1 << board->ao_nbits) - 1;
- s->range_table = &range_bipolar5;
- s->insn_write = das08_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* initialize all channels to 0V */
- for (i = 0; i < s->n_chan; i++) {
- s->readback[i] = s->maxdata / 2;
- das08_ao_set_data(dev, i, s->readback[i]);
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[2];
- /* di */
- if (board->di_nchan) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = board->di_nchan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = board->is_jr ? das08jr_di_insn_bits :
- das08_di_insn_bits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[3];
- /* do */
- if (board->do_nchan) {
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->do_nchan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = board->is_jr ? das08jr_do_insn_bits :
- das08_do_insn_bits;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[4];
- /* 8255 */
- if (board->i8255_offset != 0) {
- ret = subdev_8255_init(dev, s, NULL, board->i8255_offset);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Counter subdevice (8254) */
- s = &dev->subdevices[5];
- if (board->i8254_offset) {
- dev->pacer = comedi_8254_init(dev->iobase + board->i8254_offset,
- 0, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- comedi_8254_subdevice_init(s, dev->pacer);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(das08_common_attach);
-
-static int __init das08_init(void)
-{
- return 0;
-}
-module_init(das08_init);
-
-static void __exit das08_exit(void)
-{
-}
-module_exit(das08_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi common DAS08 support module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h
deleted file mode 100644
index ef65a7e504ee..000000000000
--- a/drivers/staging/comedi/drivers/das08.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * das08.h
- *
- * Header for common DAS08 support (used by ISA/PCI/PCMCIA drivers)
- *
- * Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-#ifndef _DAS08_H
-#define _DAS08_H
-
-#include <linux/types.h>
-
-struct comedi_device;
-
-/* different ways ai data is encoded in first two registers */
-enum das08_ai_encoding { das08_encode12, das08_encode16, das08_pcm_encode12 };
-/* types of ai range table used by different boards */
-enum das08_lrange {
- das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl, das08_pgm
-};
-
-struct das08_board_struct {
- const char *name;
- bool is_jr; /* true for 'JR' boards */
- unsigned int ai_nbits;
- enum das08_lrange ai_pg;
- enum das08_ai_encoding ai_encoding;
- unsigned int ao_nbits;
- unsigned int di_nchan;
- unsigned int do_nchan;
- unsigned int i8255_offset;
- unsigned int i8254_offset;
- unsigned int iosize; /* number of ioports used */
-};
-
-struct das08_private_struct {
- /* bits for do/mux register on boards without separate do register */
- unsigned int do_mux_bits;
- const unsigned int *pg_gainlist;
-};
-
-int das08_common_attach(struct comedi_device *dev, unsigned long iobase);
-
-#endif /* _DAS08_H */
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
deleted file mode 100644
index 223479f9ea3c..000000000000
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ /dev/null
@@ -1,104 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for DAS008 PCMCIA boards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * PCMCIA support code for this driver is adapted from the dummy_cs.c
- * driver of the Linux PCMCIA Card Services package.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
- */
-
-/*
- * Driver: das08_cs
- * Description: DAS-08 PCMCIA boards
- * Author: Warren Jasper, ds, Frank Hess
- * Devices: [ComputerBoards] PCM-DAS08 (pcm-das08)
- * Status: works
- *
- * This is the PCMCIA-specific support split off from the
- * das08 driver.
- *
- * Configuration Options: none, uses PCMCIA auto config
- *
- * Command support does not exist, but could be added for this board.
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pcmcia.h"
-
-#include "das08.h"
-
-static const struct das08_board_struct das08_cs_boards[] = {
- {
- .name = "pcm-das08",
- .ai_nbits = 12,
- .ai_pg = das08_bipolar5,
- .ai_encoding = das08_pcm_encode12,
- .di_nchan = 3,
- .do_nchan = 3,
- .iosize = 16,
- },
-};
-
-static int das08_cs_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- struct das08_private_struct *devpriv;
- unsigned long iobase;
- int ret;
-
- /* The das08 driver needs the board_ptr */
- dev->board_ptr = &das08_cs_boards[0];
-
- link->config_flags |= CONF_AUTO_SET_IO;
- ret = comedi_pcmcia_enable(dev, NULL);
- if (ret)
- return ret;
- iobase = link->resource[0]->start;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- return das08_common_attach(dev, iobase);
-}
-
-static struct comedi_driver driver_das08_cs = {
- .driver_name = "das08_cs",
- .module = THIS_MODULE,
- .auto_attach = das08_cs_auto_attach,
- .detach = comedi_pcmcia_disable,
-};
-
-static int das08_pcmcia_attach(struct pcmcia_device *link)
-{
- return comedi_pcmcia_auto_config(link, &driver_das08_cs);
-}
-
-static const struct pcmcia_device_id das08_cs_id_table[] = {
- PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4001),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, das08_cs_id_table);
-
-static struct pcmcia_driver das08_cs_driver = {
- .name = "pcm-das08",
- .owner = THIS_MODULE,
- .id_table = das08_cs_id_table,
- .probe = das08_pcmcia_attach,
- .remove = comedi_pcmcia_auto_unconfig,
-};
-module_comedi_pcmcia_driver(driver_das08_cs, das08_cs_driver);
-
-MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");
-MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
-MODULE_DESCRIPTION("Comedi driver for ComputerBoards DAS-08 PCMCIA boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das08_isa.c b/drivers/staging/comedi/drivers/das08_isa.c
deleted file mode 100644
index 8c4cfa821423..000000000000
--- a/drivers/staging/comedi/drivers/das08_isa.c
+++ /dev/null
@@ -1,190 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * das08_isa.c
- * comedi driver for DAS08 ISA/PC-104 boards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- * Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org>
- */
-
-/*
- * Driver: das08_isa
- * Description: DAS-08 ISA/PC-104 compatible boards
- * Devices: [Keithley Metrabyte] DAS08 (isa-das08),
- * [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm),
- * DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
- * DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
- * DAS08/JR-16-AO (das08jr-16-ao), PC104-DAS08 (pc104-das08),
- * DAS08/JR/16 (das08jr/16)
- * Author: Warren Jasper, ds, Frank Hess
- * Updated: Fri, 31 Aug 2012 19:19:06 +0100
- * Status: works
- *
- * This is the ISA/PC-104-specific support split off from the das08 driver.
- *
- * Configuration Options:
- * [0] - base io address
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include "das08.h"
-
-static const struct das08_board_struct das08_isa_boards[] = {
- {
- /* cio-das08.pdf */
- .name = "isa-das08",
- .ai_nbits = 12,
- .ai_pg = das08_pg_none,
- .ai_encoding = das08_encode12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8255_offset = 8,
- .i8254_offset = 4,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08pgx.pdf */
- .name = "das08-pgm",
- .ai_nbits = 12,
- .ai_pg = das08_pgm,
- .ai_encoding = das08_encode12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8255_offset = 0,
- .i8254_offset = 0x04,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08pgx.pdf */
- .name = "das08-pgh",
- .ai_nbits = 12,
- .ai_pg = das08_pgh,
- .ai_encoding = das08_encode12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8254_offset = 0x04,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08pgx.pdf */
- .name = "das08-pgl",
- .ai_nbits = 12,
- .ai_pg = das08_pgl,
- .ai_encoding = das08_encode12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8254_offset = 0x04,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08_aox.pdf */
- .name = "das08-aoh",
- .ai_nbits = 12,
- .ai_pg = das08_pgh,
- .ai_encoding = das08_encode12,
- .ao_nbits = 12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8255_offset = 0x0c,
- .i8254_offset = 0x04,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08_aox.pdf */
- .name = "das08-aol",
- .ai_nbits = 12,
- .ai_pg = das08_pgl,
- .ai_encoding = das08_encode12,
- .ao_nbits = 12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8255_offset = 0x0c,
- .i8254_offset = 0x04,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08_aox.pdf */
- .name = "das08-aom",
- .ai_nbits = 12,
- .ai_pg = das08_pgm,
- .ai_encoding = das08_encode12,
- .ao_nbits = 12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8255_offset = 0x0c,
- .i8254_offset = 0x04,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08-jr-ao.pdf */
- .name = "das08/jr-ao",
- .is_jr = true,
- .ai_nbits = 12,
- .ai_pg = das08_pg_none,
- .ai_encoding = das08_encode12,
- .ao_nbits = 12,
- .di_nchan = 8,
- .do_nchan = 8,
- .iosize = 16, /* unchecked */
- }, {
- /* cio-das08jr-16-ao.pdf */
- .name = "das08jr-16-ao",
- .is_jr = true,
- .ai_nbits = 16,
- .ai_pg = das08_pg_none,
- .ai_encoding = das08_encode16,
- .ao_nbits = 16,
- .di_nchan = 8,
- .do_nchan = 8,
- .i8254_offset = 0x04,
- .iosize = 16, /* unchecked */
- }, {
- .name = "pc104-das08",
- .ai_nbits = 12,
- .ai_pg = das08_pg_none,
- .ai_encoding = das08_encode12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8254_offset = 4,
- .iosize = 16, /* unchecked */
- }, {
- .name = "das08jr/16",
- .is_jr = true,
- .ai_nbits = 16,
- .ai_pg = das08_pg_none,
- .ai_encoding = das08_encode16,
- .di_nchan = 8,
- .do_nchan = 8,
- .iosize = 16, /* unchecked */
- },
-};
-
-static int das08_isa_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct das08_board_struct *board = dev->board_ptr;
- struct das08_private_struct *devpriv;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], board->iosize);
- if (ret)
- return ret;
-
- return das08_common_attach(dev, dev->iobase);
-}
-
-static struct comedi_driver das08_isa_driver = {
- .driver_name = "isa-das08",
- .module = THIS_MODULE,
- .attach = das08_isa_attach,
- .detach = comedi_legacy_detach,
- .board_name = &das08_isa_boards[0].name,
- .num_names = ARRAY_SIZE(das08_isa_boards),
- .offset = sizeof(das08_isa_boards[0]),
-};
-module_comedi_driver(das08_isa_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c
deleted file mode 100644
index 1cd903336a4c..000000000000
--- a/drivers/staging/comedi/drivers/das08_pci.c
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * das08_pci.c
- * comedi driver for DAS08 PCI boards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- * Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org>
- */
-
-/*
- * Driver: das08_pci
- * Description: DAS-08 PCI compatible boards
- * Devices: [ComputerBoards] PCI-DAS08 (pci-das08)
- * Author: Warren Jasper, ds, Frank Hess
- * Updated: Fri, 31 Aug 2012 19:19:06 +0100
- * Status: works
- *
- * This is the PCI-specific support split off from the das08 driver.
- *
- * Configuration Options: not applicable, uses PCI auto config
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-#include "das08.h"
-
-static const struct das08_board_struct das08_pci_boards[] = {
- {
- .name = "pci-das08",
- .ai_nbits = 12,
- .ai_pg = das08_bipolar5,
- .ai_encoding = das08_encode12,
- .di_nchan = 3,
- .do_nchan = 4,
- .i8254_offset = 4,
- .iosize = 8,
- },
-};
-
-static int das08_pci_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pdev = comedi_to_pci_dev(dev);
- struct das08_private_struct *devpriv;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- /* The das08 driver needs the board_ptr */
- dev->board_ptr = &das08_pci_boards[0];
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pdev, 2);
-
- return das08_common_attach(dev, dev->iobase);
-}
-
-static struct comedi_driver das08_pci_comedi_driver = {
- .driver_name = "pci-das08",
- .module = THIS_MODULE,
- .auto_attach = das08_pci_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int das08_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &das08_pci_comedi_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id das08_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0029) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, das08_pci_table);
-
-static struct pci_driver das08_pci_driver = {
- .name = "pci-das08",
- .id_table = das08_pci_table,
- .probe = das08_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(das08_pci_comedi_driver, das08_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
deleted file mode 100644
index 4ac2622b0fac..000000000000
--- a/drivers/staging/comedi/drivers/das16.c
+++ /dev/null
@@ -1,1200 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * das16.c
- * DAS16 driver
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
- * Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-/*
- * Driver: das16
- * Description: DAS16 compatible boards
- * Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
- * Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
- * DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
- * DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
- * DAS-1602 (das-1602),
- * [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
- * PC104-DAS16JR/16 (pc104-das16jr/16), CIO-DAS16 (cio-das16),
- * CIO-DAS16F (cio-das16/f), CIO-DAS16/JR (cio-das16/jr),
- * CIO-DAS16JR/16 (cio-das16jr/16), CIO-DAS1401/12 (cio-das1401/12),
- * CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
- * CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
- * CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
- * Status: works
- * Updated: 2003-10-12
- *
- * A rewrite of the das16 and das1600 drivers.
- *
- * Options:
- * [0] - base io address
- * [1] - irq (does nothing, irq is not used anymore)
- * [2] - dma channel (optional, required for comedi_command support)
- * [3] - master clock speed in MHz (optional, 1 or 10, ignored if
- * board can probe clock, defaults to 1)
- * [4] - analog input range lowest voltage in microvolts (optional,
- * only useful if your board does not have software
- * programmable gain)
- * [5] - analog input range highest voltage in microvolts (optional,
- * only useful if board does not have software programmable
- * gain)
- * [6] - analog output range lowest voltage in microvolts (optional)
- * [7] - analog output range highest voltage in microvolts (optional)
- *
- * Passing a zero for an option is the same as leaving it unspecified.
- */
-
-/*
- * Testing and debugging help provided by Daniel Koch.
- *
- * Keithley Manuals:
- * 2309.PDF (das16)
- * 4919.PDF (das1400, 1600)
- * 4922.PDF (das-1400)
- * 4923.PDF (das1200, 1400, 1600)
- *
- * Computer boards manuals also available from their website
- * www.measurementcomputing.com
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-#include "comedi_8254.h"
-#include "8255.h"
-
-#define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */
-
-/*
- * Register I/O map
- */
-#define DAS16_TRIG_REG 0x00
-#define DAS16_AI_LSB_REG 0x00
-#define DAS16_AI_MSB_REG 0x01
-#define DAS16_MUX_REG 0x02
-#define DAS16_DIO_REG 0x03
-#define DAS16_AO_LSB_REG(x) ((x) ? 0x06 : 0x04)
-#define DAS16_AO_MSB_REG(x) ((x) ? 0x07 : 0x05)
-#define DAS16_STATUS_REG 0x08
-#define DAS16_STATUS_BUSY BIT(7)
-#define DAS16_STATUS_UNIPOLAR BIT(6)
-#define DAS16_STATUS_MUXBIT BIT(5)
-#define DAS16_STATUS_INT BIT(4)
-#define DAS16_CTRL_REG 0x09
-#define DAS16_CTRL_INTE BIT(7)
-#define DAS16_CTRL_IRQ(x) (((x) & 0x7) << 4)
-#define DAS16_CTRL_DMAE BIT(2)
-#define DAS16_CTRL_PACING_MASK (3 << 0)
-#define DAS16_CTRL_INT_PACER (3 << 0)
-#define DAS16_CTRL_EXT_PACER (2 << 0)
-#define DAS16_CTRL_SOFT_PACER (0 << 0)
-#define DAS16_PACER_REG 0x0a
-#define DAS16_PACER_BURST_LEN(x) (((x) & 0xf) << 4)
-#define DAS16_PACER_CTR0 BIT(1)
-#define DAS16_PACER_TRIG0 BIT(0)
-#define DAS16_GAIN_REG 0x0b
-#define DAS16_TIMER_BASE_REG 0x0c /* to 0x0f */
-
-#define DAS1600_CONV_REG 0x404
-#define DAS1600_CONV_DISABLE BIT(6)
-#define DAS1600_BURST_REG 0x405
-#define DAS1600_BURST_VAL BIT(6)
-#define DAS1600_ENABLE_REG 0x406
-#define DAS1600_ENABLE_VAL BIT(6)
-#define DAS1600_STATUS_REG 0x407
-#define DAS1600_STATUS_BME BIT(6)
-#define DAS1600_STATUS_ME BIT(5)
-#define DAS1600_STATUS_CD BIT(4)
-#define DAS1600_STATUS_WS BIT(1)
-#define DAS1600_STATUS_CLK_10MHZ BIT(0)
-
-static const struct comedi_lrange range_das1x01_bip = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_das1x01_unip = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_das1x02_bip = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_das1x02_unip = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_das16jr = {
- 9, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_das16jr_16 = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
-static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
-static const int das1600_gainlist[] = { 0, 1, 2, 3 };
-
-enum {
- das16_pg_none = 0,
- das16_pg_16jr,
- das16_pg_16jr_16,
- das16_pg_1601,
- das16_pg_1602,
-};
-
-static const int *const das16_gainlists[] = {
- NULL,
- das16jr_gainlist,
- das16jr_16_gainlist,
- das1600_gainlist,
- das1600_gainlist,
-};
-
-static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
- &range_unknown,
- &range_das16jr,
- &range_das16jr_16,
- &range_das1x01_unip,
- &range_das1x02_unip,
-};
-
-static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
- &range_unknown,
- &range_das16jr,
- &range_das16jr_16,
- &range_das1x01_bip,
- &range_das1x02_bip,
-};
-
-struct das16_board {
- const char *name;
- unsigned int ai_maxdata;
- unsigned int ai_speed; /* max conversion speed in nanosec */
- unsigned int ai_pg;
- unsigned int has_ao:1;
- unsigned int has_8255:1;
-
- unsigned int i8255_offset;
-
- unsigned int size;
- unsigned int id;
-};
-
-static const struct das16_board das16_boards[] = {
- {
- .name = "das-16",
- .ai_maxdata = 0x0fff,
- .ai_speed = 15000,
- .ai_pg = das16_pg_none,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x10,
- .size = 0x14,
- .id = 0x00,
- }, {
- .name = "das-16g",
- .ai_maxdata = 0x0fff,
- .ai_speed = 15000,
- .ai_pg = das16_pg_none,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x10,
- .size = 0x14,
- .id = 0x00,
- }, {
- .name = "das-16f",
- .ai_maxdata = 0x0fff,
- .ai_speed = 8500,
- .ai_pg = das16_pg_none,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x10,
- .size = 0x14,
- .id = 0x00,
- }, {
- .name = "cio-das16",
- .ai_maxdata = 0x0fff,
- .ai_speed = 20000,
- .ai_pg = das16_pg_none,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x10,
- .size = 0x14,
- .id = 0x80,
- }, {
- .name = "cio-das16/f",
- .ai_maxdata = 0x0fff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_none,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x10,
- .size = 0x14,
- .id = 0x80,
- }, {
- .name = "cio-das16/jr",
- .ai_maxdata = 0x0fff,
- .ai_speed = 7692,
- .ai_pg = das16_pg_16jr,
- .size = 0x10,
- .id = 0x00,
- }, {
- .name = "pc104-das16jr",
- .ai_maxdata = 0x0fff,
- .ai_speed = 3300,
- .ai_pg = das16_pg_16jr,
- .size = 0x10,
- .id = 0x00,
- }, {
- .name = "cio-das16jr/16",
- .ai_maxdata = 0xffff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_16jr_16,
- .size = 0x10,
- .id = 0x00,
- }, {
- .name = "pc104-das16jr/16",
- .ai_maxdata = 0xffff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_16jr_16,
- .size = 0x10,
- .id = 0x00,
- }, {
- .name = "das-1201",
- .ai_maxdata = 0x0fff,
- .ai_speed = 20000,
- .ai_pg = das16_pg_none,
- .has_8255 = 1,
- .i8255_offset = 0x400,
- .size = 0x408,
- .id = 0x20,
- }, {
- .name = "das-1202",
- .ai_maxdata = 0x0fff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_none,
- .has_8255 = 1,
- .i8255_offset = 0x400,
- .size = 0x408,
- .id = 0x20,
- }, {
- .name = "das-1401",
- .ai_maxdata = 0x0fff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_1601,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "das-1402",
- .ai_maxdata = 0x0fff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_1602,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "das-1601",
- .ai_maxdata = 0x0fff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_1601,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x400,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "das-1602",
- .ai_maxdata = 0x0fff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_1602,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x400,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "cio-das1401/12",
- .ai_maxdata = 0x0fff,
- .ai_speed = 6250,
- .ai_pg = das16_pg_1601,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "cio-das1402/12",
- .ai_maxdata = 0x0fff,
- .ai_speed = 6250,
- .ai_pg = das16_pg_1602,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "cio-das1402/16",
- .ai_maxdata = 0xffff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_1602,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "cio-das1601/12",
- .ai_maxdata = 0x0fff,
- .ai_speed = 6250,
- .ai_pg = das16_pg_1601,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x400,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "cio-das1602/12",
- .ai_maxdata = 0x0fff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_1602,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x400,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "cio-das1602/16",
- .ai_maxdata = 0xffff,
- .ai_speed = 10000,
- .ai_pg = das16_pg_1602,
- .has_ao = 1,
- .has_8255 = 1,
- .i8255_offset = 0x400,
- .size = 0x408,
- .id = 0xc0,
- }, {
- .name = "cio-das16/330",
- .ai_maxdata = 0x0fff,
- .ai_speed = 3030,
- .ai_pg = das16_pg_16jr,
- .size = 0x14,
- .id = 0xf0,
- },
-};
-
-/*
- * Period for timer interrupt in jiffies. It's a function
- * to deal with possibility of dynamic HZ patches
- */
-static inline int timer_period(void)
-{
- return HZ / 20;
-}
-
-struct das16_private_struct {
- struct comedi_isadma *dma;
- struct comedi_device *dev;
- unsigned int clockbase;
- unsigned int ctrl_reg;
- unsigned int divisor1;
- unsigned int divisor2;
- struct timer_list timer;
- unsigned long extra_iobase;
- unsigned int can_burst:1;
- unsigned int timer_running:1;
-};
-
-static void das16_ai_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int unread_samples)
-{
- struct das16_private_struct *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
- unsigned int nsamples;
-
- /*
- * Determine dma size based on the buffer size plus the number of
- * unread samples and the number of samples remaining in the command.
- */
- nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
- if (nsamples > unread_samples) {
- nsamples -= unread_samples;
- desc->size = comedi_samples_to_bytes(s, nsamples);
- comedi_isadma_program(desc);
- }
-}
-
-static void das16_interrupt(struct comedi_device *dev)
-{
- struct das16_private_struct *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned long spin_flags;
- unsigned int residue;
- unsigned int nbytes;
- unsigned int nsamples;
-
- spin_lock_irqsave(&dev->spinlock, spin_flags);
- if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) {
- spin_unlock_irqrestore(&dev->spinlock, spin_flags);
- return;
- }
-
- /*
- * The pc104-das16jr (at least) has problems if the dma
- * transfer is interrupted in the middle of transferring
- * a 16 bit sample.
- */
- residue = comedi_isadma_disable_on_sample(desc->chan,
- comedi_bytes_per_sample(s));
-
- /* figure out how many samples to read */
- if (residue > desc->size) {
- dev_err(dev->class_dev, "residue > transfer size!\n");
- async->events |= COMEDI_CB_ERROR;
- nbytes = 0;
- } else {
- nbytes = desc->size - residue;
- }
- nsamples = comedi_bytes_to_samples(s, nbytes);
-
- /* restart DMA if more samples are needed */
- if (nsamples) {
- dma->cur_dma = 1 - dma->cur_dma;
- das16_ai_setup_dma(dev, s, nsamples);
- }
-
- spin_unlock_irqrestore(&dev->spinlock, spin_flags);
-
- comedi_buf_write_samples(s, desc->virt_addr, nsamples);
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
-}
-
-static void das16_timer_interrupt(struct timer_list *t)
-{
- struct das16_private_struct *devpriv = from_timer(devpriv, t, timer);
- struct comedi_device *dev = devpriv->dev;
- unsigned long flags;
-
- das16_interrupt(dev);
-
- spin_lock_irqsave(&dev->spinlock, flags);
- if (devpriv->timer_running)
- mod_timer(&devpriv->timer, jiffies + timer_period());
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static void das16_ai_set_mux_range(struct comedi_device *dev,
- unsigned int first_chan,
- unsigned int last_chan,
- unsigned int range)
-{
- const struct das16_board *board = dev->board_ptr;
-
- /* set multiplexer */
- outb(first_chan | (last_chan << 4), dev->iobase + DAS16_MUX_REG);
-
- /* some boards do not have programmable gain */
- if (board->ai_pg == das16_pg_none)
- return;
-
- /*
- * Set gain (this is also burst rate register but according to
- * computer boards manual, burst rate does nothing, even on
- * keithley cards).
- */
- outb((das16_gainlists[board->ai_pg])[range],
- dev->iobase + DAS16_GAIN_REG);
-}
-
-static int das16_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- if (chan != ((chan0 + i) % s->n_chan)) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- return -EINVAL;
- }
-
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must all have the same gain\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct das16_board *board = dev->board_ptr;
- struct das16_private_struct *devpriv = dev->private;
- int err = 0;
- unsigned int trig_mask;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
-
- trig_mask = TRIG_FOLLOW;
- if (devpriv->can_burst)
- trig_mask |= TRIG_TIMER | TRIG_EXT;
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, trig_mask);
-
- trig_mask = TRIG_TIMER | TRIG_EXT;
- if (devpriv->can_burst)
- trig_mask |= TRIG_NOW;
- err |= comedi_check_trigger_src(&cmd->convert_src, trig_mask);
-
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- /* make sure scan_begin_src and convert_src don't conflict */
- if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
- err |= -EINVAL;
- if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- /* check against maximum frequency */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- board->ai_speed *
- cmd->chanlist_len);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- }
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up arguments */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= das16_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
- unsigned int flags)
-{
- comedi_8254_cascade_ns_to_timer(dev->pacer, &ns, flags);
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
-
- return ns;
-}
-
-static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct das16_private_struct *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int first_chan = CR_CHAN(cmd->chanlist[0]);
- unsigned int last_chan = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
- unsigned int range = CR_RANGE(cmd->chanlist[0]);
- unsigned int byte;
- unsigned long flags;
-
- if (cmd->flags & CMDF_PRIORITY) {
- dev_err(dev->class_dev,
- "isa dma transfers cannot be performed with CMDF_PRIORITY, aborting\n");
- return -1;
- }
-
- if (devpriv->can_burst)
- outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG);
-
- /* set mux and range for chanlist scan */
- das16_ai_set_mux_range(dev, first_chan, last_chan, range);
-
- /* set counter mode and counts */
- cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags);
-
- /* enable counters */
- byte = 0;
- if (devpriv->can_burst) {
- if (cmd->convert_src == TRIG_NOW) {
- outb(DAS1600_BURST_VAL,
- dev->iobase + DAS1600_BURST_REG);
- /* set burst length */
- byte |= DAS16_PACER_BURST_LEN(cmd->chanlist_len - 1);
- } else {
- outb(0, dev->iobase + DAS1600_BURST_REG);
- }
- }
- outb(byte, dev->iobase + DAS16_PACER_REG);
-
- /* set up dma transfer */
- dma->cur_dma = 0;
- das16_ai_setup_dma(dev, s, 0);
-
- /* set up timer */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->timer_running = 1;
- devpriv->timer.expires = jiffies + timer_period();
- add_timer(&devpriv->timer);
-
- /* enable DMA interrupt with external or internal pacing */
- devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | DAS16_CTRL_PACING_MASK);
- devpriv->ctrl_reg |= DAS16_CTRL_DMAE;
- if (cmd->convert_src == TRIG_EXT)
- devpriv->ctrl_reg |= DAS16_CTRL_EXT_PACER;
- else
- devpriv->ctrl_reg |= DAS16_CTRL_INT_PACER;
- outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
-
- if (devpriv->can_burst)
- outb(0, dev->iobase + DAS1600_CONV_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return 0;
-}
-
-static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct das16_private_struct *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
-
- /* disable interrupts, dma and pacer clocked conversions */
- devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | DAS16_CTRL_DMAE |
- DAS16_CTRL_PACING_MASK);
- outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
-
- comedi_isadma_disable(dma->chan);
-
- /* disable SW timer */
- if (devpriv->timer_running) {
- devpriv->timer_running = 0;
- del_timer(&devpriv->timer);
- }
-
- if (devpriv->can_burst)
- outb(0, dev->iobase + DAS1600_BURST_REG);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return 0;
-}
-
-static void das16_ai_munge(struct comedi_device *dev,
- struct comedi_subdevice *s, void *array,
- unsigned int num_bytes,
- unsigned int start_chan_index)
-{
- unsigned short *data = array;
- unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
- unsigned int i;
- __le16 *buf = array;
-
- for (i = 0; i < num_samples; i++) {
- data[i] = le16_to_cpu(buf[i]);
- if (s->maxdata == 0x0fff)
- data[i] >>= 4;
- data[i] &= s->maxdata;
- }
-}
-
-static int das16_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DAS16_STATUS_REG);
- if ((status & DAS16_STATUS_BUSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int das16_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- int ret;
- int i;
-
- /* set mux and range for single channel */
- das16_ai_set_mux_range(dev, chan, chan, range);
-
- for (i = 0; i < insn->n; i++) {
- /* trigger conversion */
- outb_p(0, dev->iobase + DAS16_TRIG_REG);
-
- ret = comedi_timeout(dev, s, insn, das16_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inb(dev->iobase + DAS16_AI_MSB_REG) << 8;
- val |= inb(dev->iobase + DAS16_AI_LSB_REG);
- if (s->maxdata == 0x0fff)
- val >>= 4;
- val &= s->maxdata;
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int das16_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- val <<= 4;
-
- outb(val & 0xff, dev->iobase + DAS16_AO_LSB_REG(chan));
- outb((val >> 8) & 0xff, dev->iobase + DAS16_AO_MSB_REG(chan));
- }
-
- return insn->n;
-}
-
-static int das16_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + DAS16_DIO_REG) & 0xf;
-
- return insn->n;
-}
-
-static int das16_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DAS16_DIO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct das16_board *board = dev->board_ptr;
- int diobits;
-
- /* diobits indicates boards */
- diobits = inb(dev->iobase + DAS16_DIO_REG) & 0xf0;
- if (board->id != diobits) {
- dev_err(dev->class_dev,
- "requested board's id bits are incorrect (0x%x != 0x%x)\n",
- board->id, diobits);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void das16_reset(struct comedi_device *dev)
-{
- outb(0, dev->iobase + DAS16_STATUS_REG);
- outb(0, dev->iobase + DAS16_CTRL_REG);
- outb(0, dev->iobase + DAS16_PACER_REG);
-}
-
-static void das16_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
-{
- struct das16_private_struct *devpriv = dev->private;
-
- timer_setup(&devpriv->timer, das16_timer_interrupt, 0);
-
- /* only DMA channels 3 and 1 are valid */
- if (!(dma_chan == 1 || dma_chan == 3))
- return;
-
- /* DMA uses two buffers */
- devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
- DAS16_DMA_SIZE, COMEDI_ISADMA_READ);
-}
-
-static void das16_free_dma(struct comedi_device *dev)
-{
- struct das16_private_struct *devpriv = dev->private;
-
- if (devpriv) {
- del_timer_sync(&devpriv->timer);
- comedi_isadma_free(devpriv->dma);
- }
-}
-
-static const struct comedi_lrange *das16_ai_range(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_devconfig *it,
- unsigned int pg_type,
- unsigned int status)
-{
- unsigned int min = it->options[4];
- unsigned int max = it->options[5];
-
- /* get any user-defined input range */
- if (pg_type == das16_pg_none && (min || max)) {
- struct comedi_lrange *lrange;
- struct comedi_krange *krange;
-
- /* allocate single-range range table */
- lrange = comedi_alloc_spriv(s,
- sizeof(*lrange) + sizeof(*krange));
- if (!lrange)
- return &range_unknown;
-
- /* initialize ai range */
- lrange->length = 1;
- krange = lrange->range;
- krange->min = min;
- krange->max = max;
- krange->flags = UNIT_volt;
-
- return lrange;
- }
-
- /* use software programmable range */
- if (status & DAS16_STATUS_UNIPOLAR)
- return das16_ai_uni_lranges[pg_type];
- return das16_ai_bip_lranges[pg_type];
-}
-
-static const struct comedi_lrange *das16_ao_range(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_devconfig *it)
-{
- unsigned int min = it->options[6];
- unsigned int max = it->options[7];
-
- /* get any user-defined output range */
- if (min || max) {
- struct comedi_lrange *lrange;
- struct comedi_krange *krange;
-
- /* allocate single-range range table */
- lrange = comedi_alloc_spriv(s,
- sizeof(*lrange) + sizeof(*krange));
- if (!lrange)
- return &range_unknown;
-
- /* initialize ao range */
- lrange->length = 1;
- krange = lrange->range;
- krange->min = min;
- krange->max = max;
- krange->flags = UNIT_volt;
-
- return lrange;
- }
-
- return &range_unknown;
-}
-
-static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct das16_board *board = dev->board_ptr;
- struct das16_private_struct *devpriv;
- struct comedi_subdevice *s;
- unsigned int osc_base;
- unsigned int status;
- int ret;
-
- /* check that clock setting is valid */
- if (it->options[3]) {
- if (it->options[3] != 1 && it->options[3] != 10) {
- dev_err(dev->class_dev,
- "Invalid option. Master clock must be set to 1 or 10 (MHz)\n");
- return -EINVAL;
- }
- }
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
- devpriv->dev = dev;
-
- if (board->size < 0x400) {
- ret = comedi_request_region(dev, it->options[0], board->size);
- if (ret)
- return ret;
- } else {
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
- /* Request an additional region for the 8255 */
- ret = __comedi_request_region(dev, dev->iobase + 0x400,
- board->size & 0x3ff);
- if (ret)
- return ret;
- devpriv->extra_iobase = dev->iobase + 0x400;
- devpriv->can_burst = 1;
- }
-
- /* probe id bits to make sure they are consistent */
- if (das16_probe(dev, it))
- return -EINVAL;
-
- /* get master clock speed */
- osc_base = I8254_OSC_BASE_1MHZ;
- if (devpriv->can_burst) {
- status = inb(dev->iobase + DAS1600_STATUS_REG);
- if (status & DAS1600_STATUS_CLK_10MHZ)
- osc_base = I8254_OSC_BASE_10MHZ;
- } else {
- if (it->options[3])
- osc_base = I8254_OSC_BASE_1MHZ / it->options[3];
- }
-
- dev->pacer = comedi_8254_init(dev->iobase + DAS16_TIMER_BASE_REG,
- osc_base, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- das16_alloc_dma(dev, it->options[2]);
-
- ret = comedi_alloc_subdevices(dev, 4 + board->has_8255);
- if (ret)
- return ret;
-
- status = inb(dev->iobase + DAS16_STATUS_REG);
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE;
- if (status & DAS16_STATUS_MUXBIT) {
- s->subdev_flags |= SDF_GROUND;
- s->n_chan = 16;
- } else {
- s->subdev_flags |= SDF_DIFF;
- s->n_chan = 8;
- }
- s->len_chanlist = s->n_chan;
- s->maxdata = board->ai_maxdata;
- s->range_table = das16_ai_range(dev, s, it, board->ai_pg, status);
- s->insn_read = das16_ai_insn_read;
- if (devpriv->dma) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->do_cmdtest = das16_cmd_test;
- s->do_cmd = das16_cmd_exec;
- s->cancel = das16_cancel;
- s->munge = das16_ai_munge;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = das16_ao_range(dev, s, it);
- s->insn_write = das16_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das16_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das16_do_insn_bits;
-
- /* initialize digital output lines */
- outb(s->state, dev->iobase + DAS16_DIO_REG);
-
- /* 8255 Digital I/O subdevice */
- if (board->has_8255) {
- s = &dev->subdevices[4];
- ret = subdev_8255_init(dev, s, NULL, board->i8255_offset);
- if (ret)
- return ret;
- }
-
- das16_reset(dev);
- /* set the interrupt level */
- devpriv->ctrl_reg = DAS16_CTRL_IRQ(dev->irq);
- outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
-
- if (devpriv->can_burst) {
- outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE_REG);
- outb(0, dev->iobase + DAS1600_CONV_REG);
- outb(0, dev->iobase + DAS1600_BURST_REG);
- }
-
- return 0;
-}
-
-static void das16_detach(struct comedi_device *dev)
-{
- const struct das16_board *board = dev->board_ptr;
- struct das16_private_struct *devpriv = dev->private;
-
- if (devpriv) {
- if (dev->iobase)
- das16_reset(dev);
- das16_free_dma(dev);
-
- if (devpriv->extra_iobase)
- release_region(devpriv->extra_iobase,
- board->size & 0x3ff);
- }
-
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver das16_driver = {
- .driver_name = "das16",
- .module = THIS_MODULE,
- .attach = das16_attach,
- .detach = das16_detach,
- .board_name = &das16_boards[0].name,
- .num_names = ARRAY_SIZE(das16_boards),
- .offset = sizeof(das16_boards[0]),
-};
-module_comedi_driver(das16_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for DAS16 compatible boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
deleted file mode 100644
index 75f3dbbe97ac..000000000000
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ /dev/null
@@ -1,622 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for CIO-DAS16/M1
- * Author: Frank Mori Hess, based on code from the das16 driver.
- * Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: das16m1
- * Description: CIO-DAS16/M1
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Devices: [Measurement Computing] CIO-DAS16/M1 (das16m1)
- * Status: works
- *
- * This driver supports a single board - the CIO-DAS16/M1. As far as I know,
- * there are no other boards that have the same register layout. Even the
- * CIO-DAS16/M1/16 is significantly different.
- *
- * I was _barely_ able to reach the full 1 MHz capability of this board, using
- * a hard real-time interrupt (set the TRIG_RT flag in your struct comedi_cmd
- * and use rtlinux or RTAI). The board can't do dma, so the bottleneck is
- * pulling the data across the ISA bus. I timed the interrupt handler, and it
- * took my computer ~470 microseconds to pull 512 samples from the board. So
- * at 1 Mhz sampling rate, expect your CPU to be spending almost all of its
- * time in the interrupt handler.
- *
- * This board has some unusual restrictions for its channel/gain list. If the
- * list has 2 or more channels in it, then two conditions must be satisfied:
- * (1) - even/odd channels must appear at even/odd indices in the list
- * (2) - the list must have an even number of entries.
- *
- * Configuration options:
- * [0] - base io address
- * [1] - irq (optional, but you probably want it)
- *
- * irq can be omitted, although the cmd interface will not work without it.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include "../comedidev.h"
-
-#include "8255.h"
-#include "comedi_8254.h"
-
-/*
- * Register map (dev->iobase)
- */
-#define DAS16M1_AI_REG 0x00 /* 16-bit register */
-#define DAS16M1_AI_TO_CHAN(x) (((x) >> 0) & 0xf)
-#define DAS16M1_AI_TO_SAMPLE(x) (((x) >> 4) & 0xfff)
-#define DAS16M1_CS_REG 0x02
-#define DAS16M1_CS_EXT_TRIG BIT(0)
-#define DAS16M1_CS_OVRUN BIT(5)
-#define DAS16M1_CS_IRQDATA BIT(7)
-#define DAS16M1_DI_REG 0x03
-#define DAS16M1_DO_REG 0x03
-#define DAS16M1_CLR_INTR_REG 0x04
-#define DAS16M1_INTR_CTRL_REG 0x05
-#define DAS16M1_INTR_CTRL_PACER(x) (((x) & 0x3) << 0)
-#define DAS16M1_INTR_CTRL_PACER_EXT DAS16M1_INTR_CTRL_PACER(2)
-#define DAS16M1_INTR_CTRL_PACER_INT DAS16M1_INTR_CTRL_PACER(3)
-#define DAS16M1_INTR_CTRL_PACER_MASK DAS16M1_INTR_CTRL_PACER(3)
-#define DAS16M1_INTR_CTRL_IRQ(x) (((x) & 0x7) << 4)
-#define DAS16M1_INTR_CTRL_INTE BIT(7)
-#define DAS16M1_Q_ADDR_REG 0x06
-#define DAS16M1_Q_REG 0x07
-#define DAS16M1_Q_CHAN(x) (((x) & 0x7) << 0)
-#define DAS16M1_Q_RANGE(x) (((x) & 0xf) << 4)
-#define DAS16M1_8254_IOBASE1 0x08
-#define DAS16M1_8254_IOBASE2 0x0c
-#define DAS16M1_8255_IOBASE 0x400
-#define DAS16M1_8254_IOBASE3 0x404
-
-#define DAS16M1_SIZE2 0x08
-
-#define DAS16M1_AI_FIFO_SZ 1024 /* # samples */
-
-static const struct comedi_lrange range_das16m1 = {
- 9, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- BIP_RANGE(10)
- }
-};
-
-struct das16m1_private {
- struct comedi_8254 *counter;
- unsigned int intr_ctrl;
- unsigned int adc_count;
- u16 initial_hw_count;
- unsigned short ai_buffer[DAS16M1_AI_FIFO_SZ];
- unsigned long extra_iobase;
-};
-
-static void das16m1_ai_set_queue(struct comedi_device *dev,
- unsigned int *chanspec, unsigned int len)
-{
- unsigned int i;
-
- for (i = 0; i < len; i++) {
- unsigned int chan = CR_CHAN(chanspec[i]);
- unsigned int range = CR_RANGE(chanspec[i]);
-
- outb(i, dev->iobase + DAS16M1_Q_ADDR_REG);
- outb(DAS16M1_Q_CHAN(chan) | DAS16M1_Q_RANGE(range),
- dev->iobase + DAS16M1_Q_REG);
- }
-}
-
-static void das16m1_ai_munge(struct comedi_device *dev,
- struct comedi_subdevice *s,
- void *data, unsigned int num_bytes,
- unsigned int start_chan_index)
-{
- unsigned short *array = data;
- unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes);
- unsigned int i;
-
- /*
- * The fifo values have the channel number in the lower 4-bits and
- * the sample in the upper 12-bits. This just shifts the values
- * to remove the channel numbers.
- */
- for (i = 0; i < nsamples; i++)
- array[i] = DAS16M1_AI_TO_SAMPLE(array[i]);
-}
-
-static int das16m1_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int i;
-
- if (cmd->chanlist_len == 1)
- return 0;
-
- if ((cmd->chanlist_len % 2) != 0) {
- dev_dbg(dev->class_dev,
- "chanlist must be of even length or length 1\n");
- return -EINVAL;
- }
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if ((i % 2) != (chan % 2)) {
- dev_dbg(dev->class_dev,
- "even/odd channels must go have even/odd chanlist indices\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int das16m1_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER)
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 1000);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- unsigned int arg = cmd->convert_arg;
-
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= das16m1_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int das16m1_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das16m1_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int byte;
-
- /* set software count */
- devpriv->adc_count = 0;
-
- /*
- * Initialize lower half of hardware counter, used to determine how
- * many samples are in fifo. Value doesn't actually load into counter
- * until counter's next clock (the next a/d conversion).
- */
- comedi_8254_set_mode(devpriv->counter, 1, I8254_MODE2 | I8254_BINARY);
- comedi_8254_write(devpriv->counter, 1, 0);
-
- /*
- * Remember current reading of counter so we know when counter has
- * actually been loaded.
- */
- devpriv->initial_hw_count = comedi_8254_read(devpriv->counter, 1);
-
- das16m1_ai_set_queue(dev, cmd->chanlist, cmd->chanlist_len);
-
- /* enable interrupts and set internal pacer counter mode and counts */
- devpriv->intr_ctrl &= ~DAS16M1_INTR_CTRL_PACER_MASK;
- if (cmd->convert_src == TRIG_TIMER) {
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- devpriv->intr_ctrl |= DAS16M1_INTR_CTRL_PACER_INT;
- } else { /* TRIG_EXT */
- devpriv->intr_ctrl |= DAS16M1_INTR_CTRL_PACER_EXT;
- }
-
- /* set control & status register */
- byte = 0;
- /*
- * If we are using external start trigger (also board dislikes having
- * both start and conversion triggers external simultaneously).
- */
- if (cmd->start_src == TRIG_EXT && cmd->convert_src != TRIG_EXT)
- byte |= DAS16M1_CS_EXT_TRIG;
-
- outb(byte, dev->iobase + DAS16M1_CS_REG);
-
- /* clear interrupt */
- outb(0, dev->iobase + DAS16M1_CLR_INTR_REG);
-
- devpriv->intr_ctrl |= DAS16M1_INTR_CTRL_INTE;
- outb(devpriv->intr_ctrl, dev->iobase + DAS16M1_INTR_CTRL_REG);
-
- return 0;
-}
-
-static int das16m1_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das16m1_private *devpriv = dev->private;
-
- /* disable interrupts and pacer */
- devpriv->intr_ctrl &= ~(DAS16M1_INTR_CTRL_INTE |
- DAS16M1_INTR_CTRL_PACER_MASK);
- outb(devpriv->intr_ctrl, dev->iobase + DAS16M1_INTR_CTRL_REG);
-
- return 0;
-}
-
-static int das16m1_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DAS16M1_CS_REG);
- if (status & DAS16M1_CS_IRQDATA)
- return 0;
- return -EBUSY;
-}
-
-static int das16m1_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- int i;
-
- das16m1_ai_set_queue(dev, &insn->chanspec, 1);
-
- for (i = 0; i < insn->n; i++) {
- unsigned short val;
-
- /* clear interrupt */
- outb(0, dev->iobase + DAS16M1_CLR_INTR_REG);
- /* trigger conversion */
- outb(0, dev->iobase + DAS16M1_AI_REG);
-
- ret = comedi_timeout(dev, s, insn, das16m1_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inw(dev->iobase + DAS16M1_AI_REG);
- data[i] = DAS16M1_AI_TO_SAMPLE(val);
- }
-
- return insn->n;
-}
-
-static int das16m1_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + DAS16M1_DI_REG) & 0xf;
-
- return insn->n;
-}
-
-static int das16m1_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DAS16M1_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void das16m1_handler(struct comedi_device *dev, unsigned int status)
-{
- struct das16m1_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u16 num_samples;
- u16 hw_counter;
-
- /* figure out how many samples are in fifo */
- hw_counter = comedi_8254_read(devpriv->counter, 1);
- /*
- * Make sure hardware counter reading is not bogus due to initial
- * value not having been loaded yet.
- */
- if (devpriv->adc_count == 0 &&
- hw_counter == devpriv->initial_hw_count) {
- num_samples = 0;
- } else {
- /*
- * The calculation of num_samples looks odd, but it uses the
- * following facts. 16 bit hardware counter is initialized with
- * value of zero (which really means 0x1000). The counter
- * decrements by one on each conversion (when the counter
- * decrements from zero it goes to 0xffff). num_samples is a
- * 16 bit variable, so it will roll over in a similar fashion
- * to the hardware counter. Work it out, and this is what you
- * get.
- */
- num_samples = -hw_counter - devpriv->adc_count;
- }
- /* check if we only need some of the points */
- if (cmd->stop_src == TRIG_COUNT) {
- if (num_samples > cmd->stop_arg * cmd->chanlist_len)
- num_samples = cmd->stop_arg * cmd->chanlist_len;
- }
- /* make sure we don't try to get too many points if fifo has overrun */
- if (num_samples > DAS16M1_AI_FIFO_SZ)
- num_samples = DAS16M1_AI_FIFO_SZ;
- insw(dev->iobase, devpriv->ai_buffer, num_samples);
- comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples);
- devpriv->adc_count += num_samples;
-
- if (cmd->stop_src == TRIG_COUNT) {
- if (devpriv->adc_count >= cmd->stop_arg * cmd->chanlist_len) {
- /* end of acquisition */
- async->events |= COMEDI_CB_EOA;
- }
- }
-
- /*
- * This probably won't catch overruns since the card doesn't generate
- * overrun interrupts, but we might as well try.
- */
- if (status & DAS16M1_CS_OVRUN) {
- async->events |= COMEDI_CB_ERROR;
- dev_err(dev->class_dev, "fifo overflow\n");
- }
-
- comedi_handle_events(dev, s);
-}
-
-static int das16m1_ai_poll(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned long flags;
- unsigned int status;
-
- /* prevent race with interrupt handler */
- spin_lock_irqsave(&dev->spinlock, flags);
- status = inb(dev->iobase + DAS16M1_CS_REG);
- das16m1_handler(dev, status);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return comedi_buf_n_bytes_ready(s);
-}
-
-static irqreturn_t das16m1_interrupt(int irq, void *d)
-{
- int status;
- struct comedi_device *dev = d;
-
- if (!dev->attached) {
- dev_err(dev->class_dev, "premature interrupt\n");
- return IRQ_HANDLED;
- }
- /* prevent race with comedi_poll() */
- spin_lock(&dev->spinlock);
-
- status = inb(dev->iobase + DAS16M1_CS_REG);
-
- if ((status & (DAS16M1_CS_IRQDATA | DAS16M1_CS_OVRUN)) == 0) {
- dev_err(dev->class_dev, "spurious interrupt\n");
- spin_unlock(&dev->spinlock);
- return IRQ_NONE;
- }
-
- das16m1_handler(dev, status);
-
- /* clear interrupt */
- outb(0, dev->iobase + DAS16M1_CLR_INTR_REG);
-
- spin_unlock(&dev->spinlock);
- return IRQ_HANDLED;
-}
-
-static int das16m1_irq_bits(unsigned int irq)
-{
- switch (irq) {
- case 10:
- return 0x0;
- case 11:
- return 0x1;
- case 12:
- return 0x2;
- case 15:
- return 0x3;
- case 2:
- return 0x4;
- case 3:
- return 0x5;
- case 5:
- return 0x6;
- case 7:
- return 0x7;
- default:
- return 0x0;
- }
-}
-
-static int das16m1_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct das16m1_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
- /* Request an additional region for the 8255 and 3rd 8254 */
- ret = __comedi_request_region(dev, dev->iobase + DAS16M1_8255_IOBASE,
- DAS16M1_SIZE2);
- if (ret)
- return ret;
- devpriv->extra_iobase = dev->iobase + DAS16M1_8255_IOBASE;
-
- /* only irqs 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, and 15 are valid */
- if ((1 << it->options[1]) & 0xdcfc) {
- ret = request_irq(it->options[1], das16m1_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- dev->pacer = comedi_8254_init(dev->iobase + DAS16M1_8254_IOBASE2,
- I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- devpriv->counter = comedi_8254_init(dev->iobase + DAS16M1_8254_IOBASE1,
- 0, I8254_IO8, 0);
- if (!devpriv->counter)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF;
- s->n_chan = 8;
- s->maxdata = 0x0fff;
- s->range_table = &range_das16m1;
- s->insn_read = das16m1_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 256;
- s->do_cmdtest = das16m1_ai_cmdtest;
- s->do_cmd = das16m1_ai_cmd;
- s->cancel = das16m1_ai_cancel;
- s->poll = das16m1_ai_poll;
- s->munge = das16m1_ai_munge;
- }
-
- /* Digital Input subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das16m1_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das16m1_do_insn_bits;
-
- /* Digital I/O subdevice (8255) */
- s = &dev->subdevices[3];
- ret = subdev_8255_init(dev, s, NULL, DAS16M1_8255_IOBASE);
- if (ret)
- return ret;
-
- /* initialize digital output lines */
- outb(0, dev->iobase + DAS16M1_DO_REG);
-
- /* set the interrupt level */
- devpriv->intr_ctrl = DAS16M1_INTR_CTRL_IRQ(das16m1_irq_bits(dev->irq));
- outb(devpriv->intr_ctrl, dev->iobase + DAS16M1_INTR_CTRL_REG);
-
- return 0;
-}
-
-static void das16m1_detach(struct comedi_device *dev)
-{
- struct das16m1_private *devpriv = dev->private;
-
- if (devpriv) {
- if (devpriv->extra_iobase)
- release_region(devpriv->extra_iobase, DAS16M1_SIZE2);
- kfree(devpriv->counter);
- }
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver das16m1_driver = {
- .driver_name = "das16m1",
- .module = THIS_MODULE,
- .attach = das16m1_attach,
- .detach = das16m1_detach,
-};
-module_comedi_driver(das16m1_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for CIO-DAS16/M1 ISA cards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
deleted file mode 100644
index f50891a6ee7d..000000000000
--- a/drivers/staging/comedi/drivers/das1800.c
+++ /dev/null
@@ -1,1364 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for Keithley DAS-1700/DAS-1800 series boards
- * Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: das1800
- * Description: Keithley Metrabyte DAS1800 (& compatibles)
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
- * DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
- * DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
- * DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
- * DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
- * DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
- * DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
- * DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
- * DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
- * DAS-1802AO (das-1802ao)
- * Status: works
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (optional, required for analog input cmd support)
- * [2] - DMA0 (optional, requires irq)
- * [3] - DMA1 (optional, requires irq and dma0)
- *
- * analog input cmd triggers supported:
- *
- * start_src TRIG_NOW command starts immediately
- * TRIG_EXT command starts on external pin TGIN
- *
- * scan_begin_src TRIG_FOLLOW paced/external scans start immediately
- * TRIG_TIMER burst scans start periodically
- * TRIG_EXT burst scans start on external pin XPCLK
- *
- * scan_end_src TRIG_COUNT scan ends after last channel
- *
- * convert_src TRIG_TIMER paced/burst conversions are timed
- * TRIG_EXT conversions on external pin XPCLK
- * (requires scan_begin_src == TRIG_FOLLOW)
- *
- * stop_src TRIG_COUNT command stops after stop_arg scans
- * TRIG_EXT command stops on external pin TGIN
- * TRIG_NONE command runs until canceled
- *
- * If TRIG_EXT is used for both the start_src and stop_src, the first TGIN
- * trigger starts the command, and the second trigger will stop it. If only
- * one is TRIG_EXT, the first trigger will either stop or start the command.
- * The external pin TGIN is normally set for negative edge triggering. It
- * can be set to positive edge with the CR_INVERT flag. If TRIG_EXT is used
- * for both the start_src and stop_src they must have the same polarity.
- *
- * Minimum conversion speed is limited to 64 microseconds (convert_arg <= 64000)
- * for 'burst' scans. This limitation does not apply for 'paced' scans. The
- * maximum conversion speed is limited by the board (convert_arg >= ai_speed).
- * Maximum conversion speeds are not always achievable depending on the
- * board setup (see user manual).
- *
- * NOTES:
- * Only the DAS-1801ST has been tested by me.
- * Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
- *
- * The waveform analog output on the 'ao' cards is not supported.
- * If you need it, send me (Frank Hess) an email.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-#include "comedi_8254.h"
-
-/* misc. defines */
-#define DAS1800_SIZE 16 /* uses 16 io addresses */
-#define FIFO_SIZE 1024 /* 1024 sample fifo */
-#define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
-
-/* Registers for the das1800 */
-#define DAS1800_FIFO 0x0
-#define DAS1800_QRAM 0x0
-#define DAS1800_DAC 0x0
-#define DAS1800_SELECT 0x2
-#define ADC 0x0
-#define QRAM 0x1
-#define DAC(a) (0x2 + a)
-#define DAS1800_DIGITAL 0x3
-#define DAS1800_CONTROL_A 0x4
-#define FFEN 0x1
-#define CGEN 0x4
-#define CGSL 0x8
-#define TGEN 0x10
-#define TGSL 0x20
-#define TGPL 0x40
-#define ATEN 0x80
-#define DAS1800_CONTROL_B 0x5
-#define DMA_CH5 0x1
-#define DMA_CH6 0x2
-#define DMA_CH7 0x3
-#define DMA_CH5_CH6 0x5
-#define DMA_CH6_CH7 0x6
-#define DMA_CH7_CH5 0x7
-#define DMA_ENABLED 0x3
-#define DMA_DUAL 0x4
-#define IRQ3 0x8
-#define IRQ5 0x10
-#define IRQ7 0x18
-#define IRQ10 0x28
-#define IRQ11 0x30
-#define IRQ15 0x38
-#define FIMD 0x40
-#define DAS1800_CONTROL_C 0X6
-#define IPCLK 0x1
-#define XPCLK 0x3
-#define BMDE 0x4
-#define CMEN 0x8
-#define UQEN 0x10
-#define SD 0x40
-#define UB 0x80
-#define DAS1800_STATUS 0x7
-#define INT 0x1
-#define DMATC 0x2
-#define CT0TC 0x8
-#define OVF 0x10
-#define FHF 0x20
-#define FNE 0x40
-#define CVEN 0x80
-#define CVEN_MASK 0x40
-#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
-#define DAS1800_BURST_LENGTH 0x8
-#define DAS1800_BURST_RATE 0x9
-#define DAS1800_QRAM_ADDRESS 0xa
-#define DAS1800_COUNTER 0xc
-
-#define IOBASE2 0x400
-
-static const struct comedi_lrange das1801_ai_range = {
- 8, {
- BIP_RANGE(5), /* bipolar gain = 1 */
- BIP_RANGE(1), /* bipolar gain = 10 */
- BIP_RANGE(0.1), /* bipolar gain = 50 */
- BIP_RANGE(0.02), /* bipolar gain = 250 */
- UNI_RANGE(5), /* unipolar gain = 1 */
- UNI_RANGE(1), /* unipolar gain = 10 */
- UNI_RANGE(0.1), /* unipolar gain = 50 */
- UNI_RANGE(0.02) /* unipolar gain = 250 */
- }
-};
-
-static const struct comedi_lrange das1802_ai_range = {
- 8, {
- BIP_RANGE(10), /* bipolar gain = 1 */
- BIP_RANGE(5), /* bipolar gain = 2 */
- BIP_RANGE(2.5), /* bipolar gain = 4 */
- BIP_RANGE(1.25), /* bipolar gain = 8 */
- UNI_RANGE(10), /* unipolar gain = 1 */
- UNI_RANGE(5), /* unipolar gain = 2 */
- UNI_RANGE(2.5), /* unipolar gain = 4 */
- UNI_RANGE(1.25) /* unipolar gain = 8 */
- }
-};
-
-/*
- * The waveform analog outputs on the 'ao' boards are not currently
- * supported. They have a comedi_lrange of:
- * { 2, { BIP_RANGE(10), BIP_RANGE(5) } }
- */
-
-enum das1800_boardid {
- BOARD_DAS1701ST,
- BOARD_DAS1701ST_DA,
- BOARD_DAS1702ST,
- BOARD_DAS1702ST_DA,
- BOARD_DAS1702HR,
- BOARD_DAS1702HR_DA,
- BOARD_DAS1701AO,
- BOARD_DAS1702AO,
- BOARD_DAS1801ST,
- BOARD_DAS1801ST_DA,
- BOARD_DAS1802ST,
- BOARD_DAS1802ST_DA,
- BOARD_DAS1802HR,
- BOARD_DAS1802HR_DA,
- BOARD_DAS1801HC,
- BOARD_DAS1802HC,
- BOARD_DAS1801AO,
- BOARD_DAS1802AO
-};
-
-/* board probe id values (hi byte of the digital input register) */
-#define DAS1800_ID_ST_DA 0x3
-#define DAS1800_ID_HR_DA 0x4
-#define DAS1800_ID_AO 0x5
-#define DAS1800_ID_HR 0x6
-#define DAS1800_ID_ST 0x7
-#define DAS1800_ID_HC 0x8
-
-struct das1800_board {
- const char *name;
- unsigned char id;
- unsigned int ai_speed;
- unsigned int is_01_series:1;
-};
-
-static const struct das1800_board das1800_boards[] = {
- [BOARD_DAS1701ST] = {
- .name = "das-1701st",
- .id = DAS1800_ID_ST,
- .ai_speed = 6250,
- .is_01_series = 1,
- },
- [BOARD_DAS1701ST_DA] = {
- .name = "das-1701st-da",
- .id = DAS1800_ID_ST_DA,
- .ai_speed = 6250,
- .is_01_series = 1,
- },
- [BOARD_DAS1702ST] = {
- .name = "das-1702st",
- .id = DAS1800_ID_ST,
- .ai_speed = 6250,
- },
- [BOARD_DAS1702ST_DA] = {
- .name = "das-1702st-da",
- .id = DAS1800_ID_ST_DA,
- .ai_speed = 6250,
- },
- [BOARD_DAS1702HR] = {
- .name = "das-1702hr",
- .id = DAS1800_ID_HR,
- .ai_speed = 20000,
- },
- [BOARD_DAS1702HR_DA] = {
- .name = "das-1702hr-da",
- .id = DAS1800_ID_HR_DA,
- .ai_speed = 20000,
- },
- [BOARD_DAS1701AO] = {
- .name = "das-1701ao",
- .id = DAS1800_ID_AO,
- .ai_speed = 6250,
- .is_01_series = 1,
- },
- [BOARD_DAS1702AO] = {
- .name = "das-1702ao",
- .id = DAS1800_ID_AO,
- .ai_speed = 6250,
- },
- [BOARD_DAS1801ST] = {
- .name = "das-1801st",
- .id = DAS1800_ID_ST,
- .ai_speed = 3000,
- .is_01_series = 1,
- },
- [BOARD_DAS1801ST_DA] = {
- .name = "das-1801st-da",
- .id = DAS1800_ID_ST_DA,
- .ai_speed = 3000,
- .is_01_series = 1,
- },
- [BOARD_DAS1802ST] = {
- .name = "das-1802st",
- .id = DAS1800_ID_ST,
- .ai_speed = 3000,
- },
- [BOARD_DAS1802ST_DA] = {
- .name = "das-1802st-da",
- .id = DAS1800_ID_ST_DA,
- .ai_speed = 3000,
- },
- [BOARD_DAS1802HR] = {
- .name = "das-1802hr",
- .id = DAS1800_ID_HR,
- .ai_speed = 10000,
- },
- [BOARD_DAS1802HR_DA] = {
- .name = "das-1802hr-da",
- .id = DAS1800_ID_HR_DA,
- .ai_speed = 10000,
- },
- [BOARD_DAS1801HC] = {
- .name = "das-1801hc",
- .id = DAS1800_ID_HC,
- .ai_speed = 3000,
- .is_01_series = 1,
- },
- [BOARD_DAS1802HC] = {
- .name = "das-1802hc",
- .id = DAS1800_ID_HC,
- .ai_speed = 3000,
- },
- [BOARD_DAS1801AO] = {
- .name = "das-1801ao",
- .id = DAS1800_ID_AO,
- .ai_speed = 3000,
- .is_01_series = 1,
- },
- [BOARD_DAS1802AO] = {
- .name = "das-1802ao",
- .id = DAS1800_ID_AO,
- .ai_speed = 3000,
- },
-};
-
-struct das1800_private {
- struct comedi_isadma *dma;
- int irq_dma_bits;
- int dma_bits;
- unsigned short *fifo_buf;
- unsigned long iobase2;
- bool ai_is_unipolar;
-};
-
-static void das1800_ai_munge(struct comedi_device *dev,
- struct comedi_subdevice *s,
- void *data, unsigned int num_bytes,
- unsigned int start_chan_index)
-{
- struct das1800_private *devpriv = dev->private;
- unsigned short *array = data;
- unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
- unsigned int i;
-
- if (devpriv->ai_is_unipolar)
- return;
-
- for (i = 0; i < num_samples; i++)
- array[i] = comedi_offset_munge(s, array[i]);
-}
-
-static void das1800_handle_fifo_half_full(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das1800_private *devpriv = dev->private;
- unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2);
-
- insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples);
- comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples);
-}
-
-static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned short dpnt;
-
- while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
- dpnt = inw(dev->iobase + DAS1800_FIFO);
- comedi_buf_write_samples(s, &dpnt, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- break;
- }
-}
-
-static void das1800_flush_dma_channel(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_isadma_desc *desc)
-{
- unsigned int residue = comedi_isadma_disable(desc->chan);
- unsigned int nbytes = desc->size - residue;
- unsigned int nsamples;
-
- /* figure out how many points to read */
- nsamples = comedi_bytes_to_samples(s, nbytes);
- nsamples = comedi_nsamples_left(s, nsamples);
-
- comedi_buf_write_samples(s, desc->virt_addr, nsamples);
-}
-
-static void das1800_flush_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das1800_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
-
- das1800_flush_dma_channel(dev, s, desc);
-
- if (dual_dma) {
- /* switch to other channel and flush it */
- dma->cur_dma = 1 - dma->cur_dma;
- desc = &dma->desc[dma->cur_dma];
- das1800_flush_dma_channel(dev, s, desc);
- }
-
- /* get any remaining samples in fifo */
- das1800_handle_fifo_not_empty(dev, s);
-}
-
-static void das1800_handle_dma(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int status)
-{
- struct das1800_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
-
- das1800_flush_dma_channel(dev, s, desc);
-
- /* re-enable dma channel */
- comedi_isadma_program(desc);
-
- if (status & DMATC) {
- /* clear DMATC interrupt bit */
- outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
- /* switch dma channels for next time, if appropriate */
- if (dual_dma)
- dma->cur_dma = 1 - dma->cur_dma;
- }
-}
-
-static int das1800_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das1800_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc;
- int i;
-
- /* disable and stop conversions */
- outb(0x0, dev->iobase + DAS1800_STATUS);
- outb(0x0, dev->iobase + DAS1800_CONTROL_B);
- outb(0x0, dev->iobase + DAS1800_CONTROL_A);
-
- if (dma) {
- for (i = 0; i < 2; i++) {
- desc = &dma->desc[i];
- if (desc->chan)
- comedi_isadma_disable(desc->chan);
- }
- }
-
- return 0;
-}
-
-static void das1800_ai_handler(struct comedi_device *dev)
-{
- struct das1800_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int status = inb(dev->iobase + DAS1800_STATUS);
-
- /* select adc register (spinlock is already held) */
- outb(ADC, dev->iobase + DAS1800_SELECT);
-
- /* get samples with dma, fifo, or polled as necessary */
- if (devpriv->irq_dma_bits & DMA_ENABLED)
- das1800_handle_dma(dev, s, status);
- else if (status & FHF)
- das1800_handle_fifo_half_full(dev, s);
- else if (status & FNE)
- das1800_handle_fifo_not_empty(dev, s);
-
- /* if the card's fifo has overflowed */
- if (status & OVF) {
- /* clear OVF interrupt bit */
- outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
- dev_err(dev->class_dev, "FIFO overflow\n");
- async->events |= COMEDI_CB_ERROR;
- comedi_handle_events(dev, s);
- return;
- }
- /* stop taking data if appropriate */
- /* stop_src TRIG_EXT */
- if (status & CT0TC) {
- /* clear CT0TC interrupt bit */
- outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
- /* get all remaining samples before quitting */
- if (devpriv->irq_dma_bits & DMA_ENABLED)
- das1800_flush_dma(dev, s);
- else
- das1800_handle_fifo_not_empty(dev, s);
- async->events |= COMEDI_CB_EOA;
- } else if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- }
-
- comedi_handle_events(dev, s);
-}
-
-static int das1800_ai_poll(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned long flags;
-
- /*
- * Protects the indirect addressing selected by DAS1800_SELECT
- * in das1800_ai_handler() also prevents race with das1800_interrupt().
- */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- das1800_ai_handler(dev);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return comedi_buf_n_bytes_ready(s);
-}
-
-static irqreturn_t das1800_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- unsigned int status;
-
- if (!dev->attached) {
- dev_err(dev->class_dev, "premature interrupt\n");
- return IRQ_HANDLED;
- }
-
- /*
- * Protects the indirect addressing selected by DAS1800_SELECT
- * in das1800_ai_handler() also prevents race with das1800_ai_poll().
- */
- spin_lock(&dev->spinlock);
-
- status = inb(dev->iobase + DAS1800_STATUS);
-
- /* if interrupt was not caused by das-1800 */
- if (!(status & INT)) {
- spin_unlock(&dev->spinlock);
- return IRQ_NONE;
- }
- /* clear the interrupt status bit INT */
- outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
- /* handle interrupt */
- das1800_ai_handler(dev);
-
- spin_unlock(&dev->spinlock);
- return IRQ_HANDLED;
-}
-
-static int das1800_ai_fixup_paced_timing(struct comedi_device *dev,
- struct comedi_cmd *cmd)
-{
- unsigned int arg = cmd->convert_arg;
-
- /*
- * Paced mode:
- * scan_begin_src is TRIG_FOLLOW
- * convert_src is TRIG_TIMER
- *
- * The convert_arg sets the pacer sample acquisition time.
- * The max acquisition speed is limited to the boards
- * 'ai_speed' (this was already verified). The min speed is
- * limited by the cascaded 8254 timer.
- */
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- return comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-}
-
-static int das1800_ai_fixup_burst_timing(struct comedi_device *dev,
- struct comedi_cmd *cmd)
-{
- unsigned int arg = cmd->convert_arg;
- int err = 0;
-
- /*
- * Burst mode:
- * scan_begin_src is TRIG_TIMER or TRIG_EXT
- * convert_src is TRIG_TIMER
- *
- * The convert_arg sets burst sample acquisition time.
- * The max acquisition speed is limited to the boards
- * 'ai_speed' (this was already verified). The min speed is
- * limiited to 64 microseconds,
- */
- err |= comedi_check_trigger_arg_max(&arg, 64000);
-
- /* round to microseconds then verify */
- switch (cmd->flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- arg = DIV_ROUND_CLOSEST(arg, 1000);
- break;
- case CMDF_ROUND_DOWN:
- arg = arg / 1000;
- break;
- case CMDF_ROUND_UP:
- arg = DIV_ROUND_UP(arg, 1000);
- break;
- }
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg * 1000);
-
- /*
- * The pacer can be used to set the scan sample rate. The max scan
- * speed is limited by the conversion speed and the number of channels
- * to convert. The min speed is limited by the cascaded 8254 timer.
- */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->convert_arg * cmd->chanlist_len;
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
-
- arg = cmd->scan_begin_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- return err;
-}
-
-static int das1800_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int range = CR_RANGE(cmd->chanlist[0]);
- bool unipolar0 = comedi_range_is_unipolar(s, range);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- range = CR_RANGE(cmd->chanlist[i]);
-
- if (unipolar0 != comedi_range_is_unipolar(s, range)) {
- dev_dbg(dev->class_dev,
- "unipolar and bipolar ranges cannot be mixed in the chanlist\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int das1800_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct das1800_board *board = dev->board_ptr;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src,
- TRIG_COUNT | TRIG_EXT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- /* burst scans must use timed conversions */
- if (cmd->scan_begin_src != TRIG_FOLLOW &&
- cmd->convert_src != TRIG_TIMER)
- err |= -EINVAL;
-
- /* the external pin TGIN must use the same polarity */
- if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
- err |= comedi_check_trigger_arg_is(&cmd->start_arg,
- cmd->stop_arg);
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- if (cmd->start_arg == TRIG_NOW)
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- switch (cmd->stop_src) {
- case TRIG_COUNT:
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- break;
- case TRIG_NONE:
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
- break;
- default:
- break;
- }
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->scan_begin_src == TRIG_FOLLOW)
- err |= das1800_ai_fixup_paced_timing(dev, cmd);
- else /* TRIG_TIMER or TRIG_EXT */
- err |= das1800_ai_fixup_burst_timing(dev, cmd);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= das1800_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static unsigned char das1800_ai_chanspec_bits(struct comedi_subdevice *s,
- unsigned int chanspec)
-{
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
- unsigned char bits;
-
- bits = UQEN;
- if (aref != AREF_DIFF)
- bits |= SD;
- if (aref == AREF_COMMON)
- bits |= CMEN;
- if (comedi_range_is_unipolar(s, range))
- bits |= UB;
-
- return bits;
-}
-
-static unsigned int das1800_ai_transfer_size(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int maxbytes,
- unsigned int ns)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int max_samples = comedi_bytes_to_samples(s, maxbytes);
- unsigned int samples;
-
- samples = max_samples;
-
- /* for timed modes, make dma buffer fill in 'ns' time */
- switch (cmd->scan_begin_src) {
- case TRIG_FOLLOW: /* not in burst mode */
- if (cmd->convert_src == TRIG_TIMER)
- samples = ns / cmd->convert_arg;
- break;
- case TRIG_TIMER:
- samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len);
- break;
- }
-
- /* limit samples to what is remaining in the command */
- samples = comedi_nsamples_left(s, samples);
-
- if (samples > max_samples)
- samples = max_samples;
- if (samples < 1)
- samples = 1;
-
- return comedi_samples_to_bytes(s, samples);
-}
-
-static void das1800_ai_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das1800_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc;
- unsigned int bytes;
-
- if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
- return;
-
- dma->cur_dma = 0;
- desc = &dma->desc[0];
-
- /* determine a dma transfer size to fill buffer in 0.3 sec */
- bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
-
- desc->size = bytes;
- comedi_isadma_program(desc);
-
- /* set up dual dma if appropriate */
- if (devpriv->irq_dma_bits & DMA_DUAL) {
- desc = &dma->desc[1];
- desc->size = bytes;
- comedi_isadma_program(desc);
- }
-}
-
-static void das1800_ai_set_chanlist(struct comedi_device *dev,
- unsigned int *chanlist, unsigned int len)
-{
- unsigned long flags;
- unsigned int i;
-
- /* protects the indirect addressing selected by DAS1800_SELECT */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- /* select QRAM register and set start address */
- outb(QRAM, dev->iobase + DAS1800_SELECT);
- outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
-
- /* make channel / gain list */
- for (i = 0; i < len; i++) {
- unsigned int chan = CR_CHAN(chanlist[i]);
- unsigned int range = CR_RANGE(chanlist[i]);
- unsigned short val;
-
- val = chan | ((range & 0x3) << 8);
- outw(val, dev->iobase + DAS1800_QRAM);
- }
-
- /* finish write to QRAM */
- outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static int das1800_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das1800_private *devpriv = dev->private;
- int control_a, control_c;
- struct comedi_async *async = s->async;
- const struct comedi_cmd *cmd = &async->cmd;
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
-
- /*
- * Disable dma on CMDF_WAKE_EOS, or CMDF_PRIORITY (because dma in
- * handler is unsafe at hard real-time priority).
- */
- if (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY))
- devpriv->irq_dma_bits &= ~DMA_ENABLED;
- else
- devpriv->irq_dma_bits |= devpriv->dma_bits;
- /* interrupt on end of conversion for CMDF_WAKE_EOS */
- if (cmd->flags & CMDF_WAKE_EOS) {
- /* interrupt fifo not empty */
- devpriv->irq_dma_bits &= ~FIMD;
- } else {
- /* interrupt fifo half full */
- devpriv->irq_dma_bits |= FIMD;
- }
-
- das1800_ai_cancel(dev, s);
-
- devpriv->ai_is_unipolar = comedi_range_is_unipolar(s, range0);
-
- control_a = FFEN;
- if (cmd->stop_src == TRIG_EXT)
- control_a |= ATEN;
- if (cmd->start_src == TRIG_EXT)
- control_a |= TGEN | CGSL;
- else /* TRIG_NOW */
- control_a |= CGEN;
- if (control_a & (ATEN | TGEN)) {
- if ((cmd->start_arg & CR_INVERT) || (cmd->stop_arg & CR_INVERT))
- control_a |= TGPL;
- }
-
- control_c = das1800_ai_chanspec_bits(s, cmd->chanlist[0]);
- /* set clock source to internal or external */
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* not in burst mode */
- if (cmd->convert_src == TRIG_TIMER) {
- /* trig on cascaded counters */
- control_c |= IPCLK;
- } else { /* TRIG_EXT */
- /* trig on falling edge of external trigger */
- control_c |= XPCLK;
- }
- } else if (cmd->scan_begin_src == TRIG_TIMER) {
- /* burst mode with internal pacer clock */
- control_c |= BMDE | IPCLK;
- } else { /* TRIG_EXT */
- /* burst mode with external trigger */
- control_c |= BMDE | XPCLK;
- }
-
- das1800_ai_set_chanlist(dev, cmd->chanlist, cmd->chanlist_len);
-
- /* setup cascaded counters for conversion/scan frequency */
- if ((cmd->scan_begin_src == TRIG_FOLLOW ||
- cmd->scan_begin_src == TRIG_TIMER) &&
- cmd->convert_src == TRIG_TIMER) {
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- }
-
- /* setup counter 0 for 'about triggering' */
- if (cmd->stop_src == TRIG_EXT)
- comedi_8254_load(dev->pacer, 0, 1, I8254_MODE0 | I8254_BINARY);
-
- das1800_ai_setup_dma(dev, s);
- outb(control_c, dev->iobase + DAS1800_CONTROL_C);
- /* set conversion rate and length for burst mode */
- if (control_c & BMDE) {
- outb(cmd->convert_arg / 1000 - 1, /* microseconds - 1 */
- dev->iobase + DAS1800_BURST_RATE);
- outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
- }
-
- /* enable and start conversions */
- outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);
- outb(control_a, dev->iobase + DAS1800_CONTROL_A);
- outb(CVEN, dev->iobase + DAS1800_STATUS);
-
- return 0;
-}
-
-static int das1800_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + DAS1800_STATUS);
- if (status & FNE)
- return 0;
- return -EBUSY;
-}
-
-static int das1800_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int range = CR_RANGE(insn->chanspec);
- bool is_unipolar = comedi_range_is_unipolar(s, range);
- int ret = 0;
- int n;
- unsigned short dpnt;
- unsigned long flags;
-
- outb(das1800_ai_chanspec_bits(s, insn->chanspec),
- dev->iobase + DAS1800_CONTROL_C); /* software pacer */
- outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
- outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
- outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
-
- das1800_ai_set_chanlist(dev, &insn->chanspec, 1);
-
- /* protects the indirect addressing selected by DAS1800_SELECT */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- /* select ai fifo register */
- outb(ADC, dev->iobase + DAS1800_SELECT);
-
- for (n = 0; n < insn->n; n++) {
- /* trigger conversion */
- outb(0, dev->iobase + DAS1800_FIFO);
-
- ret = comedi_timeout(dev, s, insn, das1800_ai_eoc, 0);
- if (ret)
- break;
-
- dpnt = inw(dev->iobase + DAS1800_FIFO);
- if (!is_unipolar)
- dpnt = comedi_offset_munge(s, dpnt);
- data[n] = dpnt;
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return ret ? ret : insn->n;
-}
-
-static int das1800_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int update_chan = s->n_chan - 1;
- unsigned long flags;
- int i;
-
- /* protects the indirect addressing selected by DAS1800_SELECT */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- val = comedi_offset_munge(s, val);
-
- /* load this channel (and update if it's the last channel) */
- outb(DAC(chan), dev->iobase + DAS1800_SELECT);
- outw(val, dev->iobase + DAS1800_DAC);
-
- /* update all channels */
- if (chan != update_chan) {
- val = comedi_offset_munge(s, s->readback[update_chan]);
-
- outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);
- outw(val, dev->iobase + DAS1800_DAC);
- }
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return insn->n;
-}
-
-static int das1800_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
- data[0] = 0;
-
- return insn->n;
-}
-
-static int das1800_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DAS1800_DIGITAL);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void das1800_init_dma(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct das1800_private *devpriv = dev->private;
- unsigned int *dma_chan;
-
- /*
- * it->options[2] is DMA channel 0
- * it->options[3] is DMA channel 1
- *
- * Encode the DMA channels into 2 digit hexadecimal for switch.
- */
- dma_chan = &it->options[2];
-
- switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) {
- case 0x5: /* dma0 == 5 */
- devpriv->dma_bits = DMA_CH5;
- break;
- case 0x6: /* dma0 == 6 */
- devpriv->dma_bits = DMA_CH6;
- break;
- case 0x7: /* dma0 == 7 */
- devpriv->dma_bits = DMA_CH7;
- break;
- case 0x65: /* dma0 == 5, dma1 == 6 */
- devpriv->dma_bits = DMA_CH5_CH6;
- break;
- case 0x76: /* dma0 == 6, dma1 == 7 */
- devpriv->dma_bits = DMA_CH6_CH7;
- break;
- case 0x57: /* dma0 == 7, dma1 == 5 */
- devpriv->dma_bits = DMA_CH7_CH5;
- break;
- default:
- return;
- }
-
- /* DMA can use 1 or 2 buffers, each with a separate channel */
- devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1,
- dma_chan[0], dma_chan[1],
- DMA_BUF_SIZE, COMEDI_ISADMA_READ);
- if (!devpriv->dma)
- devpriv->dma_bits = 0;
-}
-
-static void das1800_free_dma(struct comedi_device *dev)
-{
- struct das1800_private *devpriv = dev->private;
-
- if (devpriv)
- comedi_isadma_free(devpriv->dma);
-}
-
-static int das1800_probe(struct comedi_device *dev)
-{
- const struct das1800_board *board = dev->board_ptr;
- unsigned char id;
-
- id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
-
- /*
- * The dev->board_ptr will be set by comedi_device_attach() if the
- * board name provided by the user matches a board->name in this
- * driver. If so, this function sanity checks the id to verify that
- * the board is correct.
- */
- if (board) {
- if (board->id == id)
- return 0;
- dev_err(dev->class_dev,
- "probed id does not match board id (0x%x != 0x%x)\n",
- id, board->id);
- return -ENODEV;
- }
-
- /*
- * If the dev->board_ptr is not set, the user is trying to attach
- * an unspecified board to this driver. In this case the id is used
- * to 'probe' for the dev->board_ptr.
- */
- switch (id) {
- case DAS1800_ID_ST_DA:
- /* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */
- board = &das1800_boards[BOARD_DAS1801ST_DA];
- break;
- case DAS1800_ID_HR_DA:
- /* das-1702hr-da, das-1802hr-da */
- board = &das1800_boards[BOARD_DAS1802HR_DA];
- break;
- case DAS1800_ID_AO:
- /* das-1701ao, das-1702ao, das-1801ao, das-1802ao */
- board = &das1800_boards[BOARD_DAS1801AO];
- break;
- case DAS1800_ID_HR:
- /* das-1702hr, das-1802hr */
- board = &das1800_boards[BOARD_DAS1802HR];
- break;
- case DAS1800_ID_ST:
- /* das-1701st, das-1702st, das-1801st, das-1802st */
- board = &das1800_boards[BOARD_DAS1801ST];
- break;
- case DAS1800_ID_HC:
- /* das-1801hc, das-1802hc */
- board = &das1800_boards[BOARD_DAS1801HC];
- break;
- default:
- dev_err(dev->class_dev, "invalid probe id 0x%x\n", id);
- return -ENODEV;
- }
- dev->board_ptr = board;
- dev->board_name = board->name;
- dev_warn(dev->class_dev,
- "probed id 0x%0x: %s series (not recommended)\n",
- id, board->name);
- return 0;
-}
-
-static int das1800_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct das1800_board *board;
- struct das1800_private *devpriv;
- struct comedi_subdevice *s;
- unsigned int irq = it->options[1];
- bool is_16bit;
- int ret;
- int i;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
- if (ret)
- return ret;
-
- ret = das1800_probe(dev);
- if (ret)
- return ret;
- board = dev->board_ptr;
-
- is_16bit = board->id == DAS1800_ID_HR || board->id == DAS1800_ID_HR_DA;
-
- /* waveform 'ao' boards have additional io ports */
- if (board->id == DAS1800_ID_AO) {
- unsigned long iobase2 = dev->iobase + IOBASE2;
-
- ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
- if (ret)
- return ret;
- devpriv->iobase2 = iobase2;
- }
-
- if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 ||
- irq == 15) {
- ret = request_irq(irq, das1800_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0) {
- dev->irq = irq;
-
- switch (irq) {
- case 3:
- devpriv->irq_dma_bits |= 0x8;
- break;
- case 5:
- devpriv->irq_dma_bits |= 0x10;
- break;
- case 7:
- devpriv->irq_dma_bits |= 0x18;
- break;
- case 10:
- devpriv->irq_dma_bits |= 0x28;
- break;
- case 11:
- devpriv->irq_dma_bits |= 0x30;
- break;
- case 15:
- devpriv->irq_dma_bits |= 0x38;
- break;
- }
- }
- }
-
- /* an irq and one dma channel is required to use dma */
- if (dev->irq & it->options[2])
- das1800_init_dma(dev, it);
-
- devpriv->fifo_buf = kmalloc_array(FIFO_SIZE,
- sizeof(*devpriv->fifo_buf),
- GFP_KERNEL);
- if (!devpriv->fifo_buf)
- return -ENOMEM;
-
- dev->pacer = comedi_8254_init(dev->iobase + DAS1800_COUNTER,
- I8254_OSC_BASE_5MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /*
- * Analog Input subdevice
- *
- * The "hc" type boards have 64 analog input channels and a 64
- * entry QRAM fifo.
- *
- * All the other board types have 16 on-board channels. Each channel
- * can be expanded to 16 channels with the addition of an EXP-1800
- * expansion board for a total of 256 channels. The QRAM fifo on
- * these boards has 256 entries.
- *
- * From the datasheets it's not clear what the comedi channel to
- * actual physical channel mapping is when EXP-1800 boards are used.
- */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
- if (board->id != DAS1800_ID_HC)
- s->subdev_flags |= SDF_COMMON;
- s->n_chan = (board->id == DAS1800_ID_HC) ? 64 : 256;
- s->maxdata = is_16bit ? 0xffff : 0x0fff;
- s->range_table = board->is_01_series ? &das1801_ai_range
- : &das1802_ai_range;
- s->insn_read = das1800_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmd = das1800_ai_cmd;
- s->do_cmdtest = das1800_ai_cmdtest;
- s->poll = das1800_ai_poll;
- s->cancel = das1800_ai_cancel;
- s->munge = das1800_ai_munge;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->id == DAS1800_ID_ST_DA || board->id == DAS1800_ID_HR_DA) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = (board->id == DAS1800_ID_ST_DA) ? 4 : 2;
- s->maxdata = is_16bit ? 0xffff : 0x0fff;
- s->range_table = &range_bipolar10;
- s->insn_write = das1800_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* initialize all channels to 0V */
- for (i = 0; i < s->n_chan; i++) {
- /* spinlock is not necessary during the attach */
- outb(DAC(i), dev->iobase + DAS1800_SELECT);
- outw(0, dev->iobase + DAS1800_DAC);
- }
- } else if (board->id == DAS1800_ID_AO) {
- /*
- * 'ao' boards have waveform analog outputs that are not
- * currently supported.
- */
- s->type = COMEDI_SUBD_UNUSED;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das1800_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = (board->id == DAS1800_ID_HC) ? 8 : 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das1800_do_insn_bits;
-
- das1800_ai_cancel(dev, dev->read_subdev);
-
- /* initialize digital out channels */
- outb(0, dev->iobase + DAS1800_DIGITAL);
-
- return 0;
-};
-
-static void das1800_detach(struct comedi_device *dev)
-{
- struct das1800_private *devpriv = dev->private;
-
- das1800_free_dma(dev);
- if (devpriv) {
- kfree(devpriv->fifo_buf);
- if (devpriv->iobase2)
- release_region(devpriv->iobase2, DAS1800_SIZE);
- }
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver das1800_driver = {
- .driver_name = "das1800",
- .module = THIS_MODULE,
- .attach = das1800_attach,
- .detach = das1800_detach,
- .num_names = ARRAY_SIZE(das1800_boards),
- .board_name = &das1800_boards[0].name,
- .offset = sizeof(struct das1800_board),
-};
-module_comedi_driver(das1800_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for DAS1800 compatible ISA boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
deleted file mode 100644
index 96f4107b8054..000000000000
--- a/drivers/staging/comedi/drivers/das6402.c
+++ /dev/null
@@ -1,669 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * das6402.c
- * Comedi driver for DAS6402 compatible boards
- * Copyright(c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
- *
- * Rewrite of an experimental driver by:
- * Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.org>
- */
-
-/*
- * Driver: das6402
- * Description: Keithley Metrabyte DAS6402 (& compatibles)
- * Devices: [Keithley Metrabyte] DAS6402-12 (das6402-12),
- * DAS6402-16 (das6402-16)
- * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
- * Updated: Fri, 14 Mar 2014 10:18:43 -0700
- * Status: unknown
- *
- * Configuration Options:
- * [0] - I/O base address
- * [1] - IRQ (optional, needed for async command support)
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "comedi_8254.h"
-
-/*
- * Register I/O map
- */
-#define DAS6402_AI_DATA_REG 0x00
-#define DAS6402_AI_MUX_REG 0x02
-#define DAS6402_AI_MUX_LO(x) (((x) & 0x3f) << 0)
-#define DAS6402_AI_MUX_HI(x) (((x) & 0x3f) << 8)
-#define DAS6402_DI_DO_REG 0x03
-#define DAS6402_AO_DATA_REG(x) (0x04 + ((x) * 2))
-#define DAS6402_AO_LSB_REG(x) (0x04 + ((x) * 2))
-#define DAS6402_AO_MSB_REG(x) (0x05 + ((x) * 2))
-#define DAS6402_STATUS_REG 0x08
-#define DAS6402_STATUS_FFNE BIT(0)
-#define DAS6402_STATUS_FHALF BIT(1)
-#define DAS6402_STATUS_FFULL BIT(2)
-#define DAS6402_STATUS_XINT BIT(3)
-#define DAS6402_STATUS_INT BIT(4)
-#define DAS6402_STATUS_XTRIG BIT(5)
-#define DAS6402_STATUS_INDGT BIT(6)
-#define DAS6402_STATUS_10MHZ BIT(7)
-#define DAS6402_STATUS_W_CLRINT BIT(0)
-#define DAS6402_STATUS_W_CLRXTR BIT(1)
-#define DAS6402_STATUS_W_CLRXIN BIT(2)
-#define DAS6402_STATUS_W_EXTEND BIT(4)
-#define DAS6402_STATUS_W_ARMED BIT(5)
-#define DAS6402_STATUS_W_POSTMODE BIT(6)
-#define DAS6402_STATUS_W_10MHZ BIT(7)
-#define DAS6402_CTRL_REG 0x09
-#define DAS6402_CTRL_TRIG(x) ((x) << 0)
-#define DAS6402_CTRL_SOFT_TRIG DAS6402_CTRL_TRIG(0)
-#define DAS6402_CTRL_EXT_FALL_TRIG DAS6402_CTRL_TRIG(1)
-#define DAS6402_CTRL_EXT_RISE_TRIG DAS6402_CTRL_TRIG(2)
-#define DAS6402_CTRL_PACER_TRIG DAS6402_CTRL_TRIG(3)
-#define DAS6402_CTRL_BURSTEN BIT(2)
-#define DAS6402_CTRL_XINTE BIT(3)
-#define DAS6402_CTRL_IRQ(x) ((x) << 4)
-#define DAS6402_CTRL_INTE BIT(7)
-#define DAS6402_TRIG_REG 0x0a
-#define DAS6402_TRIG_TGEN BIT(0)
-#define DAS6402_TRIG_TGSEL BIT(1)
-#define DAS6402_TRIG_TGPOL BIT(2)
-#define DAS6402_TRIG_PRETRIG BIT(3)
-#define DAS6402_AO_RANGE(_chan, _range) ((_range) << ((_chan) ? 6 : 4))
-#define DAS6402_AO_RANGE_MASK(_chan) (3 << ((_chan) ? 6 : 4))
-#define DAS6402_MODE_REG 0x0b
-#define DAS6402_MODE_RANGE(x) ((x) << 2)
-#define DAS6402_MODE_POLLED DAS6402_MODE_RANGE(0)
-#define DAS6402_MODE_FIFONEPTY DAS6402_MODE_RANGE(1)
-#define DAS6402_MODE_FIFOHFULL DAS6402_MODE_RANGE(2)
-#define DAS6402_MODE_EOB DAS6402_MODE_RANGE(3)
-#define DAS6402_MODE_ENHANCED BIT(4)
-#define DAS6402_MODE_SE BIT(5)
-#define DAS6402_MODE_UNI BIT(6)
-#define DAS6402_MODE_DMA(x) ((x) << 7)
-#define DAS6402_MODE_DMA1 DAS6402_MODE_DMA(0)
-#define DAS6402_MODE_DMA3 DAS6402_MODE_DMA(1)
-#define DAS6402_TIMER_BASE 0x0c
-
-static const struct comedi_lrange das6402_ai_ranges = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-/*
- * Analog output ranges are programmable on the DAS6402/12.
- * For the DAS6402/16 the range bits have no function, the
- * DAC ranges are selected by switches on the board.
- */
-static const struct comedi_lrange das6402_ao_ranges = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-struct das6402_boardinfo {
- const char *name;
- unsigned int maxdata;
-};
-
-static struct das6402_boardinfo das6402_boards[] = {
- {
- .name = "das6402-12",
- .maxdata = 0x0fff,
- }, {
- .name = "das6402-16",
- .maxdata = 0xffff,
- },
-};
-
-struct das6402_private {
- unsigned int irq;
- unsigned int ao_range;
-};
-
-static void das6402_set_mode(struct comedi_device *dev,
- unsigned int mode)
-{
- outb(DAS6402_MODE_ENHANCED | mode, dev->iobase + DAS6402_MODE_REG);
-}
-
-static void das6402_set_extended(struct comedi_device *dev,
- unsigned int val)
-{
- outb(DAS6402_STATUS_W_EXTEND, dev->iobase + DAS6402_STATUS_REG);
- outb(DAS6402_STATUS_W_EXTEND | val, dev->iobase + DAS6402_STATUS_REG);
- outb(val, dev->iobase + DAS6402_STATUS_REG);
-}
-
-static void das6402_clear_all_interrupts(struct comedi_device *dev)
-{
- outb(DAS6402_STATUS_W_CLRINT |
- DAS6402_STATUS_W_CLRXTR |
- DAS6402_STATUS_W_CLRXIN, dev->iobase + DAS6402_STATUS_REG);
-}
-
-static void das6402_ai_clear_eoc(struct comedi_device *dev)
-{
- outb(DAS6402_STATUS_W_CLRINT, dev->iobase + DAS6402_STATUS_REG);
-}
-
-static unsigned int das6402_ai_read_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- val = inw(dev->iobase + DAS6402_AI_DATA_REG);
- if (s->maxdata == 0x0fff)
- val >>= 4;
- return val;
-}
-
-static irqreturn_t das6402_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int status;
-
- status = inb(dev->iobase + DAS6402_STATUS_REG);
- if ((status & DAS6402_STATUS_INT) == 0)
- return IRQ_NONE;
-
- if (status & DAS6402_STATUS_FFULL) {
- async->events |= COMEDI_CB_OVERFLOW;
- } else if (status & DAS6402_STATUS_FFNE) {
- unsigned short val;
-
- val = das6402_ai_read_sample(dev, s);
- comedi_buf_write_samples(s, &val, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
- }
-
- das6402_clear_all_interrupts(dev);
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static void das6402_ai_set_mode(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chanspec,
- unsigned int mode)
-{
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
-
- mode |= DAS6402_MODE_RANGE(range);
- if (aref == AREF_GROUND)
- mode |= DAS6402_MODE_SE;
- if (comedi_range_is_unipolar(s, range))
- mode |= DAS6402_MODE_UNI;
-
- das6402_set_mode(dev, mode);
-}
-
-static int das6402_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct das6402_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int chan_lo = CR_CHAN(cmd->chanlist[0]);
- unsigned int chan_hi = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
-
- das6402_ai_set_mode(dev, s, cmd->chanlist[0], DAS6402_MODE_FIFONEPTY);
-
- /* load the mux for chanlist conversion */
- outw(DAS6402_AI_MUX_HI(chan_hi) | DAS6402_AI_MUX_LO(chan_lo),
- dev->iobase + DAS6402_AI_MUX_REG);
-
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
-
- /* enable interrupt and pacer trigger */
- outb(DAS6402_CTRL_INTE |
- DAS6402_CTRL_IRQ(devpriv->irq) |
- DAS6402_CTRL_PACER_TRIG, dev->iobase + DAS6402_CTRL_REG);
-
- return 0;
-}
-
-static int das6402_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- if (chan != chan0 + i) {
- dev_dbg(dev->class_dev,
- "chanlist must be consecutive\n");
- return -EINVAL;
- }
-
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "chanlist must have the same range\n");
- return -EINVAL;
- }
-
- if (aref != aref0) {
- dev_dbg(dev->class_dev,
- "chanlist must have the same reference\n");
- return -EINVAL;
- }
-
- if (aref0 == AREF_DIFF && chan > (s->n_chan / 2)) {
- dev_dbg(dev->class_dev,
- "chanlist differential channel too large\n");
- return -EINVAL;
- }
- }
- return 0;
-}
-
-static int das6402_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- arg = cmd->convert_arg;
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= das6402_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int das6402_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG);
-
- return 0;
-}
-
-static void das6402_ai_soft_trig(struct comedi_device *dev)
-{
- outw(0, dev->iobase + DAS6402_AI_DATA_REG);
-}
-
-static int das6402_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DAS6402_STATUS_REG);
- if (status & DAS6402_STATUS_FFNE)
- return 0;
- return -EBUSY;
-}
-
-static int das6402_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- int ret;
- int i;
-
- if (aref == AREF_DIFF && chan > (s->n_chan / 2))
- return -EINVAL;
-
- /* enable software conversion trigger */
- outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG);
-
- das6402_ai_set_mode(dev, s, insn->chanspec, DAS6402_MODE_POLLED);
-
- /* load the mux for single channel conversion */
- outw(DAS6402_AI_MUX_HI(chan) | DAS6402_AI_MUX_LO(chan),
- dev->iobase + DAS6402_AI_MUX_REG);
-
- for (i = 0; i < insn->n; i++) {
- das6402_ai_clear_eoc(dev);
- das6402_ai_soft_trig(dev);
-
- ret = comedi_timeout(dev, s, insn, das6402_ai_eoc, 0);
- if (ret)
- break;
-
- data[i] = das6402_ai_read_sample(dev, s);
- }
-
- das6402_ai_clear_eoc(dev);
-
- return insn->n;
-}
-
-static int das6402_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct das6402_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- int i;
-
- /* set the range for this channel */
- val = devpriv->ao_range;
- val &= ~DAS6402_AO_RANGE_MASK(chan);
- val |= DAS6402_AO_RANGE(chan, range);
- if (val != devpriv->ao_range) {
- devpriv->ao_range = val;
- outb(val, dev->iobase + DAS6402_TRIG_REG);
- }
-
- /*
- * The DAS6402/16 has a jumper to select either individual
- * update (UPDATE) or simultaneous updating (XFER) of both
- * DAC's. In UPDATE mode, when the MSB is written, that DAC
- * is updated. In XFER mode, after both DAC's are loaded,
- * a read cycle of any DAC register will update both DAC's
- * simultaneously.
- *
- * If you have XFER mode enabled a (*insn_read) will need
- * to be performed in order to update the DAC's with the
- * last value written.
- */
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- s->readback[chan] = val;
-
- if (s->maxdata == 0x0fff) {
- /*
- * DAS6402/12 has the two 8-bit DAC registers, left
- * justified (the 4 LSB bits are don't care). Data
- * can be written as one word.
- */
- val <<= 4;
- outw(val, dev->iobase + DAS6402_AO_DATA_REG(chan));
- } else {
- /*
- * DAS6402/16 uses both 8-bit DAC registers and needs
- * to be written LSB then MSB.
- */
- outb(val & 0xff,
- dev->iobase + DAS6402_AO_LSB_REG(chan));
- outb((val >> 8) & 0xff,
- dev->iobase + DAS6402_AO_LSB_REG(chan));
- }
- }
-
- return insn->n;
-}
-
-static int das6402_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /*
- * If XFER mode is enabled, reading any DAC register
- * will update both DAC's simultaneously.
- */
- inw(dev->iobase + DAS6402_AO_LSB_REG(chan));
-
- return comedi_readback_insn_read(dev, s, insn, data);
-}
-
-static int das6402_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + DAS6402_DI_DO_REG);
-
- return insn->n;
-}
-
-static int das6402_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DAS6402_DI_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void das6402_reset(struct comedi_device *dev)
-{
- struct das6402_private *devpriv = dev->private;
-
- /* enable "Enhanced" mode */
- outb(DAS6402_MODE_ENHANCED, dev->iobase + DAS6402_MODE_REG);
-
- /* enable 10MHz pacer clock */
- das6402_set_extended(dev, DAS6402_STATUS_W_10MHZ);
-
- /* enable software conversion trigger */
- outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG);
-
- /* default ADC to single-ended unipolar 10V inputs */
- das6402_set_mode(dev, DAS6402_MODE_RANGE(0) |
- DAS6402_MODE_POLLED |
- DAS6402_MODE_SE |
- DAS6402_MODE_UNI);
-
- /* default mux for single channel conversion (channel 0) */
- outw(DAS6402_AI_MUX_HI(0) | DAS6402_AI_MUX_LO(0),
- dev->iobase + DAS6402_AI_MUX_REG);
-
- /* set both DAC's for unipolar 5V output range */
- devpriv->ao_range = DAS6402_AO_RANGE(0, 2) | DAS6402_AO_RANGE(1, 2);
- outb(devpriv->ao_range, dev->iobase + DAS6402_TRIG_REG);
-
- /* set both DAC's to 0V */
- outw(0, dev->iobase + DAS6402_AO_DATA_REG(0));
- outw(0, dev->iobase + DAS6402_AO_DATA_REG(0));
- inw(dev->iobase + DAS6402_AO_LSB_REG(0));
-
- /* set all digital outputs low */
- outb(0, dev->iobase + DAS6402_DI_DO_REG);
-
- das6402_clear_all_interrupts(dev);
-}
-
-static int das6402_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct das6402_boardinfo *board = dev->board_ptr;
- struct das6402_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- das6402_reset(dev);
-
- /* IRQs 2,3,5,6,7, 10,11,15 are valid for "enhanced" mode */
- if ((1 << it->options[1]) & 0x8cec) {
- ret = request_irq(it->options[1], das6402_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0) {
- dev->irq = it->options[1];
-
- switch (dev->irq) {
- case 10:
- devpriv->irq = 4;
- break;
- case 11:
- devpriv->irq = 1;
- break;
- case 15:
- devpriv->irq = 6;
- break;
- default:
- devpriv->irq = dev->irq;
- break;
- }
- }
- }
-
- dev->pacer = comedi_8254_init(dev->iobase + DAS6402_TIMER_BASE,
- I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 64;
- s->maxdata = board->maxdata;
- s->range_table = &das6402_ai_ranges;
- s->insn_read = das6402_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = das6402_ai_cmdtest;
- s->do_cmd = das6402_ai_cmd;
- s->cancel = das6402_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = board->maxdata;
- s->range_table = &das6402_ao_ranges;
- s->insn_write = das6402_ao_insn_write;
- s->insn_read = das6402_ao_insn_read;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das6402_di_insn_bits;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das6402_do_insn_bits;
-
- return 0;
-}
-
-static struct comedi_driver das6402_driver = {
- .driver_name = "das6402",
- .module = THIS_MODULE,
- .attach = das6402_attach,
- .detach = comedi_legacy_detach,
- .board_name = &das6402_boards[0].name,
- .num_names = ARRAY_SIZE(das6402_boards),
- .offset = sizeof(struct das6402_boardinfo),
-};
-module_comedi_driver(das6402_driver)
-
-MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_DESCRIPTION("Comedi driver for DAS6402 compatible boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
deleted file mode 100644
index bc08324f422f..000000000000
--- a/drivers/staging/comedi/drivers/das800.c
+++ /dev/null
@@ -1,744 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/das800.c
- * Driver for Keitley das800 series boards and compatibles
- * Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-/*
- * Driver: das800
- * Description: Keithley Metrabyte DAS800 (& compatibles)
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Devices: [Keithley Metrabyte] DAS-800 (das-800), DAS-801 (das-801),
- * DAS-802 (das-802),
- * [Measurement Computing] CIO-DAS800 (cio-das800),
- * CIO-DAS801 (cio-das801), CIO-DAS802 (cio-das802),
- * CIO-DAS802/16 (cio-das802/16)
- * Status: works, cio-das802/16 untested - email me if you have tested it
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (optional, required for timed or externally triggered conversions)
- *
- * Notes:
- * IRQ can be omitted, although the cmd interface will not work without it.
- *
- * All entries in the channel/gain list must use the same gain and be
- * consecutive channels counting upwards in channel number (these are
- * hardware limitations.)
- *
- * I've never tested the gain setting stuff since I only have a
- * DAS-800 board with fixed gain.
- *
- * The cio-das802/16 does not have a fifo-empty status bit! Therefore
- * only fifo-half-full transfers are possible with this card.
- *
- * cmd triggers supported:
- * start_src: TRIG_NOW | TRIG_EXT
- * scan_begin_src: TRIG_FOLLOW
- * scan_end_src: TRIG_COUNT
- * convert_src: TRIG_TIMER | TRIG_EXT
- * stop_src: TRIG_NONE | TRIG_COUNT
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include "../comedidev.h"
-
-#include "comedi_8254.h"
-
-#define N_CHAN_AI 8 /* number of analog input channels */
-
-/* Registers for the das800 */
-
-#define DAS800_LSB 0
-#define FIFO_EMPTY 0x1
-#define FIFO_OVF 0x2
-#define DAS800_MSB 1
-#define DAS800_CONTROL1 2
-#define CONTROL1_INTE 0x8
-#define DAS800_CONV_CONTROL 2
-#define ITE 0x1
-#define CASC 0x2
-#define DTEN 0x4
-#define IEOC 0x8
-#define EACS 0x10
-#define CONV_HCEN 0x80
-#define DAS800_SCAN_LIMITS 2
-#define DAS800_STATUS 2
-#define IRQ 0x8
-#define BUSY 0x80
-#define DAS800_GAIN 3
-#define CIO_FFOV 0x8 /* cio-das802/16 fifo overflow */
-#define CIO_ENHF 0x90 /* cio-das802/16 fifo half full int ena */
-#define CONTROL1 0x80
-#define CONV_CONTROL 0xa0
-#define SCAN_LIMITS 0xc0
-#define ID 0xe0
-#define DAS800_8254 4
-#define DAS800_STATUS2 7
-#define STATUS2_HCEN 0x80
-#define STATUS2_INTE 0X20
-#define DAS800_ID 7
-
-#define DAS802_16_HALF_FIFO_SZ 128
-
-struct das800_board {
- const char *name;
- int ai_speed;
- const struct comedi_lrange *ai_range;
- int resolution;
-};
-
-static const struct comedi_lrange range_das801_ai = {
- 9, {
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(10),
- BIP_RANGE(0.5),
- UNI_RANGE(1),
- BIP_RANGE(0.05),
- UNI_RANGE(0.1),
- BIP_RANGE(0.01),
- UNI_RANGE(0.02)
- }
-};
-
-static const struct comedi_lrange range_cio_das801_ai = {
- 9, {
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(10),
- BIP_RANGE(0.5),
- UNI_RANGE(1),
- BIP_RANGE(0.05),
- UNI_RANGE(0.1),
- BIP_RANGE(0.005),
- UNI_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_das802_ai = {
- 9, {
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(10),
- BIP_RANGE(2.5),
- UNI_RANGE(5),
- BIP_RANGE(1.25),
- UNI_RANGE(2.5),
- BIP_RANGE(0.625),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_das80216_ai = {
- 8, {
- BIP_RANGE(10),
- UNI_RANGE(10),
- BIP_RANGE(5),
- UNI_RANGE(5),
- BIP_RANGE(2.5),
- UNI_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(1.25)
- }
-};
-
-enum das800_boardinfo {
- BOARD_DAS800,
- BOARD_CIODAS800,
- BOARD_DAS801,
- BOARD_CIODAS801,
- BOARD_DAS802,
- BOARD_CIODAS802,
- BOARD_CIODAS80216,
-};
-
-static const struct das800_board das800_boards[] = {
- [BOARD_DAS800] = {
- .name = "das-800",
- .ai_speed = 25000,
- .ai_range = &range_bipolar5,
- .resolution = 12,
- },
- [BOARD_CIODAS800] = {
- .name = "cio-das800",
- .ai_speed = 20000,
- .ai_range = &range_bipolar5,
- .resolution = 12,
- },
- [BOARD_DAS801] = {
- .name = "das-801",
- .ai_speed = 25000,
- .ai_range = &range_das801_ai,
- .resolution = 12,
- },
- [BOARD_CIODAS801] = {
- .name = "cio-das801",
- .ai_speed = 20000,
- .ai_range = &range_cio_das801_ai,
- .resolution = 12,
- },
- [BOARD_DAS802] = {
- .name = "das-802",
- .ai_speed = 25000,
- .ai_range = &range_das802_ai,
- .resolution = 12,
- },
- [BOARD_CIODAS802] = {
- .name = "cio-das802",
- .ai_speed = 20000,
- .ai_range = &range_das802_ai,
- .resolution = 12,
- },
- [BOARD_CIODAS80216] = {
- .name = "cio-das802/16",
- .ai_speed = 10000,
- .ai_range = &range_das80216_ai,
- .resolution = 16,
- },
-};
-
-struct das800_private {
- unsigned int do_bits; /* digital output bits */
-};
-
-static void das800_ind_write(struct comedi_device *dev,
- unsigned int val, unsigned int reg)
-{
- /*
- * Select dev->iobase + 2 to be desired register
- * then write to that register.
- */
- outb(reg, dev->iobase + DAS800_GAIN);
- outb(val, dev->iobase + 2);
-}
-
-static unsigned int das800_ind_read(struct comedi_device *dev, unsigned int reg)
-{
- /*
- * Select dev->iobase + 7 to be desired register
- * then read from that register.
- */
- outb(reg, dev->iobase + DAS800_GAIN);
- return inb(dev->iobase + 7);
-}
-
-static void das800_enable(struct comedi_device *dev)
-{
- const struct das800_board *board = dev->board_ptr;
- struct das800_private *devpriv = dev->private;
- unsigned long irq_flags;
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- /* enable fifo-half full interrupts for cio-das802/16 */
- if (board->resolution == 16)
- outb(CIO_ENHF, dev->iobase + DAS800_GAIN);
- /* enable hardware triggering */
- das800_ind_write(dev, CONV_HCEN, CONV_CONTROL);
- /* enable card's interrupt */
- das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-}
-
-static void das800_disable(struct comedi_device *dev)
-{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- /* disable hardware triggering of conversions */
- das800_ind_write(dev, 0x0, CONV_CONTROL);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-}
-
-static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- das800_disable(dev);
- return 0;
-}
-
-static int das800_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- if (chan != (chan0 + i) % s->n_chan) {
- dev_dbg(dev->class_dev,
- "chanlist must be consecutive, counting upwards\n");
- return -EINVAL;
- }
-
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "chanlist must all have the same gain\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int das800_ai_do_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct das800_board *board = dev->board_ptr;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- unsigned int arg = cmd->convert_arg;
-
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= das800_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int das800_ai_do_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct das800_board *board = dev->board_ptr;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int gain = CR_RANGE(cmd->chanlist[0]);
- unsigned int start_chan = CR_CHAN(cmd->chanlist[0]);
- unsigned int end_chan = (start_chan + cmd->chanlist_len - 1) % 8;
- unsigned int scan_chans = (end_chan << 3) | start_chan;
- int conv_bits;
- unsigned long irq_flags;
-
- das800_disable(dev);
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- /* set scan limits */
- das800_ind_write(dev, scan_chans, SCAN_LIMITS);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- /* set gain */
- if (board->resolution == 12 && gain > 0)
- gain += 0x7;
- gain &= 0xf;
- outb(gain, dev->iobase + DAS800_GAIN);
-
- /* enable auto channel scan, send interrupts on end of conversion
- * and set clock source to internal or external
- */
- conv_bits = 0;
- conv_bits |= EACS | IEOC;
- if (cmd->start_src == TRIG_EXT)
- conv_bits |= DTEN;
- if (cmd->convert_src == TRIG_TIMER) {
- conv_bits |= CASC | ITE;
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- }
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- das800_ind_write(dev, conv_bits, CONV_CONTROL);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- das800_enable(dev);
- return 0;
-}
-
-static unsigned int das800_ai_get_sample(struct comedi_device *dev)
-{
- unsigned int lsb = inb(dev->iobase + DAS800_LSB);
- unsigned int msb = inb(dev->iobase + DAS800_MSB);
-
- return (msb << 8) | lsb;
-}
-
-static irqreturn_t das800_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct das800_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async;
- struct comedi_cmd *cmd;
- unsigned long irq_flags;
- unsigned int status;
- unsigned short val;
- bool fifo_empty;
- bool fifo_overflow;
- int i;
-
- status = inb(dev->iobase + DAS800_STATUS);
- if (!(status & IRQ))
- return IRQ_NONE;
- if (!dev->attached)
- return IRQ_HANDLED;
-
- async = s->async;
- cmd = &async->cmd;
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- status = das800_ind_read(dev, CONTROL1) & STATUS2_HCEN;
- /*
- * Don't release spinlock yet since we want to make sure
- * no one else disables hardware conversions.
- */
-
- /* if hardware conversions are not enabled, then quit */
- if (status == 0) {
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- return IRQ_HANDLED;
- }
-
- for (i = 0; i < DAS802_16_HALF_FIFO_SZ; i++) {
- val = das800_ai_get_sample(dev);
- if (s->maxdata == 0x0fff) {
- fifo_empty = !!(val & FIFO_EMPTY);
- fifo_overflow = !!(val & FIFO_OVF);
- } else {
- /* cio-das802/16 has no fifo empty status bit */
- fifo_empty = false;
- fifo_overflow = !!(inb(dev->iobase + DAS800_GAIN) &
- CIO_FFOV);
- }
- if (fifo_empty || fifo_overflow)
- break;
-
- if (s->maxdata == 0x0fff)
- val >>= 4; /* 12-bit sample */
-
- val &= s->maxdata;
- comedi_buf_write_samples(s, &val, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- break;
- }
- }
-
- if (fifo_overflow) {
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- async->events |= COMEDI_CB_ERROR;
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
- }
-
- if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
- /*
- * Re-enable card's interrupt.
- * We already have spinlock, so indirect addressing is safe
- */
- das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits,
- CONTROL1);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- } else {
- /* otherwise, stop taking data */
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- das800_disable(dev);
- }
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static int das800_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DAS800_STATUS);
- if ((status & BUSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int das800_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct das800_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned long irq_flags;
- unsigned int val;
- int ret;
- int i;
-
- das800_disable(dev);
-
- /* set multiplexer */
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- das800_ind_write(dev, chan | devpriv->do_bits, CONTROL1);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- /* set gain / range */
- if (s->maxdata == 0x0fff && range)
- range += 0x7;
- range &= 0xf;
- outb(range, dev->iobase + DAS800_GAIN);
-
- udelay(5);
-
- for (i = 0; i < insn->n; i++) {
- /* trigger conversion */
- outb_p(0, dev->iobase + DAS800_MSB);
-
- ret = comedi_timeout(dev, s, insn, das800_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = das800_ai_get_sample(dev);
- if (s->maxdata == 0x0fff)
- val >>= 4; /* 12-bit sample */
- data[i] = val & s->maxdata;
- }
-
- return insn->n;
-}
-
-static int das800_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = (inb(dev->iobase + DAS800_STATUS) >> 4) & 0x7;
-
- return insn->n;
-}
-
-static int das800_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct das800_private *devpriv = dev->private;
- unsigned long irq_flags;
-
- if (comedi_dio_update_state(s, data)) {
- devpriv->do_bits = s->state << 4;
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits,
- CONTROL1);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static const struct das800_board *das800_probe(struct comedi_device *dev)
-{
- const struct das800_board *board = dev->board_ptr;
- int index = board ? board - das800_boards : -EINVAL;
- int id_bits;
- unsigned long irq_flags;
-
- /*
- * The dev->board_ptr will be set by comedi_device_attach() if the
- * board name provided by the user matches a board->name in this
- * driver. If so, this function sanity checks the id_bits to verify
- * that the board is correct.
- *
- * If the dev->board_ptr is not set, the user is trying to attach
- * an unspecified board to this driver. In this case the id_bits
- * are used to 'probe' for the correct dev->board_ptr.
- */
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- id_bits = das800_ind_read(dev, ID) & 0x3;
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- switch (id_bits) {
- case 0x0:
- if (index == BOARD_DAS800 || index == BOARD_CIODAS800)
- return board;
- index = BOARD_DAS800;
- break;
- case 0x2:
- if (index == BOARD_DAS801 || index == BOARD_CIODAS801)
- return board;
- index = BOARD_DAS801;
- break;
- case 0x3:
- if (index == BOARD_DAS802 || index == BOARD_CIODAS802 ||
- index == BOARD_CIODAS80216)
- return board;
- index = BOARD_DAS802;
- break;
- default:
- dev_dbg(dev->class_dev, "Board model: 0x%x (unknown)\n",
- id_bits);
- return NULL;
- }
- dev_dbg(dev->class_dev, "Board model (probed): %s series\n",
- das800_boards[index].name);
-
- return &das800_boards[index];
-}
-
-static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct das800_board *board;
- struct das800_private *devpriv;
- struct comedi_subdevice *s;
- unsigned int irq = it->options[1];
- unsigned long irq_flags;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x8);
- if (ret)
- return ret;
-
- board = das800_probe(dev);
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- if (irq > 1 && irq <= 7) {
- ret = request_irq(irq, das800_interrupt, 0, "das800",
- dev);
- if (ret == 0)
- dev->irq = irq;
- }
-
- dev->pacer = comedi_8254_init(dev->iobase + DAS800_8254,
- I8254_OSC_BASE_1MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 8;
- s->maxdata = (1 << board->resolution) - 1;
- s->range_table = board->ai_range;
- s->insn_read = das800_ai_insn_read;
- if (dev->irq) {
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 8;
- s->do_cmdtest = das800_ai_do_cmdtest;
- s->do_cmd = das800_ai_do_cmd;
- s->cancel = das800_cancel;
- }
-
- /* Digital Input subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 3;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das800_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das800_do_insn_bits;
-
- das800_disable(dev);
-
- /* initialize digital out channels */
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- return 0;
-};
-
-static struct comedi_driver driver_das800 = {
- .driver_name = "das800",
- .module = THIS_MODULE,
- .attach = das800_attach,
- .detach = comedi_legacy_detach,
- .num_names = ARRAY_SIZE(das800_boards),
- .board_name = &das800_boards[0].name,
- .offset = sizeof(struct das800_board),
-};
-module_comedi_driver(driver_das800);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
deleted file mode 100644
index 56682f01242f..000000000000
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ /dev/null
@@ -1,616 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * dmm32at.c
- * Diamond Systems Diamond-MM-32-AT Comedi driver
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: dmm32at
- * Description: Diamond Systems Diamond-MM-32-AT
- * Devices: [Diamond Systems] Diamond-MM-32-AT (dmm32at)
- * Author: Perry J. Piplani <perry.j.piplani@nasa.gov>
- * Updated: Fri Jun 4 09:13:24 CDT 2004
- * Status: experimental
- *
- * Configuration Options:
- * comedi_config /dev/comedi0 dmm32at baseaddr,irq
- *
- * This driver is for the Diamond Systems MM-32-AT board
- * http://www.diamondsystems.com/products/diamondmm32at
- *
- * It is being used on several projects inside NASA, without
- * problems so far. For analog input commands, TRIG_EXT is not
- * yet supported.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include "../comedidev.h"
-
-#include "8255.h"
-
-/* Board register addresses */
-#define DMM32AT_AI_START_CONV_REG 0x00
-#define DMM32AT_AI_LSB_REG 0x00
-#define DMM32AT_AUX_DOUT_REG 0x01
-#define DMM32AT_AUX_DOUT2 BIT(2) /* J3.42 - OUT2 (OUT2EN) */
-#define DMM32AT_AUX_DOUT1 BIT(1) /* J3.43 */
-#define DMM32AT_AUX_DOUT0 BIT(0) /* J3.44 - OUT0 (OUT0EN) */
-#define DMM32AT_AI_MSB_REG 0x01
-#define DMM32AT_AI_LO_CHAN_REG 0x02
-#define DMM32AT_AI_HI_CHAN_REG 0x03
-#define DMM32AT_AUX_DI_REG 0x04
-#define DMM32AT_AUX_DI_DACBUSY BIT(7)
-#define DMM32AT_AUX_DI_CALBUSY BIT(6)
-#define DMM32AT_AUX_DI3 BIT(3) /* J3.45 - ADCLK (CLKSEL) */
-#define DMM32AT_AUX_DI2 BIT(2) /* J3.46 - GATE12 (GT12EN) */
-#define DMM32AT_AUX_DI1 BIT(1) /* J3.47 - GATE0 (GT0EN) */
-#define DMM32AT_AUX_DI0 BIT(0) /* J3.48 - CLK0 (SRC0) */
-#define DMM32AT_AO_LSB_REG 0x04
-#define DMM32AT_AO_MSB_REG 0x05
-#define DMM32AT_AO_MSB_DACH(x) ((x) << 6)
-#define DMM32AT_FIFO_DEPTH_REG 0x06
-#define DMM32AT_FIFO_CTRL_REG 0x07
-#define DMM32AT_FIFO_CTRL_FIFOEN BIT(3)
-#define DMM32AT_FIFO_CTRL_SCANEN BIT(2)
-#define DMM32AT_FIFO_CTRL_FIFORST BIT(1)
-#define DMM32AT_FIFO_STATUS_REG 0x07
-#define DMM32AT_FIFO_STATUS_EF BIT(7)
-#define DMM32AT_FIFO_STATUS_HF BIT(6)
-#define DMM32AT_FIFO_STATUS_FF BIT(5)
-#define DMM32AT_FIFO_STATUS_OVF BIT(4)
-#define DMM32AT_FIFO_STATUS_FIFOEN BIT(3)
-#define DMM32AT_FIFO_STATUS_SCANEN BIT(2)
-#define DMM32AT_FIFO_STATUS_PAGE_MASK (3 << 0)
-#define DMM32AT_CTRL_REG 0x08
-#define DMM32AT_CTRL_RESETA BIT(5)
-#define DMM32AT_CTRL_RESETD BIT(4)
-#define DMM32AT_CTRL_INTRST BIT(3)
-#define DMM32AT_CTRL_PAGE(x) ((x) << 0)
-#define DMM32AT_CTRL_PAGE_8254 DMM32AT_CTRL_PAGE(0)
-#define DMM32AT_CTRL_PAGE_8255 DMM32AT_CTRL_PAGE(1)
-#define DMM32AT_CTRL_PAGE_CALIB DMM32AT_CTRL_PAGE(3)
-#define DMM32AT_AI_STATUS_REG 0x08
-#define DMM32AT_AI_STATUS_STS BIT(7)
-#define DMM32AT_AI_STATUS_SD1 BIT(6)
-#define DMM32AT_AI_STATUS_SD0 BIT(5)
-#define DMM32AT_AI_STATUS_ADCH_MASK (0x1f << 0)
-#define DMM32AT_INTCLK_REG 0x09
-#define DMM32AT_INTCLK_ADINT BIT(7)
-#define DMM32AT_INTCLK_DINT BIT(6)
-#define DMM32AT_INTCLK_TINT BIT(5)
-#define DMM32AT_INTCLK_CLKEN BIT(1) /* 1=see below 0=software */
-#define DMM32AT_INTCLK_CLKSEL BIT(0) /* 1=OUT2 0=EXTCLK */
-#define DMM32AT_CTRDIO_CFG_REG 0x0a
-#define DMM32AT_CTRDIO_CFG_FREQ12 BIT(7) /* CLK12 1=100KHz 0=10MHz */
-#define DMM32AT_CTRDIO_CFG_FREQ0 BIT(6) /* CLK0 1=10KHz 0=10MHz */
-#define DMM32AT_CTRDIO_CFG_OUT2EN BIT(5) /* J3.42 1=OUT2 is DOUT2 */
-#define DMM32AT_CTRDIO_CFG_OUT0EN BIT(4) /* J3,44 1=OUT0 is DOUT0 */
-#define DMM32AT_CTRDIO_CFG_GT0EN BIT(2) /* J3.47 1=DIN1 is GATE0 */
-#define DMM32AT_CTRDIO_CFG_SRC0 BIT(1) /* CLK0 is 0=FREQ0 1=J3.48 */
-#define DMM32AT_CTRDIO_CFG_GT12EN BIT(0) /* J3.46 1=DIN2 is GATE12 */
-#define DMM32AT_AI_CFG_REG 0x0b
-#define DMM32AT_AI_CFG_SCINT(x) ((x) << 4)
-#define DMM32AT_AI_CFG_SCINT_20US DMM32AT_AI_CFG_SCINT(0)
-#define DMM32AT_AI_CFG_SCINT_15US DMM32AT_AI_CFG_SCINT(1)
-#define DMM32AT_AI_CFG_SCINT_10US DMM32AT_AI_CFG_SCINT(2)
-#define DMM32AT_AI_CFG_SCINT_5US DMM32AT_AI_CFG_SCINT(3)
-#define DMM32AT_AI_CFG_RANGE BIT(3) /* 0=5V 1=10V */
-#define DMM32AT_AI_CFG_ADBU BIT(2) /* 0=bipolar 1=unipolar */
-#define DMM32AT_AI_CFG_GAIN(x) ((x) << 0)
-#define DMM32AT_AI_READBACK_REG 0x0b
-#define DMM32AT_AI_READBACK_WAIT BIT(7) /* DMM32AT_AI_STATUS_STS */
-#define DMM32AT_AI_READBACK_RANGE BIT(3)
-#define DMM32AT_AI_READBACK_ADBU BIT(2)
-#define DMM32AT_AI_READBACK_GAIN_MASK (3 << 0)
-
-#define DMM32AT_CLK1 0x0d
-#define DMM32AT_CLK2 0x0e
-#define DMM32AT_CLKCT 0x0f
-
-#define DMM32AT_8255_IOBASE 0x0c /* Page 1 registers */
-
-/* Board register values. */
-
-/* DMM32AT_AI_CFG_REG 0x0b */
-#define DMM32AT_RANGE_U10 0x0c
-#define DMM32AT_RANGE_U5 0x0d
-#define DMM32AT_RANGE_B10 0x08
-#define DMM32AT_RANGE_B5 0x00
-
-/* DMM32AT_CLKCT 0x0f */
-#define DMM32AT_CLKCT1 0x56 /* mode3 counter 1 - write low byte only */
-#define DMM32AT_CLKCT2 0xb6 /* mode3 counter 2 - write high and low byte */
-
-/* board AI ranges in comedi structure */
-static const struct comedi_lrange dmm32at_airanges = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- BIP_RANGE(10),
- BIP_RANGE(5)
- }
-};
-
-/* register values for above ranges */
-static const unsigned char dmm32at_rangebits[] = {
- DMM32AT_RANGE_U10,
- DMM32AT_RANGE_U5,
- DMM32AT_RANGE_B10,
- DMM32AT_RANGE_B5,
-};
-
-/* only one of these ranges is valid, as set by a jumper on the
- * board. The application should only use the range set by the jumper
- */
-static const struct comedi_lrange dmm32at_aoranges = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- BIP_RANGE(10),
- BIP_RANGE(5)
- }
-};
-
-static void dmm32at_ai_set_chanspec(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chanspec, int nchan)
-{
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int last_chan = (chan + nchan - 1) % s->n_chan;
-
- outb(DMM32AT_FIFO_CTRL_FIFORST, dev->iobase + DMM32AT_FIFO_CTRL_REG);
-
- if (nchan > 1)
- outb(DMM32AT_FIFO_CTRL_SCANEN,
- dev->iobase + DMM32AT_FIFO_CTRL_REG);
-
- outb(chan, dev->iobase + DMM32AT_AI_LO_CHAN_REG);
- outb(last_chan, dev->iobase + DMM32AT_AI_HI_CHAN_REG);
- outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AI_CFG_REG);
-}
-
-static unsigned int dmm32at_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- val = inb(dev->iobase + DMM32AT_AI_LSB_REG);
- val |= (inb(dev->iobase + DMM32AT_AI_MSB_REG) << 8);
-
- /* munge two's complement value to offset binary */
- return comedi_offset_munge(s, val);
-}
-
-static int dmm32at_ai_status(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + context);
- if ((status & DMM32AT_AI_STATUS_STS) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int dmm32at_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- int i;
-
- dmm32at_ai_set_chanspec(dev, s, insn->chanspec, 1);
-
- /* wait for circuit to settle */
- ret = comedi_timeout(dev, s, insn, dmm32at_ai_status,
- DMM32AT_AI_READBACK_REG);
- if (ret)
- return ret;
-
- for (i = 0; i < insn->n; i++) {
- outb(0xff, dev->iobase + DMM32AT_AI_START_CONV_REG);
-
- ret = comedi_timeout(dev, s, insn, dmm32at_ai_status,
- DMM32AT_AI_STATUS_REG);
- if (ret)
- return ret;
-
- data[i] = dmm32at_ai_get_sample(dev, s);
- }
-
- return insn->n;
-}
-
-static int dmm32at_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- int i;
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- if (chan != (chan0 + i) % s->n_chan) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- return -EINVAL;
- }
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must all have the same gain\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int dmm32at_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 1000000);
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 1000000000);
-
- if (cmd->convert_arg >= 17500)
- cmd->convert_arg = 20000;
- else if (cmd->convert_arg >= 12500)
- cmd->convert_arg = 15000;
- else if (cmd->convert_arg >= 7500)
- cmd->convert_arg = 10000;
- else
- cmd->convert_arg = 5000;
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- arg = cmd->convert_arg * cmd->scan_end_arg;
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= dmm32at_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
-{
- unsigned char lo1, lo2, hi2;
- unsigned short both2;
-
- /* based on 10mhz clock */
- lo1 = 200;
- both2 = nansec / 20000;
- hi2 = (both2 & 0xff00) >> 8;
- lo2 = both2 & 0x00ff;
-
- /* set counter clocks to 10MHz, disable all aux dio */
- outb(0, dev->iobase + DMM32AT_CTRDIO_CFG_REG);
-
- /* get access to the clock regs */
- outb(DMM32AT_CTRL_PAGE_8254, dev->iobase + DMM32AT_CTRL_REG);
-
- /* write the counter 1 control word and low byte to counter */
- outb(DMM32AT_CLKCT1, dev->iobase + DMM32AT_CLKCT);
- outb(lo1, dev->iobase + DMM32AT_CLK1);
-
- /* write the counter 2 control word and low byte then to counter */
- outb(DMM32AT_CLKCT2, dev->iobase + DMM32AT_CLKCT);
- outb(lo2, dev->iobase + DMM32AT_CLK2);
- outb(hi2, dev->iobase + DMM32AT_CLK2);
-
- /* enable the ai conversion interrupt and the clock to start scans */
- outb(DMM32AT_INTCLK_ADINT |
- DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL,
- dev->iobase + DMM32AT_INTCLK_REG);
-}
-
-static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len);
-
- /* reset the interrupt just in case */
- outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG);
-
- /*
- * wait for circuit to settle
- * we don't have the 'insn' here but it's not needed
- */
- ret = comedi_timeout(dev, s, NULL, dmm32at_ai_status,
- DMM32AT_AI_READBACK_REG);
- if (ret)
- return ret;
-
- if (cmd->stop_src == TRIG_NONE || cmd->stop_arg > 1) {
- /* start the clock and enable the interrupts */
- dmm32at_setaitimer(dev, cmd->scan_begin_arg);
- } else {
- /* start the interrupts and initiate a single scan */
- outb(DMM32AT_INTCLK_ADINT, dev->iobase + DMM32AT_INTCLK_REG);
- outb(0xff, dev->iobase + DMM32AT_AI_START_CONV_REG);
- }
-
- return 0;
-}
-
-static int dmm32at_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- /* disable further interrupts and clocks */
- outb(0x0, dev->iobase + DMM32AT_INTCLK_REG);
- return 0;
-}
-
-static irqreturn_t dmm32at_isr(int irq, void *d)
-{
- struct comedi_device *dev = d;
- unsigned char intstat;
- unsigned short val;
- int i;
-
- if (!dev->attached) {
- dev_err(dev->class_dev, "spurious interrupt\n");
- return IRQ_HANDLED;
- }
-
- intstat = inb(dev->iobase + DMM32AT_INTCLK_REG);
-
- if (intstat & DMM32AT_INTCLK_ADINT) {
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- val = dmm32at_ai_get_sample(dev, s);
- comedi_buf_write_samples(s, &val, 1);
- }
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
- }
-
- /* reset the interrupt */
- outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG);
- return IRQ_HANDLED;
-}
-
-static int dmm32at_ao_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + DMM32AT_AUX_DI_REG);
- if ((status & DMM32AT_AUX_DI_DACBUSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int dmm32at_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
- int ret;
-
- /* write LSB then MSB + chan to load DAC */
- outb(val & 0xff, dev->iobase + DMM32AT_AO_LSB_REG);
- outb((val >> 8) | DMM32AT_AO_MSB_DACH(chan),
- dev->iobase + DMM32AT_AO_MSB_REG);
-
- /* wait for circuit to settle */
- ret = comedi_timeout(dev, s, insn, dmm32at_ao_eoc, 0);
- if (ret)
- return ret;
-
- /* dummy read to update DAC */
- inb(dev->iobase + DMM32AT_AO_MSB_REG);
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int dmm32at_8255_io(struct comedi_device *dev,
- int dir, int port, int data, unsigned long regbase)
-{
- /* get access to the DIO regs */
- outb(DMM32AT_CTRL_PAGE_8255, dev->iobase + DMM32AT_CTRL_REG);
-
- if (dir) {
- outb(data, dev->iobase + regbase + port);
- return 0;
- }
- return inb(dev->iobase + regbase + port);
-}
-
-/* Make sure the board is there and put it to a known state */
-static int dmm32at_reset(struct comedi_device *dev)
-{
- unsigned char aihi, ailo, fifostat, aistat, intstat, airback;
-
- /* reset the board */
- outb(DMM32AT_CTRL_RESETA, dev->iobase + DMM32AT_CTRL_REG);
-
- /* allow a millisecond to reset */
- usleep_range(1000, 3000);
-
- /* zero scan and fifo control */
- outb(0x0, dev->iobase + DMM32AT_FIFO_CTRL_REG);
-
- /* zero interrupt and clock control */
- outb(0x0, dev->iobase + DMM32AT_INTCLK_REG);
-
- /* write a test channel range, the high 3 bits should drop */
- outb(0x80, dev->iobase + DMM32AT_AI_LO_CHAN_REG);
- outb(0xff, dev->iobase + DMM32AT_AI_HI_CHAN_REG);
-
- /* set the range at 10v unipolar */
- outb(DMM32AT_RANGE_U10, dev->iobase + DMM32AT_AI_CFG_REG);
-
- /* should take 10 us to settle, here's a hundred */
- usleep_range(100, 200);
-
- /* read back the values */
- ailo = inb(dev->iobase + DMM32AT_AI_LO_CHAN_REG);
- aihi = inb(dev->iobase + DMM32AT_AI_HI_CHAN_REG);
- fifostat = inb(dev->iobase + DMM32AT_FIFO_STATUS_REG);
- aistat = inb(dev->iobase + DMM32AT_AI_STATUS_REG);
- intstat = inb(dev->iobase + DMM32AT_INTCLK_REG);
- airback = inb(dev->iobase + DMM32AT_AI_READBACK_REG);
-
- /*
- * NOTE: The (DMM32AT_AI_STATUS_SD1 | DMM32AT_AI_STATUS_SD0)
- * test makes this driver only work if the board is configured
- * with all A/D channels set for single-ended operation.
- */
- if (ailo != 0x00 || aihi != 0x1f ||
- fifostat != DMM32AT_FIFO_STATUS_EF ||
- aistat != (DMM32AT_AI_STATUS_SD1 | DMM32AT_AI_STATUS_SD0) ||
- intstat != 0x00 || airback != 0x0c)
- return -EIO;
-
- return 0;
-}
-
-static int dmm32at_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- ret = dmm32at_reset(dev);
- if (ret) {
- dev_err(dev->class_dev, "board detection failed\n");
- return ret;
- }
-
- if (it->options[1]) {
- ret = request_irq(it->options[1], dmm32at_isr, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 32;
- s->maxdata = 0xffff;
- s->range_table = &dmm32at_airanges;
- s->insn_read = dmm32at_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmd = dmm32at_ai_cmd;
- s->do_cmdtest = dmm32at_ai_cmdtest;
- s->cancel = dmm32at_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0x0fff;
- s->range_table = &dmm32at_aoranges;
- s->insn_write = dmm32at_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- return subdev_8255_init(dev, s, dmm32at_8255_io, DMM32AT_8255_IOBASE);
-}
-
-static struct comedi_driver dmm32at_driver = {
- .driver_name = "dmm32at",
- .module = THIS_MODULE,
- .attach = dmm32at_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(dmm32at_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi: Diamond Systems Diamond-MM-32-AT");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
deleted file mode 100644
index 0d571d817b4e..000000000000
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ /dev/null
@@ -1,645 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * comedi/drivers/dt2801.c
- * Device Driver for DataTranslation DT2801
- *
- */
-/*
- * Driver: dt2801
- * Description: Data Translation DT2801 series and DT01-EZ
- * Author: ds
- * Status: works
- * Devices: [Data Translation] DT2801 (dt2801), DT2801-A, DT2801/5716A,
- * DT2805, DT2805/5716A, DT2808, DT2818, DT2809, DT01-EZ
- *
- * This driver can autoprobe the type of board.
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - unused
- * [2] - A/D reference 0=differential, 1=single-ended
- * [3] - A/D range
- * 0 = [-10, 10]
- * 1 = [0,10]
- * [4] - D/A 0 range
- * 0 = [-10, 10]
- * 1 = [-5,5]
- * 2 = [-2.5,2.5]
- * 3 = [0,10]
- * 4 = [0,5]
- * [5] - D/A 1 range (same choices)
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-#include <linux/delay.h>
-
-#define DT2801_TIMEOUT 1000
-
-/* Hardware Configuration */
-/* ====================== */
-
-#define DT2801_MAX_DMA_SIZE (64 * 1024)
-
-/* define's */
-/* ====================== */
-
-/* Commands */
-#define DT_C_RESET 0x0
-#define DT_C_CLEAR_ERR 0x1
-#define DT_C_READ_ERRREG 0x2
-#define DT_C_SET_CLOCK 0x3
-
-#define DT_C_TEST 0xb
-#define DT_C_STOP 0xf
-
-#define DT_C_SET_DIGIN 0x4
-#define DT_C_SET_DIGOUT 0x5
-#define DT_C_READ_DIG 0x6
-#define DT_C_WRITE_DIG 0x7
-
-#define DT_C_WRITE_DAIM 0x8
-#define DT_C_SET_DA 0x9
-#define DT_C_WRITE_DA 0xa
-
-#define DT_C_READ_ADIM 0xc
-#define DT_C_SET_AD 0xd
-#define DT_C_READ_AD 0xe
-
-/*
- * Command modifiers (only used with read/write), EXTTRIG can be
- * used with some other commands.
- */
-#define DT_MOD_DMA BIT(4)
-#define DT_MOD_CONT BIT(5)
-#define DT_MOD_EXTCLK BIT(6)
-#define DT_MOD_EXTTRIG BIT(7)
-
-/* Bits in status register */
-#define DT_S_DATA_OUT_READY BIT(0)
-#define DT_S_DATA_IN_FULL BIT(1)
-#define DT_S_READY BIT(2)
-#define DT_S_COMMAND BIT(3)
-#define DT_S_COMPOSITE_ERROR BIT(7)
-
-/* registers */
-#define DT2801_DATA 0
-#define DT2801_STATUS 1
-#define DT2801_CMD 1
-
-#if 0
-/* ignore 'defined but not used' warning */
-static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-#endif
-static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.02)
- }
-};
-
-#if 0
-/* ignore 'defined but not used' warning */
-static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-#endif
-static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.02)
- }
-};
-
-struct dt2801_board {
- const char *name;
- int boardcode;
- int ad_diff;
- int ad_chan;
- int adbits;
- int adrangetype;
- int dabits;
-};
-
-/*
- * Typeid's for the different boards of the DT2801-series
- * (taken from the test-software, that comes with the board)
- */
-static const struct dt2801_board boardtypes[] = {
- {
- .name = "dt2801",
- .boardcode = 0x09,
- .ad_diff = 2,
- .ad_chan = 16,
- .adbits = 12,
- .adrangetype = 0,
- .dabits = 12},
- {
- .name = "dt2801-a",
- .boardcode = 0x52,
- .ad_diff = 2,
- .ad_chan = 16,
- .adbits = 12,
- .adrangetype = 0,
- .dabits = 12},
- {
- .name = "dt2801/5716a",
- .boardcode = 0x82,
- .ad_diff = 1,
- .ad_chan = 16,
- .adbits = 16,
- .adrangetype = 1,
- .dabits = 12},
- {
- .name = "dt2805",
- .boardcode = 0x12,
- .ad_diff = 1,
- .ad_chan = 16,
- .adbits = 12,
- .adrangetype = 0,
- .dabits = 12},
- {
- .name = "dt2805/5716a",
- .boardcode = 0x92,
- .ad_diff = 1,
- .ad_chan = 16,
- .adbits = 16,
- .adrangetype = 1,
- .dabits = 12},
- {
- .name = "dt2808",
- .boardcode = 0x20,
- .ad_diff = 0,
- .ad_chan = 16,
- .adbits = 12,
- .adrangetype = 2,
- .dabits = 8},
- {
- .name = "dt2818",
- .boardcode = 0xa2,
- .ad_diff = 0,
- .ad_chan = 4,
- .adbits = 12,
- .adrangetype = 0,
- .dabits = 12},
- {
- .name = "dt2809",
- .boardcode = 0xb0,
- .ad_diff = 0,
- .ad_chan = 8,
- .adbits = 12,
- .adrangetype = 1,
- .dabits = 12},
-};
-
-struct dt2801_private {
- const struct comedi_lrange *dac_range_types[2];
-};
-
-/*
- * These are the low-level routines:
- * writecommand: write a command to the board
- * writedata: write data byte
- * readdata: read data byte
- */
-
-/*
- * Only checks DataOutReady-flag, not the Ready-flag as it is done
- * in the examples of the manual. I don't see why this should be
- * necessary.
- */
-static int dt2801_readdata(struct comedi_device *dev, int *data)
-{
- int stat = 0;
- int timeout = DT2801_TIMEOUT;
-
- do {
- stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY))
- return stat;
- if (stat & DT_S_DATA_OUT_READY) {
- *data = inb_p(dev->iobase + DT2801_DATA);
- return 0;
- }
- } while (--timeout > 0);
-
- return -ETIME;
-}
-
-static int dt2801_readdata2(struct comedi_device *dev, int *data)
-{
- int lb = 0;
- int hb = 0;
- int ret;
-
- ret = dt2801_readdata(dev, &lb);
- if (ret)
- return ret;
- ret = dt2801_readdata(dev, &hb);
- if (ret)
- return ret;
-
- *data = (hb << 8) + lb;
- return 0;
-}
-
-static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
-{
- int stat = 0;
- int timeout = DT2801_TIMEOUT;
-
- do {
- stat = inb_p(dev->iobase + DT2801_STATUS);
-
- if (stat & DT_S_COMPOSITE_ERROR)
- return stat;
- if (!(stat & DT_S_DATA_IN_FULL)) {
- outb_p(data & 0xff, dev->iobase + DT2801_DATA);
- return 0;
- }
- } while (--timeout > 0);
-
- return -ETIME;
-}
-
-static int dt2801_writedata2(struct comedi_device *dev, unsigned int data)
-{
- int ret;
-
- ret = dt2801_writedata(dev, data & 0xff);
- if (ret < 0)
- return ret;
- ret = dt2801_writedata(dev, data >> 8);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int dt2801_wait_for_ready(struct comedi_device *dev)
-{
- int timeout = DT2801_TIMEOUT;
- int stat;
-
- stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & DT_S_READY)
- return 0;
- do {
- stat = inb_p(dev->iobase + DT2801_STATUS);
-
- if (stat & DT_S_COMPOSITE_ERROR)
- return stat;
- if (stat & DT_S_READY)
- return 0;
- } while (--timeout > 0);
-
- return -ETIME;
-}
-
-static void dt2801_writecmd(struct comedi_device *dev, int command)
-{
- int stat;
-
- dt2801_wait_for_ready(dev);
-
- stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & DT_S_COMPOSITE_ERROR) {
- dev_dbg(dev->class_dev,
- "composite-error in %s, ignoring\n", __func__);
- }
- if (!(stat & DT_S_READY))
- dev_dbg(dev->class_dev, "!ready in %s, ignoring\n", __func__);
- outb_p(command, dev->iobase + DT2801_CMD);
-}
-
-static int dt2801_reset(struct comedi_device *dev)
-{
- int board_code = 0;
- unsigned int stat;
- int timeout;
-
- /* pull random data from data port */
- inb_p(dev->iobase + DT2801_DATA);
- inb_p(dev->iobase + DT2801_DATA);
- inb_p(dev->iobase + DT2801_DATA);
- inb_p(dev->iobase + DT2801_DATA);
-
- /* dt2801_writecmd(dev,DT_C_STOP); */
- outb_p(DT_C_STOP, dev->iobase + DT2801_CMD);
-
- /* dt2801_wait_for_ready(dev); */
- usleep_range(100, 200);
- timeout = 10000;
- do {
- stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & DT_S_READY)
- break;
- } while (timeout--);
- if (!timeout)
- dev_dbg(dev->class_dev, "timeout 1 status=0x%02x\n", stat);
-
- /* dt2801_readdata(dev,&board_code); */
-
- outb_p(DT_C_RESET, dev->iobase + DT2801_CMD);
- /* dt2801_writecmd(dev,DT_C_RESET); */
-
- usleep_range(100, 200);
- timeout = 10000;
- do {
- stat = inb_p(dev->iobase + DT2801_STATUS);
- if (stat & DT_S_READY)
- break;
- } while (timeout--);
- if (!timeout)
- dev_dbg(dev->class_dev, "timeout 2 status=0x%02x\n", stat);
-
- dt2801_readdata(dev, &board_code);
-
- return board_code;
-}
-
-static int probe_number_of_ai_chans(struct comedi_device *dev)
-{
- int n_chans;
- int stat;
- int data;
-
- for (n_chans = 0; n_chans < 16; n_chans++) {
- dt2801_writecmd(dev, DT_C_READ_ADIM);
- dt2801_writedata(dev, 0);
- dt2801_writedata(dev, n_chans);
- stat = dt2801_readdata2(dev, &data);
-
- if (stat)
- break;
- }
-
- dt2801_reset(dev);
- dt2801_reset(dev);
-
- return n_chans;
-}
-
-static const struct comedi_lrange *dac_range_table[] = {
- &range_bipolar10,
- &range_bipolar5,
- &range_bipolar2_5,
- &range_unipolar10,
- &range_unipolar5
-};
-
-static const struct comedi_lrange *dac_range_lkup(int opt)
-{
- if (opt < 0 || opt >= 5)
- return &range_unknown;
- return dac_range_table[opt];
-}
-
-static const struct comedi_lrange *ai_range_lkup(int type, int opt)
-{
- switch (type) {
- case 0:
- return (opt) ?
- &range_dt2801_ai_pgl_unipolar :
- &range_dt2801_ai_pgl_bipolar;
- case 1:
- return (opt) ? &range_unipolar10 : &range_bipolar10;
- case 2:
- return &range_unipolar5;
- }
- return &range_unknown;
-}
-
-static int dt2801_error(struct comedi_device *dev, int stat)
-{
- if (stat < 0) {
- if (stat == -ETIME)
- dev_dbg(dev->class_dev, "timeout\n");
- else
- dev_dbg(dev->class_dev, "error %d\n", stat);
- return stat;
- }
- dev_dbg(dev->class_dev, "error status 0x%02x, resetting...\n", stat);
-
- dt2801_reset(dev);
- dt2801_reset(dev);
-
- return -EIO;
-}
-
-static int dt2801_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int d;
- int stat;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- dt2801_writecmd(dev, DT_C_READ_ADIM);
- dt2801_writedata(dev, CR_RANGE(insn->chanspec));
- dt2801_writedata(dev, CR_CHAN(insn->chanspec));
- stat = dt2801_readdata2(dev, &d);
-
- if (stat != 0)
- return dt2801_error(dev, stat);
-
- data[i] = d;
- }
-
- return i;
-}
-
-static int dt2801_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- dt2801_writecmd(dev, DT_C_WRITE_DAIM);
- dt2801_writedata(dev, chan);
- dt2801_writedata2(dev, data[0]);
-
- s->readback[chan] = data[0];
-
- return 1;
-}
-
-static int dt2801_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int which = (s == &dev->subdevices[3]) ? 1 : 0;
- unsigned int val = 0;
-
- if (comedi_dio_update_state(s, data)) {
- dt2801_writecmd(dev, DT_C_WRITE_DIG);
- dt2801_writedata(dev, which);
- dt2801_writedata(dev, s->state);
- }
-
- dt2801_writecmd(dev, DT_C_READ_DIG);
- dt2801_writedata(dev, which);
- dt2801_readdata(dev, &val);
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int dt2801_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
- if (ret)
- return ret;
-
- dt2801_writecmd(dev, s->io_bits ? DT_C_SET_DIGOUT : DT_C_SET_DIGIN);
- dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0);
-
- return insn->n;
-}
-
-/*
- * options:
- * [0] - i/o base
- * [1] - unused
- * [2] - a/d 0=differential, 1=single-ended
- * [3] - a/d range 0=[-10,10], 1=[0,10]
- * [4] - dac0 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
- * [5] - dac1 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
- */
-static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct dt2801_board *board;
- struct dt2801_private *devpriv;
- struct comedi_subdevice *s;
- int board_code, type;
- int ret = 0;
- int n_ai_chans;
-
- ret = comedi_request_region(dev, it->options[0], 0x2);
- if (ret)
- return ret;
-
- /* do some checking */
-
- board_code = dt2801_reset(dev);
-
- /* heh. if it didn't work, try it again. */
- if (!board_code)
- board_code = dt2801_reset(dev);
-
- for (type = 0; type < ARRAY_SIZE(boardtypes); type++) {
- if (boardtypes[type].boardcode == board_code)
- goto havetype;
- }
- dev_dbg(dev->class_dev,
- "unrecognized board code=0x%02x, contact author\n", board_code);
- type = 0;
-
-havetype:
- dev->board_ptr = boardtypes + type;
- board = dev->board_ptr;
-
- n_ai_chans = probe_number_of_ai_chans(dev);
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- goto out;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- dev->board_name = board->name;
-
- s = &dev->subdevices[0];
- /* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
-#if 1
- s->n_chan = n_ai_chans;
-#else
- if (it->options[2])
- s->n_chan = board->ad_chan;
- else
- s->n_chan = board->ad_chan / 2;
-#endif
- s->maxdata = (1 << board->adbits) - 1;
- s->range_table = ai_range_lkup(board->adrangetype, it->options[3]);
- s->insn_read = dt2801_ai_insn_read;
-
- s = &dev->subdevices[1];
- /* ao subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = (1 << board->dabits) - 1;
- s->range_table_list = devpriv->dac_range_types;
- devpriv->dac_range_types[0] = dac_range_lkup(it->options[4]);
- devpriv->dac_range_types[1] = dac_range_lkup(it->options[5]);
- s->insn_write = dt2801_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s = &dev->subdevices[2];
- /* 1st digital subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dt2801_dio_insn_bits;
- s->insn_config = dt2801_dio_insn_config;
-
- s = &dev->subdevices[3];
- /* 2nd digital subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dt2801_dio_insn_bits;
- s->insn_config = dt2801_dio_insn_config;
-
- ret = 0;
-out:
- return ret;
-}
-
-static struct comedi_driver dt2801_driver = {
- .driver_name = "dt2801",
- .module = THIS_MODULE,
- .attach = dt2801_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(dt2801_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
deleted file mode 100644
index 0eb5e6ba6916..000000000000
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ /dev/null
@@ -1,645 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for Data Translation DT2811
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: dt2811
- * Description: Data Translation DT2811
- * Author: ds
- * Devices: [Data Translation] DT2811-PGL (dt2811-pgl), DT2811-PGH (dt2811-pgh)
- * Status: works
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (optional, needed for async command support)
- * [2] - A/D reference (# of analog inputs)
- * 0 = single-ended (16 channels)
- * 1 = differential (8 channels)
- * 2 = pseudo-differential (16 channels)
- * [3] - A/D range (deprecated, see below)
- * [4] - D/A 0 range (deprecated, see below)
- * [5] - D/A 1 range (deprecated, see below)
- *
- * Notes:
- * - A/D ranges are not programmable but the gain is. The AI subdevice has
- * a range_table containing all the possible analog input range/gain
- * options for the dt2811-pgh or dt2811-pgl. Use the range that matches
- * your board configuration and the desired gain to correctly convert
- * between data values and physical units and to set the correct output
- * gain.
- * - D/A ranges are not programmable. The AO subdevice has a range_table
- * containing all the possible analog output ranges. Use the range
- * that matches your board configuration to convert between data
- * values and physical units.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include "../comedidev.h"
-
-/*
- * Register I/O map
- */
-#define DT2811_ADCSR_REG 0x00 /* r/w A/D Control/Status */
-#define DT2811_ADCSR_ADDONE BIT(7) /* r 1=A/D conv done */
-#define DT2811_ADCSR_ADERROR BIT(6) /* r 1=A/D error */
-#define DT2811_ADCSR_ADBUSY BIT(5) /* r 1=A/D busy */
-#define DT2811_ADCSR_CLRERROR BIT(4)
-#define DT2811_ADCSR_DMAENB BIT(3) /* r/w 1=dma ena */
-#define DT2811_ADCSR_INTENB BIT(2) /* r/w 1=interrupts ena */
-#define DT2811_ADCSR_ADMODE(x) (((x) & 0x3) << 0)
-
-#define DT2811_ADGCR_REG 0x01 /* r/w A/D Gain/Channel */
-#define DT2811_ADGCR_GAIN(x) (((x) & 0x3) << 6)
-#define DT2811_ADGCR_CHAN(x) (((x) & 0xf) << 0)
-
-#define DT2811_ADDATA_LO_REG 0x02 /* r A/D Data low byte */
-#define DT2811_ADDATA_HI_REG 0x03 /* r A/D Data high byte */
-
-#define DT2811_DADATA_LO_REG(x) (0x02 + ((x) * 2)) /* w D/A Data low */
-#define DT2811_DADATA_HI_REG(x) (0x03 + ((x) * 2)) /* w D/A Data high */
-
-#define DT2811_DI_REG 0x06 /* r Digital Input Port 0 */
-#define DT2811_DO_REG 0x06 /* w Digital Output Port 1 */
-
-#define DT2811_TMRCTR_REG 0x07 /* r/w Timer/Counter */
-#define DT2811_TMRCTR_MANTISSA(x) (((x) & 0x7) << 3)
-#define DT2811_TMRCTR_EXPONENT(x) (((x) & 0x7) << 0)
-
-#define DT2811_OSC_BASE 1666 /* 600 kHz = 1666.6667ns */
-
-/*
- * Timer frequency control:
- * DT2811_TMRCTR_MANTISSA DT2811_TMRCTR_EXPONENT
- * val divisor frequency val multiply divisor/divide frequency by
- * 0 1 600 kHz 0 1
- * 1 10 60 kHz 1 10
- * 2 2 300 kHz 2 100
- * 3 3 200 kHz 3 1000
- * 4 4 150 kHz 4 10000
- * 5 5 120 kHz 5 100000
- * 6 6 100 kHz 6 1000000
- * 7 12 50 kHz 7 10000000
- */
-static const unsigned int dt2811_clk_dividers[] = {
- 1, 10, 2, 3, 4, 5, 6, 12
-};
-
-static const unsigned int dt2811_clk_multipliers[] = {
- 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
-};
-
-/*
- * The Analog Input range is set using jumpers on the board.
- *
- * Input Range W9 W10
- * -5V to +5V In Out
- * -2.5V to +2.5V In In
- * 0V to +5V Out In
- *
- * The gain may be set to 1, 2, 4, or 8 (on the dt2811-pgh) or to
- * 1, 10, 100, 500 (on the dt2811-pgl).
- */
-static const struct comedi_lrange dt2811_pgh_ai_ranges = {
- 12, {
- BIP_RANGE(5), /* range 0: gain=1 */
- BIP_RANGE(2.5), /* range 1: gain=2 */
- BIP_RANGE(1.25), /* range 2: gain=4 */
- BIP_RANGE(0.625), /* range 3: gain=8 */
-
- BIP_RANGE(2.5), /* range 0+4: gain=1 */
- BIP_RANGE(1.25), /* range 1+4: gain=2 */
- BIP_RANGE(0.625), /* range 2+4: gain=4 */
- BIP_RANGE(0.3125), /* range 3+4: gain=8 */
-
- UNI_RANGE(5), /* range 0+8: gain=1 */
- UNI_RANGE(2.5), /* range 1+8: gain=2 */
- UNI_RANGE(1.25), /* range 2+8: gain=4 */
- UNI_RANGE(0.625) /* range 3+8: gain=8 */
- }
-};
-
-static const struct comedi_lrange dt2811_pgl_ai_ranges = {
- 12, {
- BIP_RANGE(5), /* range 0: gain=1 */
- BIP_RANGE(0.5), /* range 1: gain=10 */
- BIP_RANGE(0.05), /* range 2: gain=100 */
- BIP_RANGE(0.01), /* range 3: gain=500 */
-
- BIP_RANGE(2.5), /* range 0+4: gain=1 */
- BIP_RANGE(0.25), /* range 1+4: gain=10 */
- BIP_RANGE(0.025), /* range 2+4: gain=100 */
- BIP_RANGE(0.005), /* range 3+4: gain=500 */
-
- UNI_RANGE(5), /* range 0+8: gain=1 */
- UNI_RANGE(0.5), /* range 1+8: gain=10 */
- UNI_RANGE(0.05), /* range 2+8: gain=100 */
- UNI_RANGE(0.01) /* range 3+8: gain=500 */
- }
-};
-
-/*
- * The Analog Output range is set per-channel using jumpers on the board.
- *
- * DAC0 Jumpers DAC1 Jumpers
- * Output Range W5 W6 W7 W8 W1 W2 W3 W4
- * -5V to +5V In Out In Out In Out In Out
- * -2.5V to +2.5V In Out Out In In Out Out In
- * 0 to +5V Out In Out In Out In Out In
- */
-static const struct comedi_lrange dt2811_ao_ranges = {
- 3, {
- BIP_RANGE(5), /* default setting from factory */
- BIP_RANGE(2.5),
- UNI_RANGE(5)
- }
-};
-
-struct dt2811_board {
- const char *name;
- unsigned int is_pgh:1;
-};
-
-static const struct dt2811_board dt2811_boards[] = {
- {
- .name = "dt2811-pgh",
- .is_pgh = 1,
- }, {
- .name = "dt2811-pgl",
- },
-};
-
-struct dt2811_private {
- unsigned int ai_divisor;
-};
-
-static unsigned int dt2811_ai_read_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- val = inb(dev->iobase + DT2811_ADDATA_LO_REG) |
- (inb(dev->iobase + DT2811_ADDATA_HI_REG) << 8);
-
- return val & s->maxdata;
-}
-
-static irqreturn_t dt2811_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int status;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- status = inb(dev->iobase + DT2811_ADCSR_REG);
-
- if (status & DT2811_ADCSR_ADERROR) {
- async->events |= COMEDI_CB_OVERFLOW;
-
- outb(status | DT2811_ADCSR_CLRERROR,
- dev->iobase + DT2811_ADCSR_REG);
- }
-
- if (status & DT2811_ADCSR_ADDONE) {
- unsigned short val;
-
- val = dt2811_ai_read_sample(dev, s);
- comedi_buf_write_samples(s, &val, 1);
- }
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int dt2811_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- /*
- * Mode 0
- * Single conversion
- *
- * Loading a chanspec will trigger a conversion.
- */
- outb(DT2811_ADCSR_ADMODE(0), dev->iobase + DT2811_ADCSR_REG);
-
- return 0;
-}
-
-static void dt2811_ai_set_chanspec(struct comedi_device *dev,
- unsigned int chanspec)
-{
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
-
- outb(DT2811_ADGCR_CHAN(chan) | DT2811_ADGCR_GAIN(range),
- dev->iobase + DT2811_ADGCR_REG);
-}
-
-static int dt2811_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dt2811_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int mode;
-
- if (cmd->start_src == TRIG_NOW) {
- /*
- * Mode 1
- * Continuous conversion, internal trigger and clock
- *
- * This resets the trigger flip-flop, disabling A/D strobes.
- * The timer/counter register is loaded with the division
- * ratio which will give the required sample rate.
- *
- * Loading the first chanspec sets the trigger flip-flop,
- * enabling the timer/counter. A/D strobes are then generated
- * at the rate set by the internal clock/divider.
- */
- mode = DT2811_ADCSR_ADMODE(1);
- } else { /* TRIG_EXT */
- if (cmd->convert_src == TRIG_TIMER) {
- /*
- * Mode 2
- * Continuous conversion, external trigger
- *
- * Similar to Mode 1, with the exception that the
- * trigger flip-flop must be set by a negative edge
- * on the external trigger input.
- */
- mode = DT2811_ADCSR_ADMODE(2);
- } else { /* TRIG_EXT */
- /*
- * Mode 3
- * Continuous conversion, external trigger, clock
- *
- * Similar to Mode 2, with the exception that the
- * conversion rate is set by the frequency on the
- * external clock/divider.
- */
- mode = DT2811_ADCSR_ADMODE(3);
- }
- }
- outb(mode | DT2811_ADCSR_INTENB, dev->iobase + DT2811_ADCSR_REG);
-
- /* load timer */
- outb(devpriv->ai_divisor, dev->iobase + DT2811_TMRCTR_REG);
-
- /* load chanspec - enables timer */
- dt2811_ai_set_chanspec(dev, cmd->chanlist[0]);
-
- return 0;
-}
-
-static unsigned int dt2811_ns_to_timer(unsigned int *nanosec,
- unsigned int flags)
-{
- unsigned long long ns;
- unsigned int ns_lo = COMEDI_MIN_SPEED;
- unsigned int ns_hi = 0;
- unsigned int divisor_hi = 0;
- unsigned int divisor_lo = 0;
- unsigned int _div;
- unsigned int _mult;
-
- /*
- * Work through all the divider/multiplier values to find the two
- * closest divisors to generate the requested nanosecond timing.
- */
- for (_div = 0; _div <= 7; _div++) {
- for (_mult = 0; _mult <= 7; _mult++) {
- unsigned int div = dt2811_clk_dividers[_div];
- unsigned int mult = dt2811_clk_multipliers[_mult];
- unsigned long long divider = div * mult;
- unsigned int divisor = DT2811_TMRCTR_MANTISSA(_div) |
- DT2811_TMRCTR_EXPONENT(_mult);
-
- /*
- * The timer can be configured to run at a slowest
- * speed of 0.005hz (600 Khz/120000000), which requires
- * 37-bits to represent the nanosecond value. Limit the
- * slowest timing to what comedi handles (32-bits).
- */
- ns = divider * DT2811_OSC_BASE;
- if (ns > COMEDI_MIN_SPEED)
- continue;
-
- /* Check for fastest found timing */
- if (ns <= *nanosec && ns > ns_hi) {
- ns_hi = ns;
- divisor_hi = divisor;
- }
- /* Check for slowest found timing */
- if (ns >= *nanosec && ns < ns_lo) {
- ns_lo = ns;
- divisor_lo = divisor;
- }
- }
- }
-
- /*
- * The slowest found timing will be invalid if the requested timing
- * is faster than what can be generated by the timer. Fix it so that
- * CMDF_ROUND_UP returns valid timing.
- */
- if (ns_lo == COMEDI_MIN_SPEED) {
- ns_lo = ns_hi;
- divisor_lo = divisor_hi;
- }
- /*
- * The fastest found timing will be invalid if the requested timing
- * is less than what can be generated by the timer. Fix it so that
- * CMDF_ROUND_NEAREST and CMDF_ROUND_DOWN return valid timing.
- */
- if (ns_hi == 0) {
- ns_hi = ns_lo;
- divisor_hi = divisor_lo;
- }
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- if (ns_hi - *nanosec < *nanosec - ns_lo) {
- *nanosec = ns_lo;
- return divisor_lo;
- }
- *nanosec = ns_hi;
- return divisor_hi;
- case CMDF_ROUND_UP:
- *nanosec = ns_lo;
- return divisor_lo;
- case CMDF_ROUND_DOWN:
- *nanosec = ns_hi;
- return divisor_hi;
- }
-}
-
-static int dt2811_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct dt2811_private *devpriv = dev->private;
- unsigned int arg;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->convert_src == TRIG_EXT && cmd->start_src != TRIG_EXT)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- if (cmd->convert_src == TRIG_TIMER)
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 12500);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- devpriv->ai_divisor = dt2811_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- } else { /* TRIG_EXT */
- /* The convert_arg is used to set the divisor. */
- devpriv->ai_divisor = cmd->convert_arg;
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int dt2811_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DT2811_ADCSR_REG);
- if ((status & DT2811_ADCSR_ADBUSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int dt2811_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- int i;
-
- /* We will already be in Mode 0 */
- for (i = 0; i < insn->n; i++) {
- /* load chanspec and trigger conversion */
- dt2811_ai_set_chanspec(dev, insn->chanspec);
-
- ret = comedi_timeout(dev, s, insn, dt2811_ai_eoc, 0);
- if (ret)
- return ret;
-
- data[i] = dt2811_ai_read_sample(dev, s);
- }
-
- return insn->n;
-}
-
-static int dt2811_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outb(val & 0xff, dev->iobase + DT2811_DADATA_LO_REG(chan));
- outb((val >> 8) & 0xff,
- dev->iobase + DT2811_DADATA_HI_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int dt2811_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + DT2811_DI_REG);
-
- return insn->n;
-}
-
-static int dt2811_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DT2811_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void dt2811_reset(struct comedi_device *dev)
-{
- /* This is the initialization sequence from the users manual */
- outb(DT2811_ADCSR_ADMODE(0), dev->iobase + DT2811_ADCSR_REG);
- usleep_range(100, 1000);
- inb(dev->iobase + DT2811_ADDATA_LO_REG);
- inb(dev->iobase + DT2811_ADDATA_HI_REG);
- outb(DT2811_ADCSR_ADMODE(0) | DT2811_ADCSR_CLRERROR,
- dev->iobase + DT2811_ADCSR_REG);
-}
-
-static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct dt2811_board *board = dev->board_ptr;
- struct dt2811_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x8);
- if (ret)
- return ret;
-
- dt2811_reset(dev);
-
- /* IRQ's 2,3,5,7 are valid for async command support */
- if (it->options[1] <= 7 && (BIT(it->options[1]) & 0xac)) {
- ret = request_irq(it->options[1], dt2811_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE |
- ((it->options[2] == 1) ? SDF_DIFF :
- (it->options[2] == 2) ? SDF_COMMON : SDF_GROUND);
- s->n_chan = (it->options[2] == 1) ? 8 : 16;
- s->maxdata = 0x0fff;
- s->range_table = board->is_pgh ? &dt2811_pgh_ai_ranges
- : &dt2811_pgl_ai_ranges;
- s->insn_read = dt2811_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 1;
- s->do_cmdtest = dt2811_ai_cmdtest;
- s->do_cmd = dt2811_ai_cmd;
- s->cancel = dt2811_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &dt2811_ao_ranges;
- s->insn_write = dt2811_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dt2811_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dt2811_do_insn_bits;
-
- return 0;
-}
-
-static struct comedi_driver dt2811_driver = {
- .driver_name = "dt2811",
- .module = THIS_MODULE,
- .attach = dt2811_attach,
- .detach = comedi_legacy_detach,
- .board_name = &dt2811_boards[0].name,
- .num_names = ARRAY_SIZE(dt2811_boards),
- .offset = sizeof(struct dt2811_board),
-};
-module_comedi_driver(dt2811_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Data Translation DT2811 series boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
deleted file mode 100644
index ed44ce0d151b..000000000000
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ /dev/null
@@ -1,372 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/dt2814.c
- * Hardware driver for Data Translation DT2814
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-/*
- * Driver: dt2814
- * Description: Data Translation DT2814
- * Author: ds
- * Status: complete
- * Devices: [Data Translation] DT2814 (dt2814)
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ
- *
- * This card has 16 analog inputs multiplexed onto a 12 bit ADC. There
- * is a minimally useful onboard clock. The base frequency for the
- * clock is selected by jumpers, and the clock divider can be selected
- * via programmed I/O. Unfortunately, the clock divider can only be
- * a power of 10, from 1 to 10^7, of which only 3 or 4 are useful. In
- * addition, the clock does not seem to be very accurate.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include "../comedidev.h"
-
-#include <linux/delay.h>
-
-#define DT2814_CSR 0
-#define DT2814_DATA 1
-
-/*
- * flags
- */
-
-#define DT2814_FINISH 0x80
-#define DT2814_ERR 0x40
-#define DT2814_BUSY 0x20
-#define DT2814_ENB 0x10
-#define DT2814_CHANMASK 0x0f
-
-#define DT2814_TIMEOUT 10
-#define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */
-
-static int dt2814_ai_notbusy(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DT2814_CSR);
- if (context)
- *(unsigned int *)context = status;
- if (status & DT2814_BUSY)
- return -EBUSY;
- return 0;
-}
-
-static int dt2814_ai_clear(struct comedi_device *dev)
-{
- unsigned int status = 0;
- int ret;
-
- /* Wait until not busy and get status register value. */
- ret = comedi_timeout(dev, NULL, NULL, dt2814_ai_notbusy,
- (unsigned long)&status);
- if (ret)
- return ret;
-
- if (status & (DT2814_FINISH | DT2814_ERR)) {
- /*
- * There unread data, or the error flag is set.
- * Read the data register twice to clear the condition.
- */
- inb(dev->iobase + DT2814_DATA);
- inb(dev->iobase + DT2814_DATA);
- }
- return 0;
-}
-
-static int dt2814_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DT2814_CSR);
- if (status & DT2814_FINISH)
- return 0;
- return -EBUSY;
-}
-
-static int dt2814_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int n, hi, lo;
- int chan;
- int ret;
-
- dt2814_ai_clear(dev); /* clear stale data or error */
- for (n = 0; n < insn->n; n++) {
- chan = CR_CHAN(insn->chanspec);
-
- outb(chan, dev->iobase + DT2814_CSR);
-
- ret = comedi_timeout(dev, s, insn, dt2814_ai_eoc, 0);
- if (ret)
- return ret;
-
- hi = inb(dev->iobase + DT2814_DATA);
- lo = inb(dev->iobase + DT2814_DATA);
-
- data[n] = (hi << 4) | (lo >> 4);
- }
-
- return n;
-}
-
-static int dt2814_ns_to_timer(unsigned int *ns, unsigned int flags)
-{
- int i;
- unsigned int f;
-
- /* XXX ignores flags */
-
- f = 10000; /* ns */
- for (i = 0; i < 8; i++) {
- if ((2 * (*ns)) < (f * 11))
- break;
- f *= 10;
- }
-
- *ns = f;
-
- return i;
-}
-
-static int dt2814_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 1000000000);
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- DT2814_MAX_SPEED);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 2);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- arg = cmd->scan_begin_arg;
- dt2814_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- int chan;
- int trigvar;
-
- dt2814_ai_clear(dev); /* clear stale data or error */
- trigvar = dt2814_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
-
- chan = CR_CHAN(cmd->chanlist[0]);
-
- outb(chan | DT2814_ENB | (trigvar << 5), dev->iobase + DT2814_CSR);
-
- return 0;
-}
-
-static int dt2814_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int status;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- status = inb(dev->iobase + DT2814_CSR);
- if (status & DT2814_ENB) {
- /*
- * Clear the timed trigger enable bit.
- *
- * Note: turning off timed mode triggers another
- * sample. This will be mopped up by the calls to
- * dt2814_ai_clear().
- */
- outb(status & DT2814_CHANMASK, dev->iobase + DT2814_CSR);
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return 0;
-}
-
-static irqreturn_t dt2814_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async;
- unsigned int lo, hi;
- unsigned short data;
- unsigned int status;
-
- if (!dev->attached) {
- dev_err(dev->class_dev, "spurious interrupt\n");
- return IRQ_HANDLED;
- }
-
- async = s->async;
-
- spin_lock(&dev->spinlock);
-
- status = inb(dev->iobase + DT2814_CSR);
- if (!(status & DT2814_ENB)) {
- /* Timed acquisition not enabled. Nothing to do. */
- spin_unlock(&dev->spinlock);
- return IRQ_HANDLED;
- }
-
- if (!(status & (DT2814_FINISH | DT2814_ERR))) {
- /* Spurious interrupt? */
- spin_unlock(&dev->spinlock);
- return IRQ_HANDLED;
- }
-
- /* Read data or clear error. */
- hi = inb(dev->iobase + DT2814_DATA);
- lo = inb(dev->iobase + DT2814_DATA);
-
- data = (hi << 4) | (lo >> 4);
-
- if (status & DT2814_ERR) {
- async->events |= COMEDI_CB_ERROR;
- } else {
- comedi_buf_write_samples(s, &data, 1);
- if (async->cmd.stop_src == TRIG_COUNT &&
- async->scans_done >= async->cmd.stop_arg) {
- async->events |= COMEDI_CB_EOA;
- }
- }
- if (async->events & COMEDI_CB_CANCEL_MASK) {
- /*
- * Disable timed mode.
- *
- * Note: turning off timed mode triggers another
- * sample. This will be mopped up by the calls to
- * dt2814_ai_clear().
- */
- outb(status & DT2814_CHANMASK, dev->iobase + DT2814_CSR);
- }
-
- spin_unlock(&dev->spinlock);
-
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x2);
- if (ret)
- return ret;
-
- outb(0, dev->iobase + DT2814_CSR);
- if (dt2814_ai_clear(dev)) {
- dev_err(dev->class_dev, "reset error (fatal)\n");
- return -EIO;
- }
-
- if (it->options[1]) {
- ret = request_irq(it->options[1], dt2814_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 16; /* XXX */
- s->insn_read = dt2814_ai_insn_read;
- s->maxdata = 0xfff;
- s->range_table = &range_unknown; /* XXX */
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 1;
- s->do_cmd = dt2814_ai_cmd;
- s->do_cmdtest = dt2814_ai_cmdtest;
- s->cancel = dt2814_ai_cancel;
- }
-
- return 0;
-}
-
-static void dt2814_detach(struct comedi_device *dev)
-{
- if (dev->irq) {
- /*
- * An extra conversion triggered on termination of an
- * asynchronous command may still be in progress. Wait for
- * it to finish and clear the data or error status.
- */
- dt2814_ai_clear(dev);
- }
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver dt2814_driver = {
- .driver_name = "dt2814",
- .module = THIS_MODULE,
- .attach = dt2814_attach,
- .detach = dt2814_detach,
-};
-module_comedi_driver(dt2814_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
deleted file mode 100644
index 5906f32aa01f..000000000000
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ /dev/null
@@ -1,217 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/dt2815.c
- * Hardware driver for Data Translation DT2815
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
- */
-/*
- * Driver: dt2815
- * Description: Data Translation DT2815
- * Author: ds
- * Status: mostly complete, untested
- * Devices: [Data Translation] DT2815 (dt2815)
- *
- * I'm not sure anyone has ever tested this board. If you have information
- * contrary, please update.
- *
- * Configuration options:
- * [0] - I/O port base base address
- * [1] - IRQ (unused)
- * [2] - Voltage unipolar/bipolar configuration
- * 0 == unipolar 5V (0V -- +5V)
- * 1 == bipolar 5V (-5V -- +5V)
- * [3] - Current offset configuration
- * 0 == disabled (0mA -- +32mAV)
- * 1 == enabled (+4mA -- +20mAV)
- * [4] - Firmware program configuration
- * 0 == program 1 (see manual table 5-4)
- * 1 == program 2 (see manual table 5-4)
- * 2 == program 3 (see manual table 5-4)
- * 3 == program 4 (see manual table 5-4)
- * [5] - Analog output 0 range configuration
- * 0 == voltage
- * 1 == current
- * [6] - Analog output 1 range configuration (same options)
- * [7] - Analog output 2 range configuration (same options)
- * [8] - Analog output 3 range configuration (same options)
- * [9] - Analog output 4 range configuration (same options)
- * [10] - Analog output 5 range configuration (same options)
- * [11] - Analog output 6 range configuration (same options)
- * [12] - Analog output 7 range configuration (same options)
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include <linux/delay.h>
-
-#define DT2815_DATA 0
-#define DT2815_STATUS 1
-
-struct dt2815_private {
- const struct comedi_lrange *range_type_list[8];
- unsigned int ao_readback[8];
-};
-
-static int dt2815_ao_status(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DT2815_STATUS);
- if (status == context)
- return 0;
- return -EBUSY;
-}
-
-static int dt2815_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct dt2815_private *devpriv = dev->private;
- int i;
- int chan = CR_CHAN(insn->chanspec);
-
- for (i = 0; i < insn->n; i++)
- data[i] = devpriv->ao_readback[chan];
-
- return i;
-}
-
-static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct dt2815_private *devpriv = dev->private;
- int i;
- int chan = CR_CHAN(insn->chanspec);
- unsigned int lo, hi;
- int ret;
-
- for (i = 0; i < insn->n; i++) {
- /* FIXME: lo bit 0 chooses voltage output or current output */
- lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01;
- hi = (data[i] & 0xff0) >> 4;
-
- ret = comedi_timeout(dev, s, insn, dt2815_ao_status, 0x00);
- if (ret)
- return ret;
-
- outb(lo, dev->iobase + DT2815_DATA);
-
- ret = comedi_timeout(dev, s, insn, dt2815_ao_status, 0x10);
- if (ret)
- return ret;
-
- outb(hi, dev->iobase + DT2815_DATA);
-
- devpriv->ao_readback[chan] = data[i];
- }
- return i;
-}
-
-/*
- * options[0] Board base address
- * options[1] IRQ (not applicable)
- * options[2] Voltage unipolar/bipolar configuration
- * 0 == unipolar 5V (0V -- +5V)
- * 1 == bipolar 5V (-5V -- +5V)
- * options[3] Current offset configuration
- * 0 == disabled (0mA -- +32mAV)
- * 1 == enabled (+4mA -- +20mAV)
- * options[4] Firmware program configuration
- * 0 == program 1 (see manual table 5-4)
- * 1 == program 2 (see manual table 5-4)
- * 2 == program 3 (see manual table 5-4)
- * 3 == program 4 (see manual table 5-4)
- * options[5] Analog output 0 range configuration
- * 0 == voltage
- * 1 == current
- * options[6] Analog output 1 range configuration
- * ...
- * options[12] Analog output 7 range configuration
- * 0 == voltage
- * 1 == current
- */
-
-static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct dt2815_private *devpriv;
- struct comedi_subdevice *s;
- int i;
- const struct comedi_lrange *current_range_type, *voltage_range_type;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x2);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- s = &dev->subdevices[0];
- /* ao subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->maxdata = 0xfff;
- s->n_chan = 8;
- s->insn_write = dt2815_ao_insn;
- s->insn_read = dt2815_ao_insn_read;
- s->range_table_list = devpriv->range_type_list;
-
- current_range_type = (it->options[3])
- ? &range_4_20mA : &range_0_32mA;
- voltage_range_type = (it->options[2])
- ? &range_bipolar5 : &range_unipolar5;
- for (i = 0; i < 8; i++) {
- devpriv->range_type_list[i] = (it->options[5 + i])
- ? current_range_type : voltage_range_type;
- }
-
- /* Init the 2815 */
- outb(0x00, dev->iobase + DT2815_STATUS);
- for (i = 0; i < 100; i++) {
- /* This is incredibly slow (approx 20 ms) */
- unsigned int status;
-
- usleep_range(1000, 3000);
- status = inb(dev->iobase + DT2815_STATUS);
- if (status == 4) {
- unsigned int program;
-
- program = (it->options[4] & 0x3) << 3 | 0x7;
- outb(program, dev->iobase + DT2815_DATA);
- dev_dbg(dev->class_dev, "program: 0x%x (@t=%d)\n",
- program, i);
- break;
- } else if (status != 0x00) {
- dev_dbg(dev->class_dev,
- "unexpected status 0x%x (@t=%d)\n",
- status, i);
- if (status & 0x60)
- outb(0x00, dev->iobase + DT2815_STATUS);
- }
- }
-
- return 0;
-}
-
-static struct comedi_driver dt2815_driver = {
- .driver_name = "dt2815",
- .module = THIS_MODULE,
- .attach = dt2815_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(dt2815_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
deleted file mode 100644
index 7c1463e835d3..000000000000
--- a/drivers/staging/comedi/drivers/dt2817.c
+++ /dev/null
@@ -1,140 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/dt2817.c
- * Hardware driver for Data Translation DT2817
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-/*
- * Driver: dt2817
- * Description: Data Translation DT2817
- * Author: ds
- * Status: complete
- * Devices: [Data Translation] DT2817 (dt2817)
- *
- * A very simple digital I/O card. Four banks of 8 lines, each bank
- * is configurable for input or output. One wonders why it takes a
- * 50 page manual to describe this thing.
- *
- * The driver (which, btw, is much less than 50 pages) has 1 subdevice
- * with 32 channels, configurable in groups of 8.
- *
- * Configuration options:
- * [0] - I/O port base base address
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#define DT2817_CR 0
-#define DT2817_DATA 1
-
-static int dt2817_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int oe = 0;
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x000000ff;
- else if (chan < 16)
- mask = 0x0000ff00;
- else if (chan < 24)
- mask = 0x00ff0000;
- else
- mask = 0xff000000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- if (s->io_bits & 0x000000ff)
- oe |= 0x1;
- if (s->io_bits & 0x0000ff00)
- oe |= 0x2;
- if (s->io_bits & 0x00ff0000)
- oe |= 0x4;
- if (s->io_bits & 0xff000000)
- oe |= 0x8;
-
- outb(oe, dev->iobase + DT2817_CR);
-
- return insn->n;
-}
-
-static int dt2817_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long iobase = dev->iobase + DT2817_DATA;
- unsigned int mask;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0x000000ff)
- outb(s->state & 0xff, iobase + 0);
- if (mask & 0x0000ff00)
- outb((s->state >> 8) & 0xff, iobase + 1);
- if (mask & 0x00ff0000)
- outb((s->state >> 16) & 0xff, iobase + 2);
- if (mask & 0xff000000)
- outb((s->state >> 24) & 0xff, iobase + 3);
- }
-
- val = inb(iobase + 0);
- val |= (inb(iobase + 1) << 8);
- val |= (inb(iobase + 2) << 16);
- val |= (inb(iobase + 3) << 24);
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- int ret;
- struct comedi_subdevice *s;
-
- ret = comedi_request_region(dev, it->options[0], 0x5);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
-
- s->n_chan = 32;
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = dt2817_dio_insn_bits;
- s->insn_config = dt2817_dio_insn_config;
-
- s->state = 0;
- outb(0, dev->iobase + DT2817_CR);
-
- return 0;
-}
-
-static struct comedi_driver dt2817_driver = {
- .driver_name = "dt2817",
- .module = THIS_MODULE,
- .attach = dt2817_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(dt2817_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
deleted file mode 100644
index 2656b4b0e3d0..000000000000
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ /dev/null
@@ -1,1172 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * dt282x.c
- * Comedi driver for Data Translation DT2821 series
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: dt282x
- * Description: Data Translation DT2821 series (including DT-EZ)
- * Author: ds
- * Devices: [Data Translation] DT2821 (dt2821), DT2821-F-16SE (dt2821-f),
- * DT2821-F-8DI (dt2821-f), DT2821-G-16SE (dt2821-g),
- * DT2821-G-8DI (dt2821-g), DT2823 (dt2823), DT2824-PGH (dt2824-pgh),
- * DT2824-PGL (dt2824-pgl), DT2825 (dt2825), DT2827 (dt2827),
- * DT2828 (dt2828), DT2928 (dt2829), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
- * DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
- * Status: complete
- * Updated: Wed, 22 Aug 2001 17:11:34 -0700
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (optional, required for async command support)
- * [2] - DMA 1 (optional, required for async command support)
- * [3] - DMA 2 (optional, required for async command support)
- * [4] - AI jumpered for 0=single ended, 1=differential
- * [5] - AI jumpered for 0=straight binary, 1=2's complement
- * [6] - AO 0 data format (deprecated, see below)
- * [7] - AO 1 data format (deprecated, see below)
- * [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
- * [9] - AO channel 0 range (deprecated, see below)
- * [10]- AO channel 1 range (deprecated, see below)
- *
- * Notes:
- * - AO commands might be broken.
- * - If you try to run a command on both the AI and AO subdevices
- * simultaneously, bad things will happen. The driver needs to
- * be fixed to check for this situation and return an error.
- * - AO range is not programmable. The AO subdevice has a range_table
- * containing all the possible analog output ranges. Use the range
- * that matches your board configuration to convert between data
- * values and physical units. The format of the data written to the
- * board is handled automatically based on the unipolar/bipolar
- * range that is selected.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-
-/*
- * Register map
- */
-#define DT2821_ADCSR_REG 0x00
-#define DT2821_ADCSR_ADERR BIT(15)
-#define DT2821_ADCSR_ADCLK BIT(9)
-#define DT2821_ADCSR_MUXBUSY BIT(8)
-#define DT2821_ADCSR_ADDONE BIT(7)
-#define DT2821_ADCSR_IADDONE BIT(6)
-#define DT2821_ADCSR_GS(x) (((x) & 0x3) << 4)
-#define DT2821_ADCSR_CHAN(x) (((x) & 0xf) << 0)
-#define DT2821_CHANCSR_REG 0x02
-#define DT2821_CHANCSR_LLE BIT(15)
-#define DT2821_CHANCSR_TO_PRESLA(x) (((x) >> 8) & 0xf)
-#define DT2821_CHANCSR_NUMB(x) ((((x) - 1) & 0xf) << 0)
-#define DT2821_ADDAT_REG 0x04
-#define DT2821_DACSR_REG 0x06
-#define DT2821_DACSR_DAERR BIT(15)
-#define DT2821_DACSR_YSEL(x) ((x) << 9)
-#define DT2821_DACSR_SSEL BIT(8)
-#define DT2821_DACSR_DACRDY BIT(7)
-#define DT2821_DACSR_IDARDY BIT(6)
-#define DT2821_DACSR_DACLK BIT(5)
-#define DT2821_DACSR_HBOE BIT(1)
-#define DT2821_DACSR_LBOE BIT(0)
-#define DT2821_DADAT_REG 0x08
-#define DT2821_DIODAT_REG 0x0a
-#define DT2821_SUPCSR_REG 0x0c
-#define DT2821_SUPCSR_DMAD BIT(15)
-#define DT2821_SUPCSR_ERRINTEN BIT(14)
-#define DT2821_SUPCSR_CLRDMADNE BIT(13)
-#define DT2821_SUPCSR_DDMA BIT(12)
-#define DT2821_SUPCSR_DS(x) (((x) & 0x3) << 10)
-#define DT2821_SUPCSR_DS_PIO DT2821_SUPCSR_DS(0)
-#define DT2821_SUPCSR_DS_AD_CLK DT2821_SUPCSR_DS(1)
-#define DT2821_SUPCSR_DS_DA_CLK DT2821_SUPCSR_DS(2)
-#define DT2821_SUPCSR_DS_AD_TRIG DT2821_SUPCSR_DS(3)
-#define DT2821_SUPCSR_BUFFB BIT(9)
-#define DT2821_SUPCSR_SCDN BIT(8)
-#define DT2821_SUPCSR_DACON BIT(7)
-#define DT2821_SUPCSR_ADCINIT BIT(6)
-#define DT2821_SUPCSR_DACINIT BIT(5)
-#define DT2821_SUPCSR_PRLD BIT(4)
-#define DT2821_SUPCSR_STRIG BIT(3)
-#define DT2821_SUPCSR_XTRIG BIT(2)
-#define DT2821_SUPCSR_XCLK BIT(1)
-#define DT2821_SUPCSR_BDINIT BIT(0)
-#define DT2821_TMRCTR_REG 0x0e
-#define DT2821_TMRCTR_PRESCALE(x) (((x) & 0xf) << 8)
-#define DT2821_TMRCTR_DIVIDER(x) ((255 - ((x) & 0xff)) << 0)
-
-/* Pacer Clock */
-#define DT2821_OSC_BASE 250 /* 4 MHz (in nanoseconds) */
-#define DT2821_PRESCALE(x) BIT(x)
-#define DT2821_PRESCALE_MAX 15
-#define DT2821_DIVIDER_MAX 255
-#define DT2821_OSC_MAX (DT2821_OSC_BASE * \
- DT2821_PRESCALE(DT2821_PRESCALE_MAX) * \
- DT2821_DIVIDER_MAX)
-
-static const struct comedi_lrange range_dt282x_ai_lo_bipolar = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_dt282x_ai_lo_unipolar = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_dt282x_ai_5_bipolar = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range_dt282x_ai_5_unipolar = {
- 4, {
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- UNI_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range_dt282x_ai_hi_bipolar = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.02)
- }
-};
-
-static const struct comedi_lrange range_dt282x_ai_hi_unipolar = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.02)
- }
-};
-
-/*
- * The Analog Output range is set per-channel using jumpers on the board.
- * All of these ranges may not be available on some DT2821 series boards.
- * The default jumper setting has both channels set for +/-10V output.
- */
-static const struct comedi_lrange dt282x_ao_range = {
- 5, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- UNI_RANGE(10),
- UNI_RANGE(5),
- }
-};
-
-struct dt282x_board {
- const char *name;
- unsigned int ai_maxdata;
- int adchan_se;
- int adchan_di;
- int ai_speed;
- int ispgl;
- int dachan;
- unsigned int ao_maxdata;
-};
-
-static const struct dt282x_board boardtypes[] = {
- {
- .name = "dt2821",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .dachan = 2,
- .ao_maxdata = 0x0fff,
- }, {
- .name = "dt2821-f",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 6500,
- .dachan = 2,
- .ao_maxdata = 0x0fff,
- }, {
- .name = "dt2821-g",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 4000,
- .dachan = 2,
- .ao_maxdata = 0x0fff,
- }, {
- .name = "dt2823",
- .ai_maxdata = 0xffff,
- .adchan_di = 4,
- .ai_speed = 10000,
- .dachan = 2,
- .ao_maxdata = 0xffff,
- }, {
- .name = "dt2824-pgh",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- }, {
- .name = "dt2824-pgl",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 1,
- }, {
- .name = "dt2825",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 1,
- .dachan = 2,
- .ao_maxdata = 0x0fff,
- }, {
- .name = "dt2827",
- .ai_maxdata = 0xffff,
- .adchan_di = 4,
- .ai_speed = 10000,
- .dachan = 2,
- .ao_maxdata = 0x0fff,
- }, {
- .name = "dt2828",
- .ai_maxdata = 0x0fff,
- .adchan_se = 4,
- .ai_speed = 10000,
- .dachan = 2,
- .ao_maxdata = 0x0fff,
- }, {
- .name = "dt2829",
- .ai_maxdata = 0xffff,
- .adchan_se = 8,
- .ai_speed = 33250,
- .dachan = 2,
- .ao_maxdata = 0xffff,
- }, {
- .name = "dt21-ez",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .dachan = 2,
- .ao_maxdata = 0x0fff,
- }, {
- .name = "dt23-ez",
- .ai_maxdata = 0xffff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- }, {
- .name = "dt24-ez",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- }, {
- .name = "dt24-ez-pgl",
- .ai_maxdata = 0x0fff,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 1,
- },
-};
-
-struct dt282x_private {
- struct comedi_isadma *dma;
- unsigned int ad_2scomp:1;
- unsigned int divisor;
- int dacsr; /* software copies of registers */
- int adcsr;
- int supcsr;
- int ntrig;
- int nread;
- int dma_dir;
-};
-
-static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma_index];
-
- if (!devpriv->ntrig)
- return 0;
-
- if (n == 0)
- n = desc->maxsize;
- if (n > devpriv->ntrig * 2)
- n = devpriv->ntrig * 2;
- devpriv->ntrig -= n / 2;
-
- desc->size = n;
- comedi_isadma_set_mode(desc, devpriv->dma_dir);
-
- comedi_isadma_program(desc);
-
- return n;
-}
-
-static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma_index];
-
- desc->size = n;
- comedi_isadma_set_mode(desc, devpriv->dma_dir);
-
- comedi_isadma_program(desc);
-
- return n;
-}
-
-static void dt282x_disable_dma(struct comedi_device *dev)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc;
- int i;
-
- for (i = 0; i < 2; i++) {
- desc = &dma->desc[i];
- comedi_isadma_disable(desc->chan);
- }
-}
-
-static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags)
-{
- unsigned int prescale, base, divider;
-
- for (prescale = 0; prescale <= DT2821_PRESCALE_MAX; prescale++) {
- if (prescale == 1) /* 0 and 1 are both divide by 1 */
- continue;
- base = DT2821_OSC_BASE * DT2821_PRESCALE(prescale);
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- divider = DIV_ROUND_CLOSEST(*ns, base);
- break;
- case CMDF_ROUND_DOWN:
- divider = (*ns) / base;
- break;
- case CMDF_ROUND_UP:
- divider = DIV_ROUND_UP(*ns, base);
- break;
- }
- if (divider <= DT2821_DIVIDER_MAX)
- break;
- }
- if (divider > DT2821_DIVIDER_MAX) {
- prescale = DT2821_PRESCALE_MAX;
- divider = DT2821_DIVIDER_MAX;
- base = DT2821_OSC_BASE * DT2821_PRESCALE(prescale);
- }
- *ns = divider * base;
- return DT2821_TMRCTR_PRESCALE(prescale) |
- DT2821_TMRCTR_DIVIDER(divider);
-}
-
-static void dt282x_munge(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned short *buf,
- unsigned int nbytes)
-{
- struct dt282x_private *devpriv = dev->private;
- unsigned int val;
- int i;
-
- if (nbytes % 2)
- dev_err(dev->class_dev,
- "bug! odd number of bytes from dma xfer\n");
-
- for (i = 0; i < nbytes / 2; i++) {
- val = buf[i];
- val &= s->maxdata;
- if (devpriv->ad_2scomp)
- val = comedi_offset_munge(s, val);
-
- buf[i] = val;
- }
-}
-
-static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s,
- int cur_dma)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[cur_dma];
- unsigned int nsamples = comedi_bytes_to_samples(s, desc->maxsize);
- unsigned int nbytes;
-
- nbytes = comedi_buf_read_samples(s, desc->virt_addr, nsamples);
- if (nbytes)
- dt282x_prep_ao_dma(dev, cur_dma, nbytes);
- else
- dev_err(dev->class_dev, "AO underrun\n");
-
- return nbytes;
-}
-
-static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
-
- outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
- dev->iobase + DT2821_SUPCSR_REG);
-
- comedi_isadma_disable(desc->chan);
-
- if (!dt282x_ao_setup_dma(dev, s, dma->cur_dma))
- s->async->events |= COMEDI_CB_OVERFLOW;
-
- dma->cur_dma = 1 - dma->cur_dma;
-}
-
-static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned int nsamples = comedi_bytes_to_samples(s, desc->size);
- int ret;
-
- outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
- dev->iobase + DT2821_SUPCSR_REG);
-
- comedi_isadma_disable(desc->chan);
-
- dt282x_munge(dev, s, desc->virt_addr, desc->size);
- ret = comedi_buf_write_samples(s, desc->virt_addr, nsamples);
- if (ret != desc->size)
- return;
-
- devpriv->nread -= nsamples;
- if (devpriv->nread < 0) {
- dev_info(dev->class_dev, "nread off by one\n");
- devpriv->nread = 0;
- }
- if (!devpriv->nread) {
- s->async->events |= COMEDI_CB_EOA;
- return;
- }
-
- /* restart the channel */
- dt282x_prep_ai_dma(dev, dma->cur_dma, 0);
-
- dma->cur_dma = 1 - dma->cur_dma;
-}
-
-static irqreturn_t dt282x_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct dt282x_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_subdevice *s_ao = dev->write_subdev;
- unsigned int supcsr, adcsr, dacsr;
- int handled = 0;
-
- if (!dev->attached) {
- dev_err(dev->class_dev, "spurious interrupt\n");
- return IRQ_HANDLED;
- }
-
- adcsr = inw(dev->iobase + DT2821_ADCSR_REG);
- dacsr = inw(dev->iobase + DT2821_DACSR_REG);
- supcsr = inw(dev->iobase + DT2821_SUPCSR_REG);
- if (supcsr & DT2821_SUPCSR_DMAD) {
- if (devpriv->dma_dir == COMEDI_ISADMA_READ)
- dt282x_ai_dma_interrupt(dev, s);
- else
- dt282x_ao_dma_interrupt(dev, s_ao);
- handled = 1;
- }
- if (adcsr & DT2821_ADCSR_ADERR) {
- if (devpriv->nread != 0) {
- dev_err(dev->class_dev, "A/D error\n");
- s->async->events |= COMEDI_CB_ERROR;
- }
- handled = 1;
- }
- if (dacsr & DT2821_DACSR_DAERR) {
- dev_err(dev->class_dev, "D/A error\n");
- s_ao->async->events |= COMEDI_CB_ERROR;
- handled = 1;
- }
-
- comedi_handle_events(dev, s);
- if (s_ao)
- comedi_handle_events(dev, s_ao);
-
- return IRQ_RETVAL(handled);
-}
-
-static void dt282x_load_changain(struct comedi_device *dev, int n,
- unsigned int *chanlist)
-{
- struct dt282x_private *devpriv = dev->private;
- int i;
-
- outw(DT2821_CHANCSR_LLE | DT2821_CHANCSR_NUMB(n),
- dev->iobase + DT2821_CHANCSR_REG);
- for (i = 0; i < n; i++) {
- unsigned int chan = CR_CHAN(chanlist[i]);
- unsigned int range = CR_RANGE(chanlist[i]);
-
- outw(devpriv->adcsr |
- DT2821_ADCSR_GS(range) |
- DT2821_ADCSR_CHAN(chan),
- dev->iobase + DT2821_ADCSR_REG);
- }
- outw(DT2821_CHANCSR_NUMB(n), dev->iobase + DT2821_CHANCSR_REG);
-}
-
-static int dt282x_ai_timeout(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + DT2821_ADCSR_REG);
- switch (context) {
- case DT2821_ADCSR_MUXBUSY:
- if ((status & DT2821_ADCSR_MUXBUSY) == 0)
- return 0;
- break;
- case DT2821_ADCSR_ADDONE:
- if (status & DT2821_ADCSR_ADDONE)
- return 0;
- break;
- default:
- return -EINVAL;
- }
- return -EBUSY;
-}
-
-/*
- * Performs a single A/D conversion.
- * - Put channel/gain into channel-gain list
- * - preload multiplexer
- * - trigger conversion and wait for it to finish
- */
-static int dt282x_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dt282x_private *devpriv = dev->private;
- unsigned int val;
- int ret;
- int i;
-
- /* XXX should we really be enabling the ad clock here? */
- devpriv->adcsr = DT2821_ADCSR_ADCLK;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
-
- dt282x_load_changain(dev, 1, &insn->chanspec);
-
- outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
- dev->iobase + DT2821_SUPCSR_REG);
- ret = comedi_timeout(dev, s, insn,
- dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
- if (ret)
- return ret;
-
- for (i = 0; i < insn->n; i++) {
- outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
- dev->iobase + DT2821_SUPCSR_REG);
-
- ret = comedi_timeout(dev, s, insn,
- dt282x_ai_timeout, DT2821_ADCSR_ADDONE);
- if (ret)
- return ret;
-
- val = inw(dev->iobase + DT2821_ADDAT_REG);
- val &= s->maxdata;
- if (devpriv->ad_2scomp)
- val = comedi_offset_munge(s, val);
-
- data[i] = val;
- }
-
- return i;
-}
-
-static int dt282x_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct dt282x_board *board = dev->board_ptr;
- struct dt282x_private *devpriv = dev->private;
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_FOLLOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg, DT2821_OSC_MAX);
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, board->ai_speed);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_EXT | TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- arg = cmd->convert_arg;
- devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- dt282x_disable_dma(dev);
-
- outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
-
- devpriv->supcsr = DT2821_SUPCSR_ERRINTEN;
- if (cmd->scan_begin_src == TRIG_FOLLOW)
- devpriv->supcsr = DT2821_SUPCSR_DS_AD_CLK;
- else
- devpriv->supcsr = DT2821_SUPCSR_DS_AD_TRIG;
- outw(devpriv->supcsr |
- DT2821_SUPCSR_CLRDMADNE |
- DT2821_SUPCSR_BUFFB |
- DT2821_SUPCSR_ADCINIT,
- dev->iobase + DT2821_SUPCSR_REG);
-
- devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
- devpriv->nread = devpriv->ntrig;
-
- devpriv->dma_dir = COMEDI_ISADMA_READ;
- dma->cur_dma = 0;
- dt282x_prep_ai_dma(dev, 0, 0);
- if (devpriv->ntrig) {
- dt282x_prep_ai_dma(dev, 1, 0);
- devpriv->supcsr |= DT2821_SUPCSR_DDMA;
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
- }
-
- devpriv->adcsr = 0;
-
- dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
-
- devpriv->adcsr = DT2821_ADCSR_ADCLK | DT2821_ADCSR_IADDONE;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
-
- outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
- dev->iobase + DT2821_SUPCSR_REG);
- ret = comedi_timeout(dev, s, NULL,
- dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
- if (ret)
- return ret;
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
- dev->iobase + DT2821_SUPCSR_REG);
- } else {
- devpriv->supcsr |= DT2821_SUPCSR_XTRIG;
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
- }
-
- return 0;
-}
-
-static int dt282x_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dt282x_private *devpriv = dev->private;
-
- dt282x_disable_dma(dev);
-
- devpriv->adcsr = 0;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
-
- devpriv->supcsr = 0;
- outw(devpriv->supcsr | DT2821_SUPCSR_ADCINIT,
- dev->iobase + DT2821_SUPCSR_REG);
-
- return 0;
-}
-
-static int dt282x_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dt282x_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int i;
-
- devpriv->dacsr |= DT2821_DACSR_SSEL | DT2821_DACSR_YSEL(chan);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- if (comedi_range_is_bipolar(s, range))
- val = comedi_offset_munge(s, val);
-
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
-
- outw(val, dev->iobase + DT2821_DADAT_REG);
-
- outw(devpriv->supcsr | DT2821_SUPCSR_DACON,
- dev->iobase + DT2821_SUPCSR_REG);
- }
-
- return insn->n;
-}
-
-static int dt282x_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct dt282x_private *devpriv = dev->private;
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 5000);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_EXT | TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- arg = cmd->scan_begin_arg;
- devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int dt282x_ao_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_src)
- return -EINVAL;
-
- if (!dt282x_ao_setup_dma(dev, s, 0))
- return -EPIPE;
-
- if (!dt282x_ao_setup_dma(dev, s, 1))
- return -EPIPE;
-
- outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
- dev->iobase + DT2821_SUPCSR_REG);
- s->async->inttrig = NULL;
-
- return 1;
-}
-
-static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct dt282x_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- dt282x_disable_dma(dev);
-
- devpriv->supcsr = DT2821_SUPCSR_ERRINTEN |
- DT2821_SUPCSR_DS_DA_CLK |
- DT2821_SUPCSR_DDMA;
- outw(devpriv->supcsr |
- DT2821_SUPCSR_CLRDMADNE |
- DT2821_SUPCSR_BUFFB |
- DT2821_SUPCSR_DACINIT,
- dev->iobase + DT2821_SUPCSR_REG);
-
- devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
- devpriv->nread = devpriv->ntrig;
-
- devpriv->dma_dir = COMEDI_ISADMA_WRITE;
- dma->cur_dma = 0;
-
- outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
-
- /* clear all bits but the DIO direction bits */
- devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
-
- devpriv->dacsr |= (DT2821_DACSR_SSEL |
- DT2821_DACSR_DACLK |
- DT2821_DACSR_IDARDY);
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
-
- s->async->inttrig = dt282x_ao_inttrig;
-
- return 0;
-}
-
-static int dt282x_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dt282x_private *devpriv = dev->private;
-
- dt282x_disable_dma(dev);
-
- /* clear all bits but the DIO direction bits */
- devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
-
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
-
- devpriv->supcsr = 0;
- outw(devpriv->supcsr | DT2821_SUPCSR_DACINIT,
- dev->iobase + DT2821_SUPCSR_REG);
-
- return 0;
-}
-
-static int dt282x_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + DT2821_DIODAT_REG);
-
- data[1] = inw(dev->iobase + DT2821_DIODAT_REG);
-
- return insn->n;
-}
-
-static int dt282x_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dt282x_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x00ff;
- else
- mask = 0xff00;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- devpriv->dacsr &= ~(DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
- if (s->io_bits & 0x00ff)
- devpriv->dacsr |= DT2821_DACSR_LBOE;
- if (s->io_bits & 0xff00)
- devpriv->dacsr |= DT2821_DACSR_HBOE;
-
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
-
- return insn->n;
-}
-
-static const struct comedi_lrange *const ai_range_table[] = {
- &range_dt282x_ai_lo_bipolar,
- &range_dt282x_ai_lo_unipolar,
- &range_dt282x_ai_5_bipolar,
- &range_dt282x_ai_5_unipolar
-};
-
-static const struct comedi_lrange *const ai_range_pgl_table[] = {
- &range_dt282x_ai_hi_bipolar,
- &range_dt282x_ai_hi_unipolar
-};
-
-static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
-{
- if (ispgl) {
- if (x < 0 || x >= 2)
- x = 0;
- return ai_range_pgl_table[x];
- }
-
- if (x < 0 || x >= 4)
- x = 0;
- return ai_range_table[x];
-}
-
-static void dt282x_alloc_dma(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct dt282x_private *devpriv = dev->private;
- unsigned int irq_num = it->options[1];
- unsigned int dma_chan[2];
-
- if (it->options[2] < it->options[3]) {
- dma_chan[0] = it->options[2];
- dma_chan[1] = it->options[3];
- } else {
- dma_chan[0] = it->options[3];
- dma_chan[1] = it->options[2];
- }
-
- if (!irq_num || dma_chan[0] == dma_chan[1] ||
- dma_chan[0] < 5 || dma_chan[0] > 7 ||
- dma_chan[1] < 5 || dma_chan[1] > 7)
- return;
-
- if (request_irq(irq_num, dt282x_interrupt, 0, dev->board_name, dev))
- return;
-
- /* DMA uses two 4K buffers with separate DMA channels */
- devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan[0], dma_chan[1],
- PAGE_SIZE, 0);
- if (!devpriv->dma)
- free_irq(irq_num, dev);
- else
- dev->irq = irq_num;
-}
-
-static void dt282x_free_dma(struct comedi_device *dev)
-{
- struct dt282x_private *devpriv = dev->private;
-
- if (devpriv)
- comedi_isadma_free(devpriv->dma);
-}
-
-static int dt282x_initialize(struct comedi_device *dev)
-{
- /* Initialize board */
- outw(DT2821_SUPCSR_BDINIT, dev->iobase + DT2821_SUPCSR_REG);
- inw(dev->iobase + DT2821_ADCSR_REG);
-
- /*
- * At power up, some registers are in a well-known state.
- * Check them to see if a DT2821 series board is present.
- */
- if (((inw(dev->iobase + DT2821_ADCSR_REG) & 0xfff0) != 0x7c00) ||
- ((inw(dev->iobase + DT2821_CHANCSR_REG) & 0xf0f0) != 0x70f0) ||
- ((inw(dev->iobase + DT2821_DACSR_REG) & 0x7c93) != 0x7c90) ||
- ((inw(dev->iobase + DT2821_SUPCSR_REG) & 0xf8ff) != 0x0000) ||
- ((inw(dev->iobase + DT2821_TMRCTR_REG) & 0xff00) != 0xf000)) {
- dev_err(dev->class_dev, "board not found\n");
- return -EIO;
- }
- return 0;
-}
-
-static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct dt282x_board *board = dev->board_ptr;
- struct dt282x_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- ret = dt282x_initialize(dev);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- /* an IRQ and 2 DMA channels are required for async command support */
- dt282x_alloc_dma(dev, it);
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE;
- if ((it->options[4] && board->adchan_di) || board->adchan_se == 0) {
- s->subdev_flags |= SDF_DIFF;
- s->n_chan = board->adchan_di;
- } else {
- s->subdev_flags |= SDF_COMMON;
- s->n_chan = board->adchan_se;
- }
- s->maxdata = board->ai_maxdata;
-
- s->range_table = opt_ai_range_lkup(board->ispgl, it->options[8]);
- devpriv->ad_2scomp = it->options[5] ? 1 : 0;
-
- s->insn_read = dt282x_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = dt282x_ai_cmdtest;
- s->do_cmd = dt282x_ai_cmd;
- s->cancel = dt282x_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->dachan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->dachan;
- s->maxdata = board->ao_maxdata;
- /* ranges are per-channel, set by jumpers on the board */
- s->range_table = &dt282x_ao_range;
- s->insn_write = dt282x_ao_insn_write;
- if (dev->irq) {
- dev->write_subdev = s;
- s->subdev_flags |= SDF_CMD_WRITE;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = dt282x_ao_cmdtest;
- s->do_cmd = dt282x_ao_cmd;
- s->cancel = dt282x_ao_cancel;
- }
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dt282x_dio_insn_bits;
- s->insn_config = dt282x_dio_insn_config;
-
- return 0;
-}
-
-static void dt282x_detach(struct comedi_device *dev)
-{
- dt282x_free_dma(dev);
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver dt282x_driver = {
- .driver_name = "dt282x",
- .module = THIS_MODULE,
- .attach = dt282x_attach,
- .detach = dt282x_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct dt282x_board),
-};
-module_comedi_driver(dt282x_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Data Translation DT2821 series");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
deleted file mode 100644
index ec27aa4730d4..000000000000
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ /dev/null
@@ -1,740 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * dt3000.c
- * Data Translation DT3000 series driver
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: dt3000
- * Description: Data Translation DT3000 series
- * Devices: [Data Translation] DT3001 (dt3000), DT3001-PGL, DT3002, DT3003,
- * DT3003-PGL, DT3004, DT3005, DT3004-200
- * Author: ds
- * Updated: Mon, 14 Apr 2008 15:41:24 +0100
- * Status: works
- *
- * Configuration Options: not applicable, uses PCI auto config
- *
- * There is code to support AI commands, but it may not work.
- *
- * AO commands are not supported.
- */
-
-/*
- * The DT3000 series is Data Translation's attempt to make a PCI
- * data acquisition board. The design of this series is very nice,
- * since each board has an on-board DSP (Texas Instruments TMS320C52).
- * However, a few details are a little annoying. The boards lack
- * bus-mastering DMA, which eliminates them from serious work.
- * They also are not capable of autocalibration, which is a common
- * feature in modern hardware. The default firmware is pretty bad,
- * making it nearly impossible to write an RT compatible driver.
- * It would make an interesting project to write a decent firmware
- * for these boards.
- *
- * Data Translation originally wanted an NDA for the documentation
- * for the 3k series. However, if you ask nicely, they might send
- * you the docs without one, also.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI BAR0 - dual-ported RAM location definitions (dev->mmio)
- */
-#define DPR_DAC_BUFFER (4 * 0x000)
-#define DPR_ADC_BUFFER (4 * 0x800)
-#define DPR_COMMAND (4 * 0xfd3)
-#define DPR_SUBSYS (4 * 0xfd3)
-#define DPR_SUBSYS_AI 0
-#define DPR_SUBSYS_AO 1
-#define DPR_SUBSYS_DIN 2
-#define DPR_SUBSYS_DOUT 3
-#define DPR_SUBSYS_MEM 4
-#define DPR_SUBSYS_CT 5
-#define DPR_ENCODE (4 * 0xfd4)
-#define DPR_PARAMS(x) (4 * (0xfd5 + (x)))
-#define DPR_TICK_REG_LO (4 * 0xff5)
-#define DPR_TICK_REG_HI (4 * 0xff6)
-#define DPR_DA_BUF_FRONT (4 * 0xff7)
-#define DPR_DA_BUF_REAR (4 * 0xff8)
-#define DPR_AD_BUF_FRONT (4 * 0xff9)
-#define DPR_AD_BUF_REAR (4 * 0xffa)
-#define DPR_INT_MASK (4 * 0xffb)
-#define DPR_INTR_FLAG (4 * 0xffc)
-#define DPR_INTR_CMDONE BIT(7)
-#define DPR_INTR_CTDONE BIT(6)
-#define DPR_INTR_DAHWERR BIT(5)
-#define DPR_INTR_DASWERR BIT(4)
-#define DPR_INTR_DAEMPTY BIT(3)
-#define DPR_INTR_ADHWERR BIT(2)
-#define DPR_INTR_ADSWERR BIT(1)
-#define DPR_INTR_ADFULL BIT(0)
-#define DPR_RESPONSE_MBX (4 * 0xffe)
-#define DPR_CMD_MBX (4 * 0xfff)
-#define DPR_CMD_COMPLETION(x) ((x) << 8)
-#define DPR_CMD_NOTPROCESSED DPR_CMD_COMPLETION(0x00)
-#define DPR_CMD_NOERROR DPR_CMD_COMPLETION(0x55)
-#define DPR_CMD_ERROR DPR_CMD_COMPLETION(0xaa)
-#define DPR_CMD_NOTSUPPORTED DPR_CMD_COMPLETION(0xff)
-#define DPR_CMD_COMPLETION_MASK DPR_CMD_COMPLETION(0xff)
-#define DPR_CMD(x) ((x) << 0)
-#define DPR_CMD_GETBRDINFO DPR_CMD(0)
-#define DPR_CMD_CONFIG DPR_CMD(1)
-#define DPR_CMD_GETCONFIG DPR_CMD(2)
-#define DPR_CMD_START DPR_CMD(3)
-#define DPR_CMD_STOP DPR_CMD(4)
-#define DPR_CMD_READSINGLE DPR_CMD(5)
-#define DPR_CMD_WRITESINGLE DPR_CMD(6)
-#define DPR_CMD_CALCCLOCK DPR_CMD(7)
-#define DPR_CMD_READEVENTS DPR_CMD(8)
-#define DPR_CMD_WRITECTCTRL DPR_CMD(16)
-#define DPR_CMD_READCTCTRL DPR_CMD(17)
-#define DPR_CMD_WRITECT DPR_CMD(18)
-#define DPR_CMD_READCT DPR_CMD(19)
-#define DPR_CMD_WRITEDATA DPR_CMD(32)
-#define DPR_CMD_READDATA DPR_CMD(33)
-#define DPR_CMD_WRITEIO DPR_CMD(34)
-#define DPR_CMD_READIO DPR_CMD(35)
-#define DPR_CMD_WRITECODE DPR_CMD(36)
-#define DPR_CMD_READCODE DPR_CMD(37)
-#define DPR_CMD_EXECUTE DPR_CMD(38)
-#define DPR_CMD_HALT DPR_CMD(48)
-#define DPR_CMD_MASK DPR_CMD(0xff)
-
-#define DPR_PARAM5_AD_TRIG(x) (((x) & 0x7) << 2)
-#define DPR_PARAM5_AD_TRIG_INT DPR_PARAM5_AD_TRIG(0)
-#define DPR_PARAM5_AD_TRIG_EXT DPR_PARAM5_AD_TRIG(1)
-#define DPR_PARAM5_AD_TRIG_INT_RETRIG DPR_PARAM5_AD_TRIG(2)
-#define DPR_PARAM5_AD_TRIG_EXT_RETRIG DPR_PARAM5_AD_TRIG(3)
-#define DPR_PARAM5_AD_TRIG_INT_RETRIG2 DPR_PARAM5_AD_TRIG(4)
-
-#define DPR_PARAM6_AD_DIFF BIT(0)
-
-#define DPR_AI_FIFO_DEPTH 2003
-#define DPR_AO_FIFO_DEPTH 2048
-
-#define DPR_EXTERNAL_CLOCK 1
-#define DPR_RISING_EDGE 2
-
-#define DPR_TMODE_MASK 0x1c
-
-#define DPR_CMD_TIMEOUT 100
-
-static const struct comedi_lrange range_dt3000_ai = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_dt3000_ai_pgl = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.02)
- }
-};
-
-enum dt3k_boardid {
- BOARD_DT3001,
- BOARD_DT3001_PGL,
- BOARD_DT3002,
- BOARD_DT3003,
- BOARD_DT3003_PGL,
- BOARD_DT3004,
- BOARD_DT3005,
-};
-
-struct dt3k_boardtype {
- const char *name;
- int adchan;
- int ai_speed;
- const struct comedi_lrange *adrange;
- unsigned int ai_is_16bit:1;
- unsigned int has_ao:1;
-};
-
-static const struct dt3k_boardtype dt3k_boardtypes[] = {
- [BOARD_DT3001] = {
- .name = "dt3001",
- .adchan = 16,
- .adrange = &range_dt3000_ai,
- .ai_speed = 3000,
- .has_ao = 1,
- },
- [BOARD_DT3001_PGL] = {
- .name = "dt3001-pgl",
- .adchan = 16,
- .adrange = &range_dt3000_ai_pgl,
- .ai_speed = 3000,
- .has_ao = 1,
- },
- [BOARD_DT3002] = {
- .name = "dt3002",
- .adchan = 32,
- .adrange = &range_dt3000_ai,
- .ai_speed = 3000,
- },
- [BOARD_DT3003] = {
- .name = "dt3003",
- .adchan = 64,
- .adrange = &range_dt3000_ai,
- .ai_speed = 3000,
- .has_ao = 1,
- },
- [BOARD_DT3003_PGL] = {
- .name = "dt3003-pgl",
- .adchan = 64,
- .adrange = &range_dt3000_ai_pgl,
- .ai_speed = 3000,
- .has_ao = 1,
- },
- [BOARD_DT3004] = {
- .name = "dt3004",
- .adchan = 16,
- .adrange = &range_dt3000_ai,
- .ai_speed = 10000,
- .ai_is_16bit = 1,
- .has_ao = 1,
- },
- [BOARD_DT3005] = {
- .name = "dt3005", /* a.k.a. 3004-200 */
- .adchan = 16,
- .adrange = &range_dt3000_ai,
- .ai_speed = 5000,
- .ai_is_16bit = 1,
- .has_ao = 1,
- },
-};
-
-struct dt3k_private {
- unsigned int lock;
- unsigned int ai_front;
- unsigned int ai_rear;
-};
-
-static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
-{
- int i;
- unsigned int status = 0;
-
- writew(cmd, dev->mmio + DPR_CMD_MBX);
-
- for (i = 0; i < DPR_CMD_TIMEOUT; i++) {
- status = readw(dev->mmio + DPR_CMD_MBX);
- status &= DPR_CMD_COMPLETION_MASK;
- if (status != DPR_CMD_NOTPROCESSED)
- break;
- udelay(1);
- }
-
- if (status != DPR_CMD_NOERROR)
- dev_dbg(dev->class_dev, "%s: timeout/error status=0x%04x\n",
- __func__, status);
-}
-
-static unsigned int dt3k_readsingle(struct comedi_device *dev,
- unsigned int subsys, unsigned int chan,
- unsigned int gain)
-{
- writew(subsys, dev->mmio + DPR_SUBSYS);
-
- writew(chan, dev->mmio + DPR_PARAMS(0));
- writew(gain, dev->mmio + DPR_PARAMS(1));
-
- dt3k_send_cmd(dev, DPR_CMD_READSINGLE);
-
- return readw(dev->mmio + DPR_PARAMS(2));
-}
-
-static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys,
- unsigned int chan, unsigned int data)
-{
- writew(subsys, dev->mmio + DPR_SUBSYS);
-
- writew(chan, dev->mmio + DPR_PARAMS(0));
- writew(0, dev->mmio + DPR_PARAMS(1));
- writew(data, dev->mmio + DPR_PARAMS(2));
-
- dt3k_send_cmd(dev, DPR_CMD_WRITESINGLE);
-}
-
-static void dt3k_ai_empty_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dt3k_private *devpriv = dev->private;
- int front;
- int rear;
- int count;
- int i;
- unsigned short data;
-
- front = readw(dev->mmio + DPR_AD_BUF_FRONT);
- count = front - devpriv->ai_front;
- if (count < 0)
- count += DPR_AI_FIFO_DEPTH;
-
- rear = devpriv->ai_rear;
-
- for (i = 0; i < count; i++) {
- data = readw(dev->mmio + DPR_ADC_BUFFER + rear);
- comedi_buf_write_samples(s, &data, 1);
- rear++;
- if (rear >= DPR_AI_FIFO_DEPTH)
- rear = 0;
- }
-
- devpriv->ai_rear = rear;
- writew(rear, dev->mmio + DPR_AD_BUF_REAR);
-}
-
-static int dt3k_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- writew(DPR_SUBSYS_AI, dev->mmio + DPR_SUBSYS);
- dt3k_send_cmd(dev, DPR_CMD_STOP);
-
- writew(0, dev->mmio + DPR_INT_MASK);
-
- return 0;
-}
-
-static int debug_n_ints;
-
-/* FIXME! Assumes shared interrupt is for this card. */
-/* What's this debug_n_ints stuff? Obviously needs some work... */
-static irqreturn_t dt3k_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int status;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- status = readw(dev->mmio + DPR_INTR_FLAG);
-
- if (status & DPR_INTR_ADFULL)
- dt3k_ai_empty_fifo(dev, s);
-
- if (status & (DPR_INTR_ADSWERR | DPR_INTR_ADHWERR))
- s->async->events |= COMEDI_CB_ERROR;
-
- debug_n_ints++;
- if (debug_n_ints >= 10)
- s->async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
- unsigned int flags)
-{
- unsigned int divider, base, prescale;
-
- /* This function needs improvement */
- /* Don't know if divider==0 works. */
-
- for (prescale = 0; prescale < 16; prescale++) {
- base = timer_base * (prescale + 1);
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- divider = DIV_ROUND_CLOSEST(*nanosec, base);
- break;
- case CMDF_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case CMDF_ROUND_UP:
- divider = DIV_ROUND_UP(*nanosec, base);
- break;
- }
- if (divider < 65536) {
- *nanosec = divider * base;
- return (prescale << 16) | (divider);
- }
- }
-
- prescale = 15;
- base = timer_base * (prescale + 1);
- divider = 65535;
- *nanosec = divider * base;
- return (prescale << 16) | (divider);
-}
-
-static int dt3k_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- const struct dt3k_boardtype *board = dev->board_ptr;
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- board->ai_speed);
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- 100 * 16 * 65535);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
- 50 * 16 * 65535);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- dt3k_ns_to_timer(100, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- dt3k_ns_to_timer(50, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->convert_arg * cmd->scan_end_arg;
- err |= comedi_check_trigger_arg_min(
- &cmd->scan_begin_arg, arg);
- }
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- int i;
- unsigned int chan, range, aref;
- unsigned int divider;
- unsigned int tscandiv;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- chan = CR_CHAN(cmd->chanlist[i]);
- range = CR_RANGE(cmd->chanlist[i]);
-
- writew((range << 6) | chan, dev->mmio + DPR_ADC_BUFFER + i);
- }
- aref = CR_AREF(cmd->chanlist[0]);
-
- writew(cmd->scan_end_arg, dev->mmio + DPR_PARAMS(0));
-
- if (cmd->convert_src == TRIG_TIMER) {
- divider = dt3k_ns_to_timer(50, &cmd->convert_arg, cmd->flags);
- writew((divider >> 16), dev->mmio + DPR_PARAMS(1));
- writew((divider & 0xffff), dev->mmio + DPR_PARAMS(2));
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
- cmd->flags);
- writew((tscandiv >> 16), dev->mmio + DPR_PARAMS(3));
- writew((tscandiv & 0xffff), dev->mmio + DPR_PARAMS(4));
- }
-
- writew(DPR_PARAM5_AD_TRIG_INT_RETRIG, dev->mmio + DPR_PARAMS(5));
- writew((aref == AREF_DIFF) ? DPR_PARAM6_AD_DIFF : 0,
- dev->mmio + DPR_PARAMS(6));
-
- writew(DPR_AI_FIFO_DEPTH / 2, dev->mmio + DPR_PARAMS(7));
-
- writew(DPR_SUBSYS_AI, dev->mmio + DPR_SUBSYS);
- dt3k_send_cmd(dev, DPR_CMD_CONFIG);
-
- writew(DPR_INTR_ADFULL | DPR_INTR_ADSWERR | DPR_INTR_ADHWERR,
- dev->mmio + DPR_INT_MASK);
-
- debug_n_ints = 0;
-
- writew(DPR_SUBSYS_AI, dev->mmio + DPR_SUBSYS);
- dt3k_send_cmd(dev, DPR_CMD_START);
-
- return 0;
-}
-
-static int dt3k_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int i;
- unsigned int chan, gain;
-
- chan = CR_CHAN(insn->chanspec);
- gain = CR_RANGE(insn->chanspec);
- /* XXX docs don't explain how to select aref */
-
- for (i = 0; i < insn->n; i++)
- data[i] = dt3k_readsingle(dev, DPR_SUBSYS_AI, chan, gain);
-
- return i;
-}
-
-static int dt3k_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- dt3k_writesingle(dev, DPR_SUBSYS_AO, chan, val);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static void dt3k_dio_config(struct comedi_device *dev, int bits)
-{
- /* XXX */
- writew(DPR_SUBSYS_DOUT, dev->mmio + DPR_SUBSYS);
-
- writew(bits, dev->mmio + DPR_PARAMS(0));
-
- /* XXX write 0 to DPR_PARAMS(1) and DPR_PARAMS(2) ? */
-
- dt3k_send_cmd(dev, DPR_CMD_CONFIG);
-}
-
-static int dt3k_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 4)
- mask = 0x0f;
- else
- mask = 0xf0;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- dt3k_dio_config(dev, (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3));
-
- return insn->n;
-}
-
-static int dt3k_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- dt3k_writesingle(dev, DPR_SUBSYS_DOUT, 0, s->state);
-
- data[1] = dt3k_readsingle(dev, DPR_SUBSYS_DIN, 0, 0);
-
- return insn->n;
-}
-
-static int dt3k_mem_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int addr = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- writew(DPR_SUBSYS_MEM, dev->mmio + DPR_SUBSYS);
- writew(addr, dev->mmio + DPR_PARAMS(0));
- writew(1, dev->mmio + DPR_PARAMS(1));
-
- dt3k_send_cmd(dev, DPR_CMD_READCODE);
-
- data[i] = readw(dev->mmio + DPR_PARAMS(2));
- }
-
- return i;
-}
-
-static int dt3000_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct dt3k_boardtype *board = NULL;
- struct dt3k_private *devpriv;
- struct comedi_subdevice *s;
- int ret = 0;
-
- if (context < ARRAY_SIZE(dt3k_boardtypes))
- board = &dt3k_boardtypes[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret < 0)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 0);
- if (!dev->mmio)
- return -ENOMEM;
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = board->adchan;
- s->maxdata = board->ai_is_16bit ? 0xffff : 0x0fff;
- s->range_table = &range_dt3000_ai; /* XXX */
- s->insn_read = dt3k_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 512;
- s->do_cmd = dt3k_ai_cmd;
- s->do_cmdtest = dt3k_ai_cmdtest;
- s->cancel = dt3k_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &range_bipolar10;
- s->insn_write = dt3k_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = dt3k_dio_insn_config;
- s->insn_bits = dt3k_dio_insn_bits;
-
- /* Memory subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 0x1000;
- s->maxdata = 0xff;
- s->range_table = &range_unknown;
- s->insn_read = dt3k_mem_insn_read;
-
- return 0;
-}
-
-static struct comedi_driver dt3000_driver = {
- .driver_name = "dt3000",
- .module = THIS_MODULE,
- .auto_attach = dt3000_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int dt3000_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &dt3000_driver, id->driver_data);
-}
-
-static const struct pci_device_id dt3000_pci_table[] = {
- { PCI_VDEVICE(DT, 0x0022), BOARD_DT3001 },
- { PCI_VDEVICE(DT, 0x0023), BOARD_DT3002 },
- { PCI_VDEVICE(DT, 0x0024), BOARD_DT3003 },
- { PCI_VDEVICE(DT, 0x0025), BOARD_DT3004 },
- { PCI_VDEVICE(DT, 0x0026), BOARD_DT3005 },
- { PCI_VDEVICE(DT, 0x0027), BOARD_DT3001_PGL },
- { PCI_VDEVICE(DT, 0x0028), BOARD_DT3003_PGL },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, dt3000_pci_table);
-
-static struct pci_driver dt3000_pci_driver = {
- .name = "dt3000",
- .id_table = dt3000_pci_table,
- .probe = dt3000_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(dt3000_driver, dt3000_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Data Translation DT3000 series boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
deleted file mode 100644
index 634f57730c1e..000000000000
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ /dev/null
@@ -1,871 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/dt9812.c
- * COMEDI driver for DataTranslation DT9812 USB module
- *
- * Copyright (C) 2005 Anders Blomdell <anders.blomdell@control.lth.se>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- */
-
-/*
- * Driver: dt9812
- * Description: Data Translation DT9812 USB module
- * Devices: [Data Translation] DT9812 (dt9812)
- * Author: anders.blomdell@control.lth.se (Anders Blomdell)
- * Status: in development
- * Updated: Sun Nov 20 20:18:34 EST 2005
- *
- * This driver works, but bulk transfers not implemented. Might be a
- * starting point for someone else. I found out too late that USB has
- * too high latencies (>1 ms) for my needs.
- */
-
-/*
- * Nota Bene:
- * 1. All writes to command pipe has to be 32 bytes (ISP1181B SHRTP=0 ?)
- * 2. The DDK source (as of sep 2005) is in error regarding the
- * input MUX bits (example code says P4, but firmware schematics
- * says P1).
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/uaccess.h>
-
-#include "../comedi_usb.h"
-
-#define DT9812_DIAGS_BOARD_INFO_ADDR 0xFBFF
-#define DT9812_MAX_WRITE_CMD_PIPE_SIZE 32
-#define DT9812_MAX_READ_CMD_PIPE_SIZE 32
-
-/* usb_bulk_msg() timeout in milliseconds */
-#define DT9812_USB_TIMEOUT 1000
-
-/*
- * See Silican Laboratories C8051F020/1/2/3 manual
- */
-#define F020_SFR_P4 0x84
-#define F020_SFR_P1 0x90
-#define F020_SFR_P2 0xa0
-#define F020_SFR_P3 0xb0
-#define F020_SFR_AMX0CF 0xba
-#define F020_SFR_AMX0SL 0xbb
-#define F020_SFR_ADC0CF 0xbc
-#define F020_SFR_ADC0L 0xbe
-#define F020_SFR_ADC0H 0xbf
-#define F020_SFR_DAC0L 0xd2
-#define F020_SFR_DAC0H 0xd3
-#define F020_SFR_DAC0CN 0xd4
-#define F020_SFR_DAC1L 0xd5
-#define F020_SFR_DAC1H 0xd6
-#define F020_SFR_DAC1CN 0xd7
-#define F020_SFR_ADC0CN 0xe8
-
-#define F020_MASK_ADC0CF_AMP0GN0 0x01
-#define F020_MASK_ADC0CF_AMP0GN1 0x02
-#define F020_MASK_ADC0CF_AMP0GN2 0x04
-
-#define F020_MASK_ADC0CN_AD0EN 0x80
-#define F020_MASK_ADC0CN_AD0INT 0x20
-#define F020_MASK_ADC0CN_AD0BUSY 0x10
-
-#define F020_MASK_DACXCN_DACXEN 0x80
-
-enum {
- /* A/D D/A DI DO CT */
- DT9812_DEVID_DT9812_10, /* 8 2 8 8 1 +/- 10V */
- DT9812_DEVID_DT9812_2PT5, /* 8 2 8 8 1 0-2.44V */
-};
-
-enum dt9812_gain {
- DT9812_GAIN_0PT25 = 1,
- DT9812_GAIN_0PT5 = 2,
- DT9812_GAIN_1 = 4,
- DT9812_GAIN_2 = 8,
- DT9812_GAIN_4 = 16,
- DT9812_GAIN_8 = 32,
- DT9812_GAIN_16 = 64,
-};
-
-enum {
- DT9812_LEAST_USB_FIRMWARE_CMD_CODE = 0,
- /* Write Flash memory */
- DT9812_W_FLASH_DATA = 0,
- /* Read Flash memory misc config info */
- DT9812_R_FLASH_DATA = 1,
-
- /*
- * Register read/write commands for processor
- */
-
- /* Read a single byte of USB memory */
- DT9812_R_SINGLE_BYTE_REG = 2,
- /* Write a single byte of USB memory */
- DT9812_W_SINGLE_BYTE_REG = 3,
- /* Multiple Reads of USB memory */
- DT9812_R_MULTI_BYTE_REG = 4,
- /* Multiple Writes of USB memory */
- DT9812_W_MULTI_BYTE_REG = 5,
- /* Read, (AND) with mask, OR value, then write (single) */
- DT9812_RMW_SINGLE_BYTE_REG = 6,
- /* Read, (AND) with mask, OR value, then write (multiple) */
- DT9812_RMW_MULTI_BYTE_REG = 7,
-
- /*
- * Register read/write commands for SMBus
- */
-
- /* Read a single byte of SMBus */
- DT9812_R_SINGLE_BYTE_SMBUS = 8,
- /* Write a single byte of SMBus */
- DT9812_W_SINGLE_BYTE_SMBUS = 9,
- /* Multiple Reads of SMBus */
- DT9812_R_MULTI_BYTE_SMBUS = 10,
- /* Multiple Writes of SMBus */
- DT9812_W_MULTI_BYTE_SMBUS = 11,
-
- /*
- * Register read/write commands for a device
- */
-
- /* Read a single byte of a device */
- DT9812_R_SINGLE_BYTE_DEV = 12,
- /* Write a single byte of a device */
- DT9812_W_SINGLE_BYTE_DEV = 13,
- /* Multiple Reads of a device */
- DT9812_R_MULTI_BYTE_DEV = 14,
- /* Multiple Writes of a device */
- DT9812_W_MULTI_BYTE_DEV = 15,
-
- /* Not sure if we'll need this */
- DT9812_W_DAC_THRESHOLD = 16,
-
- /* Set interrupt on change mask */
- DT9812_W_INT_ON_CHANGE_MASK = 17,
-
- /* Write (or Clear) the CGL for the ADC */
- DT9812_W_CGL = 18,
- /* Multiple Reads of USB memory */
- DT9812_R_MULTI_BYTE_USBMEM = 19,
- /* Multiple Writes to USB memory */
- DT9812_W_MULTI_BYTE_USBMEM = 20,
-
- /* Issue a start command to a given subsystem */
- DT9812_START_SUBSYSTEM = 21,
- /* Issue a stop command to a given subsystem */
- DT9812_STOP_SUBSYSTEM = 22,
-
- /* calibrate the board using CAL_POT_CMD */
- DT9812_CALIBRATE_POT = 23,
- /* set the DAC FIFO size */
- DT9812_W_DAC_FIFO_SIZE = 24,
- /* Write or Clear the CGL for the DAC */
- DT9812_W_CGL_DAC = 25,
- /* Read a single value from a subsystem */
- DT9812_R_SINGLE_VALUE_CMD = 26,
- /* Write a single value to a subsystem */
- DT9812_W_SINGLE_VALUE_CMD = 27,
- /* Valid DT9812_USB_FIRMWARE_CMD_CODE's will be less than this number */
- DT9812_MAX_USB_FIRMWARE_CMD_CODE,
-};
-
-struct dt9812_flash_data {
- __le16 numbytes;
- __le16 address;
-};
-
-#define DT9812_MAX_NUM_MULTI_BYTE_RDS \
- ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8))
-
-struct dt9812_read_multi {
- u8 count;
- u8 address[DT9812_MAX_NUM_MULTI_BYTE_RDS];
-};
-
-struct dt9812_write_byte {
- u8 address;
- u8 value;
-};
-
-#define DT9812_MAX_NUM_MULTI_BYTE_WRTS \
- ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
- sizeof(struct dt9812_write_byte))
-
-struct dt9812_write_multi {
- u8 count;
- struct dt9812_write_byte write[DT9812_MAX_NUM_MULTI_BYTE_WRTS];
-};
-
-struct dt9812_rmw_byte {
- u8 address;
- u8 and_mask;
- u8 or_value;
-};
-
-#define DT9812_MAX_NUM_MULTI_BYTE_RMWS \
- ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
- sizeof(struct dt9812_rmw_byte))
-
-struct dt9812_rmw_multi {
- u8 count;
- struct dt9812_rmw_byte rmw[DT9812_MAX_NUM_MULTI_BYTE_RMWS];
-};
-
-struct dt9812_usb_cmd {
- __le32 cmd;
- union {
- struct dt9812_flash_data flash_data_info;
- struct dt9812_read_multi read_multi_info;
- struct dt9812_write_multi write_multi_info;
- struct dt9812_rmw_multi rmw_multi_info;
- } u;
-};
-
-struct dt9812_private {
- struct mutex mut;
- struct {
- __u8 addr;
- size_t size;
- } cmd_wr, cmd_rd;
- u16 device;
-};
-
-static int dt9812_read_info(struct comedi_device *dev,
- int offset, void *buf, size_t buf_size)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct dt9812_private *devpriv = dev->private;
- struct dt9812_usb_cmd cmd;
- int count, ret;
-
- cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
- cmd.u.flash_data_info.address =
- cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
- cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size);
-
- /* DT9812 only responds to 32 byte writes!! */
- ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
- &cmd, 32, &count, DT9812_USB_TIMEOUT);
- if (ret)
- return ret;
-
- return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
- buf, buf_size, &count, DT9812_USB_TIMEOUT);
-}
-
-static int dt9812_read_multiple_registers(struct comedi_device *dev,
- int reg_count, u8 *address,
- u8 *value)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct dt9812_private *devpriv = dev->private;
- struct dt9812_usb_cmd cmd;
- int i, count, ret;
-
- cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG);
- cmd.u.read_multi_info.count = reg_count;
- for (i = 0; i < reg_count; i++)
- cmd.u.read_multi_info.address[i] = address[i];
-
- /* DT9812 only responds to 32 byte writes!! */
- ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
- &cmd, 32, &count, DT9812_USB_TIMEOUT);
- if (ret)
- return ret;
-
- return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
- value, reg_count, &count, DT9812_USB_TIMEOUT);
-}
-
-static int dt9812_write_multiple_registers(struct comedi_device *dev,
- int reg_count, u8 *address,
- u8 *value)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct dt9812_private *devpriv = dev->private;
- struct dt9812_usb_cmd cmd;
- int i, count;
-
- cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG);
- cmd.u.read_multi_info.count = reg_count;
- for (i = 0; i < reg_count; i++) {
- cmd.u.write_multi_info.write[i].address = address[i];
- cmd.u.write_multi_info.write[i].value = value[i];
- }
-
- /* DT9812 only responds to 32 byte writes!! */
- return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
- &cmd, 32, &count, DT9812_USB_TIMEOUT);
-}
-
-static int dt9812_rmw_multiple_registers(struct comedi_device *dev,
- int reg_count,
- struct dt9812_rmw_byte *rmw)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct dt9812_private *devpriv = dev->private;
- struct dt9812_usb_cmd cmd;
- int i, count;
-
- cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG);
- cmd.u.rmw_multi_info.count = reg_count;
- for (i = 0; i < reg_count; i++)
- cmd.u.rmw_multi_info.rmw[i] = rmw[i];
-
- /* DT9812 only responds to 32 byte writes!! */
- return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
- &cmd, 32, &count, DT9812_USB_TIMEOUT);
-}
-
-static int dt9812_digital_in(struct comedi_device *dev, u8 *bits)
-{
- struct dt9812_private *devpriv = dev->private;
- u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 };
- u8 value[2];
- int ret;
-
- mutex_lock(&devpriv->mut);
- ret = dt9812_read_multiple_registers(dev, 2, reg, value);
- if (ret == 0) {
- /*
- * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital
- * input port bit 3 in F020_SFR_P1 is bit 7 in the
- * digital input port
- */
- *bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
- }
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int dt9812_digital_out(struct comedi_device *dev, u8 bits)
-{
- struct dt9812_private *devpriv = dev->private;
- u8 reg[1] = { F020_SFR_P2 };
- u8 value[1] = { bits };
- int ret;
-
- mutex_lock(&devpriv->mut);
- ret = dt9812_write_multiple_registers(dev, 1, reg, value);
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static void dt9812_configure_mux(struct comedi_device *dev,
- struct dt9812_rmw_byte *rmw, int channel)
-{
- struct dt9812_private *devpriv = dev->private;
-
- if (devpriv->device == DT9812_DEVID_DT9812_10) {
- /* In the DT9812/10V MUX is selected by P1.5-7 */
- rmw->address = F020_SFR_P1;
- rmw->and_mask = 0xe0;
- rmw->or_value = channel << 5;
- } else {
- /* In the DT9812/2.5V, internal mux is selected by bits 0:2 */
- rmw->address = F020_SFR_AMX0SL;
- rmw->and_mask = 0xff;
- rmw->or_value = channel & 0x07;
- }
-}
-
-static void dt9812_configure_gain(struct comedi_device *dev,
- struct dt9812_rmw_byte *rmw,
- enum dt9812_gain gain)
-{
- struct dt9812_private *devpriv = dev->private;
-
- /* In the DT9812/10V, there is an external gain of 0.5 */
- if (devpriv->device == DT9812_DEVID_DT9812_10)
- gain <<= 1;
-
- rmw->address = F020_SFR_ADC0CF;
- rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 |
- F020_MASK_ADC0CF_AMP0GN1 |
- F020_MASK_ADC0CF_AMP0GN0;
-
- switch (gain) {
- /*
- * 000 -> Gain = 1
- * 001 -> Gain = 2
- * 010 -> Gain = 4
- * 011 -> Gain = 8
- * 10x -> Gain = 16
- * 11x -> Gain = 0.5
- */
- case DT9812_GAIN_0PT5:
- rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 |
- F020_MASK_ADC0CF_AMP0GN1;
- break;
- default:
- /* this should never happen, just use a gain of 1 */
- case DT9812_GAIN_1:
- rmw->or_value = 0x00;
- break;
- case DT9812_GAIN_2:
- rmw->or_value = F020_MASK_ADC0CF_AMP0GN0;
- break;
- case DT9812_GAIN_4:
- rmw->or_value = F020_MASK_ADC0CF_AMP0GN1;
- break;
- case DT9812_GAIN_8:
- rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 |
- F020_MASK_ADC0CF_AMP0GN0;
- break;
- case DT9812_GAIN_16:
- rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
- break;
- }
-}
-
-static int dt9812_analog_in(struct comedi_device *dev,
- int channel, u16 *value, enum dt9812_gain gain)
-{
- struct dt9812_private *devpriv = dev->private;
- struct dt9812_rmw_byte rmw[3];
- u8 reg[3] = {
- F020_SFR_ADC0CN,
- F020_SFR_ADC0H,
- F020_SFR_ADC0L
- };
- u8 val[3];
- int ret;
-
- mutex_lock(&devpriv->mut);
-
- /* 1 select the gain */
- dt9812_configure_gain(dev, &rmw[0], gain);
-
- /* 2 set the MUX to select the channel */
- dt9812_configure_mux(dev, &rmw[1], channel);
-
- /* 3 start conversion */
- rmw[2].address = F020_SFR_ADC0CN;
- rmw[2].and_mask = 0xff;
- rmw[2].or_value = F020_MASK_ADC0CN_AD0EN | F020_MASK_ADC0CN_AD0BUSY;
-
- ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
- if (ret)
- goto exit;
-
- /* read the status and ADC */
- ret = dt9812_read_multiple_registers(dev, 3, reg, val);
- if (ret)
- goto exit;
-
- /*
- * An ADC conversion takes 16 SAR clocks cycles, i.e. about 9us.
- * Therefore, between the instant that AD0BUSY was set via
- * dt9812_rmw_multiple_registers and the read of AD0BUSY via
- * dt9812_read_multiple_registers, the conversion should be complete
- * since these two operations require two USB transactions each taking
- * at least a millisecond to complete. However, lets make sure that
- * conversion is finished.
- */
- if ((val[0] & (F020_MASK_ADC0CN_AD0INT | F020_MASK_ADC0CN_AD0BUSY)) ==
- F020_MASK_ADC0CN_AD0INT) {
- switch (devpriv->device) {
- case DT9812_DEVID_DT9812_10:
- /*
- * For DT9812-10V the personality module set the
- * encoding to 2's complement. Hence, convert it before
- * returning it
- */
- *value = ((val[1] << 8) | val[2]) + 0x800;
- break;
- case DT9812_DEVID_DT9812_2PT5:
- *value = (val[1] << 8) | val[2];
- break;
- }
- }
-
-exit:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int dt9812_analog_out(struct comedi_device *dev, int channel, u16 value)
-{
- struct dt9812_private *devpriv = dev->private;
- struct dt9812_rmw_byte rmw[3];
- int ret;
-
- mutex_lock(&devpriv->mut);
-
- switch (channel) {
- case 0:
- /* 1. Set DAC mode */
- rmw[0].address = F020_SFR_DAC0CN;
- rmw[0].and_mask = 0xff;
- rmw[0].or_value = F020_MASK_DACXCN_DACXEN;
-
- /* 2. load lsb of DAC value first */
- rmw[1].address = F020_SFR_DAC0L;
- rmw[1].and_mask = 0xff;
- rmw[1].or_value = value & 0xff;
-
- /* 3. load msb of DAC value next to latch the 12-bit value */
- rmw[2].address = F020_SFR_DAC0H;
- rmw[2].and_mask = 0xff;
- rmw[2].or_value = (value >> 8) & 0xf;
- break;
-
- case 1:
- /* 1. Set DAC mode */
- rmw[0].address = F020_SFR_DAC1CN;
- rmw[0].and_mask = 0xff;
- rmw[0].or_value = F020_MASK_DACXCN_DACXEN;
-
- /* 2. load lsb of DAC value first */
- rmw[1].address = F020_SFR_DAC1L;
- rmw[1].and_mask = 0xff;
- rmw[1].or_value = value & 0xff;
-
- /* 3. load msb of DAC value next to latch the 12-bit value */
- rmw[2].address = F020_SFR_DAC1H;
- rmw[2].and_mask = 0xff;
- rmw[2].or_value = (value >> 8) & 0xf;
- break;
- }
- ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
-
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int dt9812_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- u8 bits = 0;
- int ret;
-
- ret = dt9812_digital_in(dev, &bits);
- if (ret)
- return ret;
-
- data[1] = bits;
-
- return insn->n;
-}
-
-static int dt9812_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- dt9812_digital_out(dev, s->state);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int dt9812_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- u16 val = 0;
- int ret;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- ret = dt9812_analog_in(dev, chan, &val, DT9812_GAIN_1);
- if (ret)
- return ret;
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int dt9812_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dt9812_private *devpriv = dev->private;
- int ret;
-
- mutex_lock(&devpriv->mut);
- ret = comedi_readback_insn_read(dev, s, insn, data);
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int dt9812_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
- int ret;
-
- ret = dt9812_analog_out(dev, chan, val);
- if (ret)
- return ret;
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int dt9812_find_endpoints(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usb_host_interface *host = intf->cur_altsetting;
- struct dt9812_private *devpriv = dev->private;
- struct usb_endpoint_descriptor *ep;
- int i;
-
- if (host->desc.bNumEndpoints != 5) {
- dev_err(dev->class_dev, "Wrong number of endpoints\n");
- return -ENODEV;
- }
-
- for (i = 0; i < host->desc.bNumEndpoints; ++i) {
- int dir = -1;
-
- ep = &host->endpoint[i].desc;
- switch (i) {
- case 0:
- /* unused message pipe */
- dir = USB_DIR_IN;
- break;
- case 1:
- dir = USB_DIR_OUT;
- devpriv->cmd_wr.addr = ep->bEndpointAddress;
- devpriv->cmd_wr.size = usb_endpoint_maxp(ep);
- break;
- case 2:
- dir = USB_DIR_IN;
- devpriv->cmd_rd.addr = ep->bEndpointAddress;
- devpriv->cmd_rd.size = usb_endpoint_maxp(ep);
- break;
- case 3:
- /* unused write stream */
- dir = USB_DIR_OUT;
- break;
- case 4:
- /* unused read stream */
- dir = USB_DIR_IN;
- break;
- }
- if ((ep->bEndpointAddress & USB_DIR_IN) != dir) {
- dev_err(dev->class_dev,
- "Endpoint has wrong direction\n");
- return -ENODEV;
- }
- }
- return 0;
-}
-
-static int dt9812_reset_device(struct comedi_device *dev)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct dt9812_private *devpriv = dev->private;
- u32 serial;
- u16 vendor;
- u16 product;
- u8 tmp8;
- __le16 tmp16;
- __le32 tmp32;
- int ret;
- int i;
-
- ret = dt9812_read_info(dev, 0, &tmp8, sizeof(tmp8));
- if (ret) {
- /*
- * Seems like a configuration reset is necessary if driver is
- * reloaded while device is attached
- */
- usb_reset_configuration(usb);
- for (i = 0; i < 10; i++) {
- ret = dt9812_read_info(dev, 1, &tmp8, sizeof(tmp8));
- if (ret == 0)
- break;
- }
- if (ret) {
- dev_err(dev->class_dev,
- "unable to reset configuration\n");
- return ret;
- }
- }
-
- ret = dt9812_read_info(dev, 1, &tmp16, sizeof(tmp16));
- if (ret) {
- dev_err(dev->class_dev, "failed to read vendor id\n");
- return ret;
- }
- vendor = le16_to_cpu(tmp16);
-
- ret = dt9812_read_info(dev, 3, &tmp16, sizeof(tmp16));
- if (ret) {
- dev_err(dev->class_dev, "failed to read product id\n");
- return ret;
- }
- product = le16_to_cpu(tmp16);
-
- ret = dt9812_read_info(dev, 5, &tmp16, sizeof(tmp16));
- if (ret) {
- dev_err(dev->class_dev, "failed to read device id\n");
- return ret;
- }
- devpriv->device = le16_to_cpu(tmp16);
-
- ret = dt9812_read_info(dev, 7, &tmp32, sizeof(tmp32));
- if (ret) {
- dev_err(dev->class_dev, "failed to read serial number\n");
- return ret;
- }
- serial = le32_to_cpu(tmp32);
-
- /* let the user know what node this device is now attached to */
- dev_info(dev->class_dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n",
- vendor, product, devpriv->device, serial);
-
- if (devpriv->device != DT9812_DEVID_DT9812_10 &&
- devpriv->device != DT9812_DEVID_DT9812_2PT5) {
- dev_err(dev->class_dev, "Unsupported device!\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int dt9812_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct dt9812_private *devpriv;
- struct comedi_subdevice *s;
- bool is_unipolar;
- int ret;
- int i;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- mutex_init(&devpriv->mut);
- usb_set_intfdata(intf, devpriv);
-
- ret = dt9812_find_endpoints(dev);
- if (ret)
- return ret;
-
- ret = dt9812_reset_device(dev);
- if (ret)
- return ret;
-
- is_unipolar = (devpriv->device == DT9812_DEVID_DT9812_2PT5);
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dt9812_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dt9812_do_insn_bits;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 8;
- s->maxdata = 0x0fff;
- s->range_table = is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
- s->insn_read = dt9812_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
- s->insn_write = dt9812_ao_insn_write;
- s->insn_read = dt9812_ao_insn_read;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++)
- s->readback[i] = is_unipolar ? 0x0000 : 0x0800;
-
- return 0;
-}
-
-static void dt9812_detach(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct dt9812_private *devpriv = dev->private;
-
- if (!devpriv)
- return;
-
- mutex_destroy(&devpriv->mut);
- usb_set_intfdata(intf, NULL);
-}
-
-static struct comedi_driver dt9812_driver = {
- .driver_name = "dt9812",
- .module = THIS_MODULE,
- .auto_attach = dt9812_auto_attach,
- .detach = dt9812_detach,
-};
-
-static int dt9812_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return comedi_usb_auto_config(intf, &dt9812_driver, id->driver_info);
-}
-
-static const struct usb_device_id dt9812_usb_table[] = {
- { USB_DEVICE(0x0867, 0x9812) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, dt9812_usb_table);
-
-static struct usb_driver dt9812_usb_driver = {
- .name = "dt9812",
- .id_table = dt9812_usb_table,
- .probe = dt9812_usb_probe,
- .disconnect = comedi_usb_auto_unconfig,
-};
-module_comedi_usb_driver(dt9812_driver, dt9812_usb_driver);
-
-MODULE_AUTHOR("Anders Blomdell <anders.blomdell@control.lth.se>");
-MODULE_DESCRIPTION("Comedi DT9812 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c
deleted file mode 100644
index c224422bb126..000000000000
--- a/drivers/staging/comedi/drivers/dyna_pci10xx.c
+++ /dev/null
@@ -1,265 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/dyna_pci10xx.c
- * Copyright (C) 2011 Prashant Shah, pshah.mumbai@gmail.com
- */
-
-/*
- * Driver: dyna_pci10xx
- * Description: Dynalog India PCI DAQ Cards, http://www.dynalogindia.com/
- * Devices: [Dynalog] PCI-1050 (dyna_pci1050)
- * Author: Prashant Shah <pshah.mumbai@gmail.com>
- * Status: Stable
- *
- * Developed at Automation Labs, Chemical Dept., IIT Bombay, India.
- * Prof. Kannan Moudgalya <kannan@iitb.ac.in>
- * http://www.iitb.ac.in
- *
- * Notes :
- * - Dynalog India Pvt. Ltd. does not have a registered PCI Vendor ID and
- * they are using the PLX Technlogies Vendor ID since that is the PCI Chip
- * used in the card.
- * - Dynalog India Pvt. Ltd. has provided the internal register specification
- * for their cards in their manuals.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-
-#include "../comedi_pci.h"
-
-#define READ_TIMEOUT 50
-
-static const struct comedi_lrange range_pci1050_ai = {
- 3, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-static const char range_codes_pci1050_ai[] = { 0x00, 0x10, 0x30 };
-
-struct dyna_pci10xx_private {
- struct mutex mutex;
- unsigned long BADR3;
-};
-
-static int dyna_pci10xx_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw_p(dev->iobase);
- if (status & BIT(15))
- return 0;
- return -EBUSY;
-}
-
-static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dyna_pci10xx_private *devpriv = dev->private;
- int n;
- u16 d = 0;
- int ret = 0;
- unsigned int chan, range;
-
- /* get the channel number and range */
- chan = CR_CHAN(insn->chanspec);
- range = range_codes_pci1050_ai[CR_RANGE((insn->chanspec))];
-
- mutex_lock(&devpriv->mutex);
- /* convert n samples */
- for (n = 0; n < insn->n; n++) {
- /* trigger conversion */
- smp_mb();
- outw_p(0x0000 + range + chan, dev->iobase + 2);
- usleep_range(10, 20);
-
- ret = comedi_timeout(dev, s, insn, dyna_pci10xx_ai_eoc, 0);
- if (ret)
- break;
-
- /* read data */
- d = inw_p(dev->iobase);
- /* mask the first 4 bits - EOC bits */
- d &= 0x0FFF;
- data[n] = d;
- }
- mutex_unlock(&devpriv->mutex);
-
- /* return the number of samples read/written */
- return ret ? ret : n;
-}
-
-/* analog output callback */
-static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dyna_pci10xx_private *devpriv = dev->private;
- int n;
-
- mutex_lock(&devpriv->mutex);
- for (n = 0; n < insn->n; n++) {
- smp_mb();
- /* trigger conversion and write data */
- outw_p(data[n], dev->iobase);
- usleep_range(10, 20);
- }
- mutex_unlock(&devpriv->mutex);
- return n;
-}
-
-/* digital input bit interface */
-static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dyna_pci10xx_private *devpriv = dev->private;
- u16 d = 0;
-
- mutex_lock(&devpriv->mutex);
- smp_mb();
- d = inw_p(devpriv->BADR3);
- usleep_range(10, 100);
-
- /* on return the data[0] contains output and data[1] contains input */
- data[1] = d;
- data[0] = s->state;
- mutex_unlock(&devpriv->mutex);
- return insn->n;
-}
-
-static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct dyna_pci10xx_private *devpriv = dev->private;
-
- mutex_lock(&devpriv->mutex);
- if (comedi_dio_update_state(s, data)) {
- smp_mb();
- outw_p(s->state, devpriv->BADR3);
- usleep_range(10, 100);
- }
-
- data[1] = s->state;
- mutex_unlock(&devpriv->mutex);
-
- return insn->n;
-}
-
-static int dyna_pci10xx_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct dyna_pci10xx_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 2);
- devpriv->BADR3 = pci_resource_start(pcidev, 3);
-
- mutex_init(&devpriv->mutex);
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* analog input */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = 0x0FFF;
- s->range_table = &range_pci1050_ai;
- s->insn_read = dyna_pci10xx_insn_read_ai;
-
- /* analog output */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 1;
- s->maxdata = 0x0FFF;
- s->range_table = &range_unipolar10;
- s->insn_write = dyna_pci10xx_insn_write_ao;
-
- /* digital input */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dyna_pci10xx_di_insn_bits;
-
- /* digital output */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->state = 0;
- s->insn_bits = dyna_pci10xx_do_insn_bits;
-
- return 0;
-}
-
-static void dyna_pci10xx_detach(struct comedi_device *dev)
-{
- struct dyna_pci10xx_private *devpriv = dev->private;
-
- comedi_pci_detach(dev);
- if (devpriv)
- mutex_destroy(&devpriv->mutex);
-}
-
-static struct comedi_driver dyna_pci10xx_driver = {
- .driver_name = "dyna_pci10xx",
- .module = THIS_MODULE,
- .auto_attach = dyna_pci10xx_auto_attach,
- .detach = dyna_pci10xx_detach,
-};
-
-static int dyna_pci10xx_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &dyna_pci10xx_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id dyna_pci10xx_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_PLX, 0x1050) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table);
-
-static struct pci_driver dyna_pci10xx_pci_driver = {
- .name = "dyna_pci10xx",
- .id_table = dyna_pci10xx_pci_table,
- .probe = dyna_pci10xx_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(dyna_pci10xx_driver, dyna_pci10xx_pci_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Prashant Shah <pshah.mumbai@gmail.com>");
-MODULE_DESCRIPTION("Comedi based drivers for Dynalog PCI DAQ cards");
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
deleted file mode 100644
index b715f30659fa..000000000000
--- a/drivers/staging/comedi/drivers/fl512.c
+++ /dev/null
@@ -1,143 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * fl512.c
- * Anders Gnistrup <ex18@kalman.iau.dtu.dk>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: fl512
- * Description: unknown
- * Author: Anders Gnistrup <ex18@kalman.iau.dtu.dk>
- * Devices: [unknown] FL512 (fl512)
- * Status: unknown
- *
- * Digital I/O is not supported.
- *
- * Configuration options:
- * [0] - I/O port base address
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include <linux/delay.h>
-
-/*
- * Register I/O map
- */
-#define FL512_AI_LSB_REG 0x02
-#define FL512_AI_MSB_REG 0x03
-#define FL512_AI_MUX_REG 0x02
-#define FL512_AI_START_CONV_REG 0x03
-#define FL512_AO_DATA_REG(x) (0x04 + ((x) * 2))
-#define FL512_AO_TRIG_REG(x) (0x04 + ((x) * 2))
-
-static const struct comedi_lrange range_fl512 = {
- 4, {
- BIP_RANGE(0.5),
- BIP_RANGE(1),
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-static int fl512_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
- int i;
-
- outb(chan, dev->iobase + FL512_AI_MUX_REG);
-
- for (i = 0; i < insn->n; i++) {
- outb(0, dev->iobase + FL512_AI_START_CONV_REG);
-
- /* XXX should test "done" flag instead of delay */
- usleep_range(30, 100);
-
- val = inb(dev->iobase + FL512_AI_LSB_REG);
- val |= (inb(dev->iobase + FL512_AI_MSB_REG) << 8);
- val &= s->maxdata;
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int fl512_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- /* write LSB, MSB then trigger conversion */
- outb(val & 0x0ff, dev->iobase + FL512_AO_DATA_REG(chan));
- outb((val >> 8) & 0xf, dev->iobase + FL512_AO_DATA_REG(chan));
- inb(dev->iobase + FL512_AO_TRIG_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 16;
- s->maxdata = 0x0fff;
- s->range_table = &range_fl512;
- s->insn_read = fl512_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &range_fl512;
- s->insn_write = fl512_ao_insn_write;
-
- return comedi_alloc_subdev_readback(s);
-}
-
-static struct comedi_driver fl512_driver = {
- .driver_name = "fl512",
- .module = THIS_MODULE,
- .attach = fl512_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(fl512_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
deleted file mode 100644
index e35e4a743714..000000000000
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ /dev/null
@@ -1,723 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * gsc_hpdi.c
- * Comedi driver the General Standards Corporation
- * High Speed Parallel Digital Interface rs485 boards.
- *
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Copyright (C) 2003 Coherent Imaging Systems
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: gsc_hpdi
- * Description: General Standards Corporation High
- * Speed Parallel Digital Interface rs485 boards
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Status: only receive mode works, transmit not supported
- * Updated: Thu, 01 Nov 2012 16:17:38 +0000
- * Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
- * PMC-HPDI32
- *
- * Configuration options:
- * None.
- *
- * Manual configuration of supported devices is not supported; they are
- * configured automatically.
- *
- * There are some additional hpdi models available from GSC for which
- * support could be added to this driver.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "plx9080.h"
-
-/*
- * PCI BAR2 Register map (dev->mmio)
- */
-#define FIRMWARE_REV_REG 0x00
-#define FEATURES_REG_PRESENT_BIT BIT(15)
-#define BOARD_CONTROL_REG 0x04
-#define BOARD_RESET_BIT BIT(0)
-#define TX_FIFO_RESET_BIT BIT(1)
-#define RX_FIFO_RESET_BIT BIT(2)
-#define TX_ENABLE_BIT BIT(4)
-#define RX_ENABLE_BIT BIT(5)
-#define DEMAND_DMA_DIRECTION_TX_BIT BIT(6) /* ch 0 only */
-#define LINE_VALID_ON_STATUS_VALID_BIT BIT(7)
-#define START_TX_BIT BIT(8)
-#define CABLE_THROTTLE_ENABLE_BIT BIT(9)
-#define TEST_MODE_ENABLE_BIT BIT(31)
-#define BOARD_STATUS_REG 0x08
-#define COMMAND_LINE_STATUS_MASK (0x7f << 0)
-#define TX_IN_PROGRESS_BIT BIT(7)
-#define TX_NOT_EMPTY_BIT BIT(8)
-#define TX_NOT_ALMOST_EMPTY_BIT BIT(9)
-#define TX_NOT_ALMOST_FULL_BIT BIT(10)
-#define TX_NOT_FULL_BIT BIT(11)
-#define RX_NOT_EMPTY_BIT BIT(12)
-#define RX_NOT_ALMOST_EMPTY_BIT BIT(13)
-#define RX_NOT_ALMOST_FULL_BIT BIT(14)
-#define RX_NOT_FULL_BIT BIT(15)
-#define BOARD_JUMPER0_INSTALLED_BIT BIT(16)
-#define BOARD_JUMPER1_INSTALLED_BIT BIT(17)
-#define TX_OVERRUN_BIT BIT(21)
-#define RX_UNDERRUN_BIT BIT(22)
-#define RX_OVERRUN_BIT BIT(23)
-#define TX_PROG_ALMOST_REG 0x0c
-#define RX_PROG_ALMOST_REG 0x10
-#define ALMOST_EMPTY_BITS(x) (((x) & 0xffff) << 0)
-#define ALMOST_FULL_BITS(x) (((x) & 0xff) << 16)
-#define FEATURES_REG 0x14
-#define FIFO_SIZE_PRESENT_BIT BIT(0)
-#define FIFO_WORDS_PRESENT_BIT BIT(1)
-#define LEVEL_EDGE_INTERRUPTS_PRESENT_BIT BIT(2)
-#define GPIO_SUPPORTED_BIT BIT(3)
-#define PLX_DMA_CH1_SUPPORTED_BIT BIT(4)
-#define OVERRUN_UNDERRUN_SUPPORTED_BIT BIT(5)
-#define FIFO_REG 0x18
-#define TX_STATUS_COUNT_REG 0x1c
-#define TX_LINE_VALID_COUNT_REG 0x20,
-#define TX_LINE_INVALID_COUNT_REG 0x24
-#define RX_STATUS_COUNT_REG 0x28
-#define RX_LINE_COUNT_REG 0x2c
-#define INTERRUPT_CONTROL_REG 0x30
-#define FRAME_VALID_START_INTR BIT(0)
-#define FRAME_VALID_END_INTR BIT(1)
-#define TX_FIFO_EMPTY_INTR BIT(8)
-#define TX_FIFO_ALMOST_EMPTY_INTR BIT(9)
-#define TX_FIFO_ALMOST_FULL_INTR BIT(10)
-#define TX_FIFO_FULL_INTR BIT(11)
-#define RX_EMPTY_INTR BIT(12)
-#define RX_ALMOST_EMPTY_INTR BIT(13)
-#define RX_ALMOST_FULL_INTR BIT(14)
-#define RX_FULL_INTR BIT(15)
-#define INTERRUPT_STATUS_REG 0x34
-#define TX_CLOCK_DIVIDER_REG 0x38
-#define TX_FIFO_SIZE_REG 0x40
-#define RX_FIFO_SIZE_REG 0x44
-#define FIFO_SIZE_MASK (0xfffff << 0)
-#define TX_FIFO_WORDS_REG 0x48
-#define RX_FIFO_WORDS_REG 0x4c
-#define INTERRUPT_EDGE_LEVEL_REG 0x50
-#define INTERRUPT_POLARITY_REG 0x54
-
-#define TIMER_BASE 50 /* 20MHz master clock */
-#define DMA_BUFFER_SIZE 0x10000
-#define NUM_DMA_BUFFERS 4
-#define NUM_DMA_DESCRIPTORS 256
-
-struct hpdi_private {
- void __iomem *plx9080_mmio;
- u32 *dio_buffer[NUM_DMA_BUFFERS]; /* dma buffers */
- /* physical addresses of dma buffers */
- dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];
- /*
- * array of dma descriptors read by plx9080, allocated to get proper
- * alignment
- */
- struct plx_dma_desc *dma_desc;
- /* physical address of dma descriptor array */
- dma_addr_t dma_desc_phys_addr;
- unsigned int num_dma_descriptors;
- /* pointer to start of buffers indexed by descriptor */
- u32 *desc_dio_buffer[NUM_DMA_DESCRIPTORS];
- /* index of the dma descriptor that is currently being used */
- unsigned int dma_desc_index;
- unsigned int tx_fifo_size;
- unsigned int rx_fifo_size;
- unsigned long dio_count;
- /* number of bytes at which to generate COMEDI_CB_BLOCK events */
- unsigned int block_size;
-};
-
-static void gsc_hpdi_drain_dma(struct comedi_device *dev, unsigned int channel)
-{
- struct hpdi_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int idx;
- unsigned int start;
- unsigned int desc;
- unsigned int size;
- unsigned int next;
-
- next = readl(devpriv->plx9080_mmio + PLX_REG_DMAPADR(channel));
-
- idx = devpriv->dma_desc_index;
- start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);
- /* loop until we have read all the full buffers */
- for (desc = 0; (next < start || next >= start + devpriv->block_size) &&
- desc < devpriv->num_dma_descriptors; desc++) {
- /* transfer data from dma buffer to comedi buffer */
- size = devpriv->block_size / sizeof(u32);
- if (cmd->stop_src == TRIG_COUNT) {
- if (size > devpriv->dio_count)
- size = devpriv->dio_count;
- devpriv->dio_count -= size;
- }
- comedi_buf_write_samples(s, devpriv->desc_dio_buffer[idx],
- size);
- idx++;
- idx %= devpriv->num_dma_descriptors;
- start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);
-
- devpriv->dma_desc_index = idx;
- }
- /* XXX check for buffer overrun somehow */
-}
-
-static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct hpdi_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- u32 hpdi_intr_status, hpdi_board_status;
- u32 plx_status;
- u32 plx_bits;
- u8 dma0_status, dma1_status;
- unsigned long flags;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- plx_status = readl(devpriv->plx9080_mmio + PLX_REG_INTCSR);
- if ((plx_status &
- (PLX_INTCSR_DMA0IA | PLX_INTCSR_DMA1IA | PLX_INTCSR_PLIA)) == 0)
- return IRQ_NONE;
-
- hpdi_intr_status = readl(dev->mmio + INTERRUPT_STATUS_REG);
- hpdi_board_status = readl(dev->mmio + BOARD_STATUS_REG);
-
- if (hpdi_intr_status)
- writel(hpdi_intr_status, dev->mmio + INTERRUPT_STATUS_REG);
-
- /* spin lock makes sure no one else changes plx dma control reg */
- spin_lock_irqsave(&dev->spinlock, flags);
- dma0_status = readb(devpriv->plx9080_mmio + PLX_REG_DMACSR0);
- if (plx_status & PLX_INTCSR_DMA0IA) {
- /* dma chan 0 interrupt */
- writeb((dma0_status & PLX_DMACSR_ENABLE) | PLX_DMACSR_CLEARINTR,
- devpriv->plx9080_mmio + PLX_REG_DMACSR0);
-
- if (dma0_status & PLX_DMACSR_ENABLE)
- gsc_hpdi_drain_dma(dev, 0);
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* spin lock makes sure no one else changes plx dma control reg */
- spin_lock_irqsave(&dev->spinlock, flags);
- dma1_status = readb(devpriv->plx9080_mmio + PLX_REG_DMACSR1);
- if (plx_status & PLX_INTCSR_DMA1IA) {
- /* XXX */ /* dma chan 1 interrupt */
- writeb((dma1_status & PLX_DMACSR_ENABLE) | PLX_DMACSR_CLEARINTR,
- devpriv->plx9080_mmio + PLX_REG_DMACSR1);
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* clear possible plx9080 interrupt sources */
- if (plx_status & PLX_INTCSR_LDBIA) {
- /* clear local doorbell interrupt */
- plx_bits = readl(devpriv->plx9080_mmio + PLX_REG_L2PDBELL);
- writel(plx_bits, devpriv->plx9080_mmio + PLX_REG_L2PDBELL);
- }
-
- if (hpdi_board_status & RX_OVERRUN_BIT) {
- dev_err(dev->class_dev, "rx fifo overrun\n");
- async->events |= COMEDI_CB_ERROR;
- }
-
- if (hpdi_board_status & RX_UNDERRUN_BIT) {
- dev_err(dev->class_dev, "rx fifo underrun\n");
- async->events |= COMEDI_CB_ERROR;
- }
-
- if (devpriv->dio_count == 0)
- async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static void gsc_hpdi_abort_dma(struct comedi_device *dev, unsigned int channel)
-{
- struct hpdi_private *devpriv = dev->private;
- unsigned long flags;
-
- /* spinlock for plx dma control/status reg */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- plx9080_abort_dma(devpriv->plx9080_mmio, channel);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static int gsc_hpdi_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- writel(0, dev->mmio + BOARD_CONTROL_REG);
- writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
-
- gsc_hpdi_abort_dma(dev, 0);
-
- return 0;
-}
-
-static int gsc_hpdi_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct hpdi_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned long flags;
- u32 bits;
-
- if (s->io_bits)
- return -EINVAL;
-
- writel(RX_FIFO_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
-
- gsc_hpdi_abort_dma(dev, 0);
-
- devpriv->dma_desc_index = 0;
-
- /*
- * These register are supposedly unused during chained dma,
- * but I have found that left over values from last operation
- * occasionally cause problems with transfer of first dma
- * block. Initializing them to zero seems to fix the problem.
- */
- writel(0, devpriv->plx9080_mmio + PLX_REG_DMASIZ0);
- writel(0, devpriv->plx9080_mmio + PLX_REG_DMAPADR0);
- writel(0, devpriv->plx9080_mmio + PLX_REG_DMALADR0);
-
- /* give location of first dma descriptor */
- bits = devpriv->dma_desc_phys_addr | PLX_DMADPR_DESCPCI |
- PLX_DMADPR_TCINTR | PLX_DMADPR_XFERL2P;
- writel(bits, devpriv->plx9080_mmio + PLX_REG_DMADPR0);
-
- /* enable dma transfer */
- spin_lock_irqsave(&dev->spinlock, flags);
- writeb(PLX_DMACSR_ENABLE | PLX_DMACSR_START | PLX_DMACSR_CLEARINTR,
- devpriv->plx9080_mmio + PLX_REG_DMACSR0);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- if (cmd->stop_src == TRIG_COUNT)
- devpriv->dio_count = cmd->stop_arg;
- else
- devpriv->dio_count = 1;
-
- /* clear over/under run status flags */
- writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT, dev->mmio + BOARD_STATUS_REG);
-
- /* enable interrupts */
- writel(RX_FULL_INTR, dev->mmio + INTERRUPT_CONTROL_REG);
-
- writel(RX_ENABLE_BIT, dev->mmio + BOARD_CONTROL_REG);
-
- return 0;
-}
-
-static int gsc_hpdi_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (chan != i) {
- dev_dbg(dev->class_dev,
- "chanlist must be ch 0 to 31 in order\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int gsc_hpdi_cmd_test(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- if (s->io_bits)
- return -EINVAL;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (!cmd->chanlist_len || !cmd->chanlist) {
- cmd->chanlist_len = 32;
- err |= -EINVAL;
- }
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= gsc_hpdi_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-/* setup dma descriptors so a link completes every 'len' bytes */
-static int gsc_hpdi_setup_dma_descriptors(struct comedi_device *dev,
- unsigned int len)
-{
- struct hpdi_private *devpriv = dev->private;
- dma_addr_t phys_addr = devpriv->dma_desc_phys_addr;
- u32 next_bits = PLX_DMADPR_DESCPCI | PLX_DMADPR_TCINTR |
- PLX_DMADPR_XFERL2P;
- unsigned int offset = 0;
- unsigned int idx = 0;
- unsigned int i;
-
- if (len > DMA_BUFFER_SIZE)
- len = DMA_BUFFER_SIZE;
- len -= len % sizeof(u32);
- if (len == 0)
- return -EINVAL;
-
- for (i = 0; i < NUM_DMA_DESCRIPTORS && idx < NUM_DMA_BUFFERS; i++) {
- devpriv->dma_desc[i].pci_start_addr =
- cpu_to_le32(devpriv->dio_buffer_phys_addr[idx] + offset);
- devpriv->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
- devpriv->dma_desc[i].transfer_size = cpu_to_le32(len);
- devpriv->dma_desc[i].next = cpu_to_le32((phys_addr +
- (i + 1) * sizeof(devpriv->dma_desc[0])) | next_bits);
-
- devpriv->desc_dio_buffer[i] = devpriv->dio_buffer[idx] +
- (offset / sizeof(u32));
-
- offset += len;
- if (len + offset > DMA_BUFFER_SIZE) {
- offset = 0;
- idx++;
- }
- }
- devpriv->num_dma_descriptors = i;
- /* fix last descriptor to point back to first */
- devpriv->dma_desc[i - 1].next = cpu_to_le32(phys_addr | next_bits);
-
- devpriv->block_size = len;
-
- return len;
-}
-
-static int gsc_hpdi_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- switch (data[0]) {
- case INSN_CONFIG_BLOCK_SIZE:
- ret = gsc_hpdi_setup_dma_descriptors(dev, data[1]);
- if (ret)
- return ret;
-
- data[1] = ret;
- break;
- default:
- ret = comedi_dio_insn_config(dev, s, insn, data, 0xffffffff);
- if (ret)
- return ret;
- break;
- }
-
- return insn->n;
-}
-
-static void gsc_hpdi_free_dma(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct hpdi_private *devpriv = dev->private;
- int i;
-
- if (!devpriv)
- return;
-
- /* free pci dma buffers */
- for (i = 0; i < NUM_DMA_BUFFERS; i++) {
- if (devpriv->dio_buffer[i])
- dma_free_coherent(&pcidev->dev,
- DMA_BUFFER_SIZE,
- devpriv->dio_buffer[i],
- devpriv->dio_buffer_phys_addr[i]);
- }
- /* free dma descriptors */
- if (devpriv->dma_desc)
- dma_free_coherent(&pcidev->dev,
- sizeof(struct plx_dma_desc) *
- NUM_DMA_DESCRIPTORS,
- devpriv->dma_desc,
- devpriv->dma_desc_phys_addr);
-}
-
-static int gsc_hpdi_init(struct comedi_device *dev)
-{
- struct hpdi_private *devpriv = dev->private;
- u32 plx_intcsr_bits;
-
- /* wait 10usec after reset before accessing fifos */
- writel(BOARD_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
- usleep_range(10, 1000);
-
- writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
- dev->mmio + RX_PROG_ALMOST_REG);
- writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
- dev->mmio + TX_PROG_ALMOST_REG);
-
- devpriv->tx_fifo_size = readl(dev->mmio + TX_FIFO_SIZE_REG) &
- FIFO_SIZE_MASK;
- devpriv->rx_fifo_size = readl(dev->mmio + RX_FIFO_SIZE_REG) &
- FIFO_SIZE_MASK;
-
- writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
-
- /* enable interrupts */
- plx_intcsr_bits =
- PLX_INTCSR_LSEABORTEN | PLX_INTCSR_LSEPARITYEN | PLX_INTCSR_PIEN |
- PLX_INTCSR_PLIEN | PLX_INTCSR_PABORTIEN | PLX_INTCSR_LIOEN |
- PLX_INTCSR_DMA0IEN;
- writel(plx_intcsr_bits, devpriv->plx9080_mmio + PLX_REG_INTCSR);
-
- return 0;
-}
-
-static void gsc_hpdi_init_plx9080(struct comedi_device *dev)
-{
- struct hpdi_private *devpriv = dev->private;
- u32 bits;
- void __iomem *plx_iobase = devpriv->plx9080_mmio;
-
-#ifdef __BIG_ENDIAN
- bits = PLX_BIGEND_DMA0 | PLX_BIGEND_DMA1;
-#else
- bits = 0;
-#endif
- writel(bits, devpriv->plx9080_mmio + PLX_REG_BIGEND);
-
- writel(0, devpriv->plx9080_mmio + PLX_REG_INTCSR);
-
- gsc_hpdi_abort_dma(dev, 0);
- gsc_hpdi_abort_dma(dev, 1);
-
- /* configure dma0 mode */
- bits = 0;
- /* enable ready input */
- bits |= PLX_DMAMODE_READYIEN;
- /* enable dma chaining */
- bits |= PLX_DMAMODE_CHAINEN;
- /*
- * enable interrupt on dma done
- * (probably don't need this, since chain never finishes)
- */
- bits |= PLX_DMAMODE_DONEIEN;
- /*
- * don't increment local address during transfers
- * (we are transferring from a fixed fifo register)
- */
- bits |= PLX_DMAMODE_LACONST;
- /* route dma interrupt to pci bus */
- bits |= PLX_DMAMODE_INTRPCI;
- /* enable demand mode */
- bits |= PLX_DMAMODE_DEMAND;
- /* enable local burst mode */
- bits |= PLX_DMAMODE_BURSTEN;
- bits |= PLX_DMAMODE_WIDTH_32;
- writel(bits, plx_iobase + PLX_REG_DMAMODE0);
-}
-
-static int gsc_hpdi_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct hpdi_private *devpriv;
- struct comedi_subdevice *s;
- int i;
- int retval;
-
- dev->board_name = "pci-hpdi32";
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- retval = comedi_pci_enable(dev);
- if (retval)
- return retval;
- pci_set_master(pcidev);
-
- devpriv->plx9080_mmio = pci_ioremap_bar(pcidev, 0);
- dev->mmio = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->plx9080_mmio || !dev->mmio) {
- dev_warn(dev->class_dev, "failed to remap io memory\n");
- return -ENOMEM;
- }
-
- gsc_hpdi_init_plx9080(dev);
-
- /* get irq */
- if (request_irq(pcidev->irq, gsc_hpdi_interrupt, IRQF_SHARED,
- dev->board_name, dev)) {
- dev_warn(dev->class_dev,
- "unable to allocate irq %u\n", pcidev->irq);
- return -EINVAL;
- }
- dev->irq = pcidev->irq;
-
- dev_dbg(dev->class_dev, " irq %u\n", dev->irq);
-
- /* allocate pci dma buffers */
- for (i = 0; i < NUM_DMA_BUFFERS; i++) {
- devpriv->dio_buffer[i] =
- dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
- &devpriv->dio_buffer_phys_addr[i],
- GFP_KERNEL);
- if (!devpriv->dio_buffer[i]) {
- dev_warn(dev->class_dev,
- "failed to allocate DMA buffer\n");
- return -ENOMEM;
- }
- }
- /* allocate dma descriptors */
- devpriv->dma_desc = dma_alloc_coherent(&pcidev->dev,
- sizeof(struct plx_dma_desc) *
- NUM_DMA_DESCRIPTORS,
- &devpriv->dma_desc_phys_addr,
- GFP_KERNEL);
- if (!devpriv->dma_desc) {
- dev_warn(dev->class_dev,
- "failed to allocate DMA descriptors\n");
- return -ENOMEM;
- }
- if (devpriv->dma_desc_phys_addr & 0xf) {
- dev_warn(dev->class_dev,
- " dma descriptors not quad-word aligned (bug)\n");
- return -EIO;
- }
-
- retval = gsc_hpdi_setup_dma_descriptors(dev, 0x1000);
- if (retval < 0)
- return retval;
-
- retval = comedi_alloc_subdevices(dev, 1);
- if (retval)
- return retval;
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
- SDF_CMD_READ;
- s->n_chan = 32;
- s->len_chanlist = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = gsc_hpdi_dio_insn_config;
- s->do_cmd = gsc_hpdi_cmd;
- s->do_cmdtest = gsc_hpdi_cmd_test;
- s->cancel = gsc_hpdi_cancel;
-
- return gsc_hpdi_init(dev);
-}
-
-static void gsc_hpdi_detach(struct comedi_device *dev)
-{
- struct hpdi_private *devpriv = dev->private;
-
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (devpriv) {
- if (devpriv->plx9080_mmio) {
- writel(0, devpriv->plx9080_mmio + PLX_REG_INTCSR);
- iounmap(devpriv->plx9080_mmio);
- }
- if (dev->mmio)
- iounmap(dev->mmio);
- }
- comedi_pci_disable(dev);
- gsc_hpdi_free_dma(dev);
-}
-
-static struct comedi_driver gsc_hpdi_driver = {
- .driver_name = "gsc_hpdi",
- .module = THIS_MODULE,
- .auto_attach = gsc_hpdi_auto_attach,
- .detach = gsc_hpdi_detach,
-};
-
-static int gsc_hpdi_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &gsc_hpdi_driver, id->driver_data);
-}
-
-static const struct pci_device_id gsc_hpdi_pci_table[] = {
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080,
- PCI_VENDOR_ID_PLX, 0x2400) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, gsc_hpdi_pci_table);
-
-static struct pci_driver gsc_hpdi_pci_driver = {
- .name = "gsc_hpdi",
- .id_table = gsc_hpdi_pci_table,
- .probe = gsc_hpdi_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for General Standards PCI-HPDI32/PMC-HPDI32");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
deleted file mode 100644
index 16d2b78de83c..000000000000
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ /dev/null
@@ -1,336 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * icp_multi.c
- * Comedi driver for Inova ICP_MULTI board
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2002 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: icp_multi
- * Description: Inova ICP_MULTI
- * Devices: [Inova] ICP_MULTI (icp_multi)
- * Author: Anne Smorthit <anne.smorthit@sfwte.ch>
- * Status: works
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * The driver works for analog input and output and digital input and
- * output. It does not work with interrupts or with the counters. Currently
- * no support for DMA.
- *
- * It has 16 single-ended or 8 differential Analogue Input channels with
- * 12-bit resolution. Ranges : 5V, 10V, +/-5V, +/-10V, 0..20mA and 4..20mA.
- * Input ranges can be individually programmed for each channel. Voltage or
- * current measurement is selected by jumper.
- *
- * There are 4 x 12-bit Analogue Outputs. Ranges : 5V, 10V, +/-5V, +/-10V
- *
- * 16 x Digital Inputs, 24V
- *
- * 8 x Digital Outputs, 24V, 1A
- *
- * 4 x 16-bit counters - not implemented
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedi_pci.h"
-
-#define ICP_MULTI_ADC_CSR 0x00 /* R/W: ADC command/status register */
-#define ICP_MULTI_ADC_CSR_ST BIT(0) /* Start ADC */
-#define ICP_MULTI_ADC_CSR_BSY BIT(0) /* ADC busy */
-#define ICP_MULTI_ADC_CSR_BI BIT(4) /* Bipolar input range */
-#define ICP_MULTI_ADC_CSR_RA BIT(5) /* Input range 0 = 5V, 1 = 10V */
-#define ICP_MULTI_ADC_CSR_DI BIT(6) /* Input mode 1 = differential */
-#define ICP_MULTI_ADC_CSR_DI_CHAN(x) (((x) & 0x7) << 9)
-#define ICP_MULTI_ADC_CSR_SE_CHAN(x) (((x) & 0xf) << 8)
-#define ICP_MULTI_AI 2 /* R: Analogue input data */
-#define ICP_MULTI_DAC_CSR 0x04 /* R/W: DAC command/status register */
-#define ICP_MULTI_DAC_CSR_ST BIT(0) /* Start DAC */
-#define ICP_MULTI_DAC_CSR_BSY BIT(0) /* DAC busy */
-#define ICP_MULTI_DAC_CSR_BI BIT(4) /* Bipolar output range */
-#define ICP_MULTI_DAC_CSR_RA BIT(5) /* Output range 0 = 5V, 1 = 10V */
-#define ICP_MULTI_DAC_CSR_CHAN(x) (((x) & 0x3) << 8)
-#define ICP_MULTI_AO 6 /* R/W: Analogue output data */
-#define ICP_MULTI_DI 8 /* R/W: Digital inputs */
-#define ICP_MULTI_DO 0x0A /* R/W: Digital outputs */
-#define ICP_MULTI_INT_EN 0x0c /* R/W: Interrupt enable register */
-#define ICP_MULTI_INT_STAT 0x0e /* R/W: Interrupt status register */
-#define ICP_MULTI_INT_ADC_RDY BIT(0) /* A/D conversion ready interrupt */
-#define ICP_MULTI_INT_DAC_RDY BIT(1) /* D/A conversion ready interrupt */
-#define ICP_MULTI_INT_DOUT_ERR BIT(2) /* Digital output error interrupt */
-#define ICP_MULTI_INT_DIN_STAT BIT(3) /* Digital input status change int. */
-#define ICP_MULTI_INT_CIE0 BIT(4) /* Counter 0 overrun interrupt */
-#define ICP_MULTI_INT_CIE1 BIT(5) /* Counter 1 overrun interrupt */
-#define ICP_MULTI_INT_CIE2 BIT(6) /* Counter 2 overrun interrupt */
-#define ICP_MULTI_INT_CIE3 BIT(7) /* Counter 3 overrun interrupt */
-#define ICP_MULTI_INT_MASK 0xff /* All interrupts */
-#define ICP_MULTI_CNTR0 0x10 /* R/W: Counter 0 */
-#define ICP_MULTI_CNTR1 0x12 /* R/W: counter 1 */
-#define ICP_MULTI_CNTR2 0x14 /* R/W: Counter 2 */
-#define ICP_MULTI_CNTR3 0x16 /* R/W: Counter 3 */
-
-/* analog input and output have the same range options */
-static const struct comedi_lrange icp_multi_ranges = {
- 4, {
- UNI_RANGE(5),
- UNI_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(10)
- }
-};
-
-static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
-
-static int icp_multi_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = readw(dev->mmio + ICP_MULTI_ADC_CSR);
- if ((status & ICP_MULTI_ADC_CSR_BSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int icp_multi_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- unsigned int adc_csr;
- int ret = 0;
- int n;
-
- /* Set mode and range data for specified channel */
- if (aref == AREF_DIFF) {
- adc_csr = ICP_MULTI_ADC_CSR_DI_CHAN(chan) |
- ICP_MULTI_ADC_CSR_DI;
- } else {
- adc_csr = ICP_MULTI_ADC_CSR_SE_CHAN(chan);
- }
- adc_csr |= range_codes_analog[range];
- writew(adc_csr, dev->mmio + ICP_MULTI_ADC_CSR);
-
- for (n = 0; n < insn->n; n++) {
- /* Set start ADC bit */
- writew(adc_csr | ICP_MULTI_ADC_CSR_ST,
- dev->mmio + ICP_MULTI_ADC_CSR);
-
- udelay(1);
-
- /* Wait for conversion to complete, or get fed up waiting */
- ret = comedi_timeout(dev, s, insn, icp_multi_ai_eoc, 0);
- if (ret)
- break;
-
- data[n] = (readw(dev->mmio + ICP_MULTI_AI) >> 4) & 0x0fff;
- }
-
- return ret ? ret : n;
-}
-
-static int icp_multi_ao_ready(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = readw(dev->mmio + ICP_MULTI_DAC_CSR);
- if ((status & ICP_MULTI_DAC_CSR_BSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int icp_multi_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int dac_csr;
- int i;
-
- /* Select channel and range */
- dac_csr = ICP_MULTI_DAC_CSR_CHAN(chan);
- dac_csr |= range_codes_analog[range];
- writew(dac_csr, dev->mmio + ICP_MULTI_DAC_CSR);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
- int ret;
-
- /* Wait for analog output to be ready for new data */
- ret = comedi_timeout(dev, s, insn, icp_multi_ao_ready, 0);
- if (ret)
- return ret;
-
- writew(val, dev->mmio + ICP_MULTI_AO);
-
- /* Set start conversion bit to write data to channel */
- writew(dac_csr | ICP_MULTI_DAC_CSR_ST,
- dev->mmio + ICP_MULTI_DAC_CSR);
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int icp_multi_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = readw(dev->mmio + ICP_MULTI_DI);
-
- return insn->n;
-}
-
-static int icp_multi_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- writew(s->state, dev->mmio + ICP_MULTI_DO);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int icp_multi_reset(struct comedi_device *dev)
-{
- int i;
-
- /* Disable all interrupts and clear any requests */
- writew(0, dev->mmio + ICP_MULTI_INT_EN);
- writew(ICP_MULTI_INT_MASK, dev->mmio + ICP_MULTI_INT_STAT);
-
- /* Reset the analog output channels to 0V */
- for (i = 0; i < 4; i++) {
- unsigned int dac_csr = ICP_MULTI_DAC_CSR_CHAN(i);
-
- /* Select channel and 0..5V range */
- writew(dac_csr, dev->mmio + ICP_MULTI_DAC_CSR);
-
- /* Output 0V */
- writew(0, dev->mmio + ICP_MULTI_AO);
-
- /* Set start conversion bit to write data to channel */
- writew(dac_csr | ICP_MULTI_DAC_CSR_ST,
- dev->mmio + ICP_MULTI_DAC_CSR);
- udelay(1);
- }
-
- /* Digital outputs to 0 */
- writew(0, dev->mmio + ICP_MULTI_DO);
-
- return 0;
-}
-
-static int icp_multi_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 2);
- if (!dev->mmio)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- icp_multi_reset(dev);
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = 0x0fff;
- s->range_table = &icp_multi_ranges;
- s->insn_read = icp_multi_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
- s->n_chan = 4;
- s->maxdata = 0x0fff;
- s->range_table = &icp_multi_ranges;
- s->insn_write = icp_multi_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = icp_multi_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = icp_multi_do_insn_bits;
-
- return 0;
-}
-
-static struct comedi_driver icp_multi_driver = {
- .driver_name = "icp_multi",
- .module = THIS_MODULE,
- .auto_attach = icp_multi_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int icp_multi_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &icp_multi_driver, id->driver_data);
-}
-
-static const struct pci_device_id icp_multi_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ICP, 0x8000) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, icp_multi_pci_table);
-
-static struct pci_driver icp_multi_pci_driver = {
- .name = "icp_multi",
- .id_table = icp_multi_pci_table,
- .probe = icp_multi_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(icp_multi_driver, icp_multi_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Inova ICP_MULTI board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
deleted file mode 100644
index 399255dbe388..000000000000
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ /dev/null
@@ -1,524 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * ii_pci20kc.c
- * Driver for Intelligent Instruments PCI-20001C carrier board and modules.
- *
- * Copyright (C) 2000 Markus Kempf <kempf@matsci.uni-sb.de>
- * with suggestions from David Schleef 16.06.2000
- */
-
-/*
- * Driver: ii_pci20kc
- * Description: Intelligent Instruments PCI-20001C carrier board
- * Devices: [Intelligent Instrumentation] PCI-20001C (ii_pci20kc)
- * Author: Markus Kempf <kempf@matsci.uni-sb.de>
- * Status: works
- *
- * Supports the PCI-20001C-1a and PCI-20001C-2a carrier boards. The
- * -2a version has 32 on-board DIO channels. Three add-on modules
- * can be added to the carrier board for additional functionality.
- *
- * Supported add-on modules:
- * PCI-20006M-1 1 channel, 16-bit analog output module
- * PCI-20006M-2 2 channel, 16-bit analog output module
- * PCI-20341M-1A 4 channel, 16-bit analog input module
- *
- * Options:
- * 0 Board base address
- * 1 IRQ (not-used)
- */
-
-#include <linux/module.h>
-#include <linux/io.h>
-#include "../comedidev.h"
-
-/*
- * Register I/O map
- */
-#define II20K_SIZE 0x400
-#define II20K_MOD_OFFSET 0x100
-#define II20K_ID_REG 0x00
-#define II20K_ID_MOD1_EMPTY BIT(7)
-#define II20K_ID_MOD2_EMPTY BIT(6)
-#define II20K_ID_MOD3_EMPTY BIT(5)
-#define II20K_ID_MASK 0x1f
-#define II20K_ID_PCI20001C_1A 0x1b /* no on-board DIO */
-#define II20K_ID_PCI20001C_2A 0x1d /* on-board DIO */
-#define II20K_MOD_STATUS_REG 0x40
-#define II20K_MOD_STATUS_IRQ_MOD1 BIT(7)
-#define II20K_MOD_STATUS_IRQ_MOD2 BIT(6)
-#define II20K_MOD_STATUS_IRQ_MOD3 BIT(5)
-#define II20K_DIO0_REG 0x80
-#define II20K_DIO1_REG 0x81
-#define II20K_DIR_ENA_REG 0x82
-#define II20K_DIR_DIO3_OUT BIT(7)
-#define II20K_DIR_DIO2_OUT BIT(6)
-#define II20K_BUF_DISAB_DIO3 BIT(5)
-#define II20K_BUF_DISAB_DIO2 BIT(4)
-#define II20K_DIR_DIO1_OUT BIT(3)
-#define II20K_DIR_DIO0_OUT BIT(2)
-#define II20K_BUF_DISAB_DIO1 BIT(1)
-#define II20K_BUF_DISAB_DIO0 BIT(0)
-#define II20K_CTRL01_REG 0x83
-#define II20K_CTRL01_SET BIT(7)
-#define II20K_CTRL01_DIO0_IN BIT(4)
-#define II20K_CTRL01_DIO1_IN BIT(1)
-#define II20K_DIO2_REG 0xc0
-#define II20K_DIO3_REG 0xc1
-#define II20K_CTRL23_REG 0xc3
-#define II20K_CTRL23_SET BIT(7)
-#define II20K_CTRL23_DIO2_IN BIT(4)
-#define II20K_CTRL23_DIO3_IN BIT(1)
-
-#define II20K_ID_PCI20006M_1 0xe2 /* 1 AO channels */
-#define II20K_ID_PCI20006M_2 0xe3 /* 2 AO channels */
-#define II20K_AO_STRB_REG(x) (0x0b + ((x) * 0x08))
-#define II20K_AO_LSB_REG(x) (0x0d + ((x) * 0x08))
-#define II20K_AO_MSB_REG(x) (0x0e + ((x) * 0x08))
-#define II20K_AO_STRB_BOTH_REG 0x1b
-
-#define II20K_ID_PCI20341M_1 0x77 /* 4 AI channels */
-#define II20K_AI_STATUS_CMD_REG 0x01
-#define II20K_AI_STATUS_CMD_BUSY BIT(7)
-#define II20K_AI_STATUS_CMD_HW_ENA BIT(1)
-#define II20K_AI_STATUS_CMD_EXT_START BIT(0)
-#define II20K_AI_LSB_REG 0x02
-#define II20K_AI_MSB_REG 0x03
-#define II20K_AI_PACER_RESET_REG 0x04
-#define II20K_AI_16BIT_DATA_REG 0x06
-#define II20K_AI_CONF_REG 0x10
-#define II20K_AI_CONF_ENA BIT(2)
-#define II20K_AI_OPT_REG 0x11
-#define II20K_AI_OPT_TRIG_ENA BIT(5)
-#define II20K_AI_OPT_TRIG_INV BIT(4)
-#define II20K_AI_OPT_TIMEBASE(x) (((x) & 0x3) << 1)
-#define II20K_AI_OPT_BURST_MODE BIT(0)
-#define II20K_AI_STATUS_REG 0x12
-#define II20K_AI_STATUS_INT BIT(7)
-#define II20K_AI_STATUS_TRIG BIT(6)
-#define II20K_AI_STATUS_TRIG_ENA BIT(5)
-#define II20K_AI_STATUS_PACER_ERR BIT(2)
-#define II20K_AI_STATUS_DATA_ERR BIT(1)
-#define II20K_AI_STATUS_SET_TIME_ERR BIT(0)
-#define II20K_AI_LAST_CHAN_ADDR_REG 0x13
-#define II20K_AI_CUR_ADDR_REG 0x14
-#define II20K_AI_SET_TIME_REG 0x15
-#define II20K_AI_DELAY_LSB_REG 0x16
-#define II20K_AI_DELAY_MSB_REG 0x17
-#define II20K_AI_CHAN_ADV_REG 0x18
-#define II20K_AI_CHAN_RESET_REG 0x19
-#define II20K_AI_START_TRIG_REG 0x1a
-#define II20K_AI_COUNT_RESET_REG 0x1b
-#define II20K_AI_CHANLIST_REG 0x80
-#define II20K_AI_CHANLIST_ONBOARD_ONLY BIT(5)
-#define II20K_AI_CHANLIST_GAIN(x) (((x) & 0x3) << 3)
-#define II20K_AI_CHANLIST_MUX_ENA BIT(2)
-#define II20K_AI_CHANLIST_CHAN(x) (((x) & 0x3) << 0)
-#define II20K_AI_CHANLIST_LEN 0x80
-
-/* the AO range is set by jumpers on the 20006M module */
-static const struct comedi_lrange ii20k_ao_ranges = {
- 3, {
- BIP_RANGE(5), /* Chan 0 - W1/W3 in Chan 1 - W2/W4 in */
- UNI_RANGE(10), /* Chan 0 - W1/W3 out Chan 1 - W2/W4 in */
- BIP_RANGE(10) /* Chan 0 - W1/W3 in Chan 1 - W2/W4 out */
- }
-};
-
-static const struct comedi_lrange ii20k_ai_ranges = {
- 4, {
- BIP_RANGE(5), /* gain 1 */
- BIP_RANGE(0.5), /* gain 10 */
- BIP_RANGE(0.05), /* gain 100 */
- BIP_RANGE(0.025) /* gain 200 */
- },
-};
-
-static void __iomem *ii20k_module_iobase(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- return dev->mmio + (s->index + 1) * II20K_MOD_OFFSET;
-}
-
-static int ii20k_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- void __iomem *iobase = ii20k_module_iobase(dev, s);
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- /* munge the offset binary data to 2's complement */
- val = comedi_offset_munge(s, val);
-
- writeb(val & 0xff, iobase + II20K_AO_LSB_REG(chan));
- writeb((val >> 8) & 0xff, iobase + II20K_AO_MSB_REG(chan));
- writeb(0x00, iobase + II20K_AO_STRB_REG(chan));
- }
-
- return insn->n;
-}
-
-static int ii20k_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- void __iomem *iobase = ii20k_module_iobase(dev, s);
- unsigned char status;
-
- status = readb(iobase + II20K_AI_STATUS_REG);
- if ((status & II20K_AI_STATUS_INT) == 0)
- return 0;
- return -EBUSY;
-}
-
-static void ii20k_ai_setup(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chanspec)
-{
- void __iomem *iobase = ii20k_module_iobase(dev, s);
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned char val;
-
- /* initialize module */
- writeb(II20K_AI_CONF_ENA, iobase + II20K_AI_CONF_REG);
-
- /* software conversion */
- writeb(0, iobase + II20K_AI_STATUS_CMD_REG);
-
- /* set the time base for the settling time counter based on the gain */
- val = (range < 3) ? II20K_AI_OPT_TIMEBASE(0) : II20K_AI_OPT_TIMEBASE(2);
- writeb(val, iobase + II20K_AI_OPT_REG);
-
- /* set the settling time counter based on the gain */
- val = (range < 2) ? 0x58 : (range < 3) ? 0x93 : 0x99;
- writeb(val, iobase + II20K_AI_SET_TIME_REG);
-
- /* set number of input channels */
- writeb(1, iobase + II20K_AI_LAST_CHAN_ADDR_REG);
-
- /* set the channel list byte */
- val = II20K_AI_CHANLIST_ONBOARD_ONLY |
- II20K_AI_CHANLIST_MUX_ENA |
- II20K_AI_CHANLIST_GAIN(range) |
- II20K_AI_CHANLIST_CHAN(chan);
- writeb(val, iobase + II20K_AI_CHANLIST_REG);
-
- /* reset settling time counter and trigger delay counter */
- writeb(0, iobase + II20K_AI_COUNT_RESET_REG);
-
- /* reset channel scanner */
- writeb(0, iobase + II20K_AI_CHAN_RESET_REG);
-}
-
-static int ii20k_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- void __iomem *iobase = ii20k_module_iobase(dev, s);
- int ret;
- int i;
-
- ii20k_ai_setup(dev, s, insn->chanspec);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val;
-
- /* generate a software start convert signal */
- readb(iobase + II20K_AI_PACER_RESET_REG);
-
- ret = comedi_timeout(dev, s, insn, ii20k_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = readb(iobase + II20K_AI_LSB_REG);
- val |= (readb(iobase + II20K_AI_MSB_REG) << 8);
-
- /* munge the 2's complement data to offset binary */
- data[i] = comedi_offset_munge(s, val);
- }
-
- return insn->n;
-}
-
-static void ii20k_dio_config(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned char ctrl01 = 0;
- unsigned char ctrl23 = 0;
- unsigned char dir_ena = 0;
-
- /* port 0 - channels 0-7 */
- if (s->io_bits & 0x000000ff) {
- /* output port */
- ctrl01 &= ~II20K_CTRL01_DIO0_IN;
- dir_ena &= ~II20K_BUF_DISAB_DIO0;
- dir_ena |= II20K_DIR_DIO0_OUT;
- } else {
- /* input port */
- ctrl01 |= II20K_CTRL01_DIO0_IN;
- dir_ena &= ~II20K_DIR_DIO0_OUT;
- }
-
- /* port 1 - channels 8-15 */
- if (s->io_bits & 0x0000ff00) {
- /* output port */
- ctrl01 &= ~II20K_CTRL01_DIO1_IN;
- dir_ena &= ~II20K_BUF_DISAB_DIO1;
- dir_ena |= II20K_DIR_DIO1_OUT;
- } else {
- /* input port */
- ctrl01 |= II20K_CTRL01_DIO1_IN;
- dir_ena &= ~II20K_DIR_DIO1_OUT;
- }
-
- /* port 2 - channels 16-23 */
- if (s->io_bits & 0x00ff0000) {
- /* output port */
- ctrl23 &= ~II20K_CTRL23_DIO2_IN;
- dir_ena &= ~II20K_BUF_DISAB_DIO2;
- dir_ena |= II20K_DIR_DIO2_OUT;
- } else {
- /* input port */
- ctrl23 |= II20K_CTRL23_DIO2_IN;
- dir_ena &= ~II20K_DIR_DIO2_OUT;
- }
-
- /* port 3 - channels 24-31 */
- if (s->io_bits & 0xff000000) {
- /* output port */
- ctrl23 &= ~II20K_CTRL23_DIO3_IN;
- dir_ena &= ~II20K_BUF_DISAB_DIO3;
- dir_ena |= II20K_DIR_DIO3_OUT;
- } else {
- /* input port */
- ctrl23 |= II20K_CTRL23_DIO3_IN;
- dir_ena &= ~II20K_DIR_DIO3_OUT;
- }
-
- ctrl23 |= II20K_CTRL01_SET;
- ctrl23 |= II20K_CTRL23_SET;
-
- /* order is important */
- writeb(ctrl01, dev->mmio + II20K_CTRL01_REG);
- writeb(ctrl23, dev->mmio + II20K_CTRL23_REG);
- writeb(dir_ena, dev->mmio + II20K_DIR_ENA_REG);
-}
-
-static int ii20k_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x000000ff;
- else if (chan < 16)
- mask = 0x0000ff00;
- else if (chan < 24)
- mask = 0x00ff0000;
- else
- mask = 0xff000000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- ii20k_dio_config(dev, s);
-
- return insn->n;
-}
-
-static int ii20k_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0x000000ff)
- writeb((s->state >> 0) & 0xff,
- dev->mmio + II20K_DIO0_REG);
- if (mask & 0x0000ff00)
- writeb((s->state >> 8) & 0xff,
- dev->mmio + II20K_DIO1_REG);
- if (mask & 0x00ff0000)
- writeb((s->state >> 16) & 0xff,
- dev->mmio + II20K_DIO2_REG);
- if (mask & 0xff000000)
- writeb((s->state >> 24) & 0xff,
- dev->mmio + II20K_DIO3_REG);
- }
-
- data[1] = readb(dev->mmio + II20K_DIO0_REG);
- data[1] |= readb(dev->mmio + II20K_DIO1_REG) << 8;
- data[1] |= readb(dev->mmio + II20K_DIO2_REG) << 16;
- data[1] |= readb(dev->mmio + II20K_DIO3_REG) << 24;
-
- return insn->n;
-}
-
-static int ii20k_init_module(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- void __iomem *iobase = ii20k_module_iobase(dev, s);
- unsigned char id;
- int ret;
-
- id = readb(iobase + II20K_ID_REG);
- switch (id) {
- case II20K_ID_PCI20006M_1:
- case II20K_ID_PCI20006M_2:
- /* Analog Output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = (id == II20K_ID_PCI20006M_2) ? 2 : 1;
- s->maxdata = 0xffff;
- s->range_table = &ii20k_ao_ranges;
- s->insn_write = ii20k_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- break;
- case II20K_ID_PCI20341M_1:
- /* Analog Input subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->range_table = &ii20k_ai_ranges;
- s->insn_read = ii20k_ai_insn_read;
- break;
- default:
- s->type = COMEDI_SUBD_UNUSED;
- break;
- }
-
- return 0;
-}
-
-static int ii20k_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- unsigned int membase;
- unsigned char id;
- bool has_dio;
- int ret;
-
- membase = it->options[0];
- if (!membase || (membase & ~(0x100000 - II20K_SIZE))) {
- dev_warn(dev->class_dev,
- "%s: invalid memory address specified\n",
- dev->board_name);
- return -EINVAL;
- }
-
- if (!request_mem_region(membase, II20K_SIZE, dev->board_name)) {
- dev_warn(dev->class_dev, "%s: I/O mem conflict (%#x,%u)\n",
- dev->board_name, membase, II20K_SIZE);
- return -EIO;
- }
- dev->iobase = membase; /* actually, a memory address */
-
- dev->mmio = ioremap(membase, II20K_SIZE);
- if (!dev->mmio)
- return -ENOMEM;
-
- id = readb(dev->mmio + II20K_ID_REG);
- switch (id & II20K_ID_MASK) {
- case II20K_ID_PCI20001C_1A:
- has_dio = false;
- break;
- case II20K_ID_PCI20001C_2A:
- has_dio = true;
- break;
- default:
- return -ENODEV;
- }
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- if (id & II20K_ID_MOD1_EMPTY) {
- s->type = COMEDI_SUBD_UNUSED;
- } else {
- ret = ii20k_init_module(dev, s);
- if (ret)
- return ret;
- }
-
- s = &dev->subdevices[1];
- if (id & II20K_ID_MOD2_EMPTY) {
- s->type = COMEDI_SUBD_UNUSED;
- } else {
- ret = ii20k_init_module(dev, s);
- if (ret)
- return ret;
- }
-
- s = &dev->subdevices[2];
- if (id & II20K_ID_MOD3_EMPTY) {
- s->type = COMEDI_SUBD_UNUSED;
- } else {
- ret = ii20k_init_module(dev, s);
- if (ret)
- return ret;
- }
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[3];
- if (has_dio) {
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ii20k_dio_insn_bits;
- s->insn_config = ii20k_dio_insn_config;
-
- /* default all channels to input */
- ii20k_dio_config(dev, s);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- return 0;
-}
-
-static void ii20k_detach(struct comedi_device *dev)
-{
- if (dev->mmio)
- iounmap(dev->mmio);
- if (dev->iobase) /* actually, a memory address */
- release_mem_region(dev->iobase, II20K_SIZE);
-}
-
-static struct comedi_driver ii20k_driver = {
- .driver_name = "ii_pci20kc",
- .module = THIS_MODULE,
- .attach = ii20k_attach,
- .detach = ii20k_detach,
-};
-module_comedi_driver(ii20k_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Intelligent Instruments PCI-20001C");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
deleted file mode 100644
index 7a02c4fa3cda..000000000000
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ /dev/null
@@ -1,816 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/jr3_pci.c
- * hardware driver for JR3/PCI force sensor board
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2007 Anders Blomdell <anders.blomdell@control.lth.se>
- */
-/*
- * Driver: jr3_pci
- * Description: JR3/PCI force sensor board
- * Author: Anders Blomdell <anders.blomdell@control.lth.se>
- * Updated: Thu, 01 Nov 2012 17:34:55 +0000
- * Status: works
- * Devices: [JR3] PCI force sensor board (jr3_pci)
- *
- * Configuration options:
- * None
- *
- * Manual configuration of comedi devices is not supported by this
- * driver; supported PCI devices are configured as comedi devices
- * automatically.
- *
- * The DSP on the board requires initialization code, which can be
- * loaded by placing it in /lib/firmware/comedi. The initialization
- * code should be somewhere on the media you got with your card. One
- * version is available from https://www.comedi.org in the
- * comedi_nonfree_firmware tarball. The file is called "jr3pci.idm".
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
-
-#include "../comedi_pci.h"
-
-#include "jr3_pci.h"
-
-#define PCI_VENDOR_ID_JR3 0x1762
-
-enum jr3_pci_boardid {
- BOARD_JR3_1,
- BOARD_JR3_2,
- BOARD_JR3_3,
- BOARD_JR3_4,
-};
-
-struct jr3_pci_board {
- const char *name;
- int n_subdevs;
-};
-
-static const struct jr3_pci_board jr3_pci_boards[] = {
- [BOARD_JR3_1] = {
- .name = "jr3_pci_1",
- .n_subdevs = 1,
- },
- [BOARD_JR3_2] = {
- .name = "jr3_pci_2",
- .n_subdevs = 2,
- },
- [BOARD_JR3_3] = {
- .name = "jr3_pci_3",
- .n_subdevs = 3,
- },
- [BOARD_JR3_4] = {
- .name = "jr3_pci_4",
- .n_subdevs = 4,
- },
-};
-
-struct jr3_pci_transform {
- struct {
- u16 link_type;
- s16 link_amount;
- } link[8];
-};
-
-struct jr3_pci_poll_delay {
- int min;
- int max;
-};
-
-struct jr3_pci_dev_private {
- struct timer_list timer;
- struct comedi_device *dev;
-};
-
-union jr3_pci_single_range {
- struct comedi_lrange l;
- char _reserved[offsetof(struct comedi_lrange, range[1])];
-};
-
-enum jr3_pci_poll_state {
- state_jr3_poll,
- state_jr3_init_wait_for_offset,
- state_jr3_init_transform_complete,
- state_jr3_init_set_full_scale_complete,
- state_jr3_init_use_offset_complete,
- state_jr3_done
-};
-
-struct jr3_pci_subdev_private {
- struct jr3_sensor __iomem *sensor;
- unsigned long next_time_min;
- enum jr3_pci_poll_state state;
- int serial_no;
- int model_no;
- union jr3_pci_single_range range[9];
- const struct comedi_lrange *range_table_list[8 * 7 + 2];
- unsigned int maxdata_list[8 * 7 + 2];
- u16 errors;
- int retries;
-};
-
-static struct jr3_pci_poll_delay poll_delay_min_max(int min, int max)
-{
- struct jr3_pci_poll_delay result;
-
- result.min = min;
- result.max = max;
- return result;
-}
-
-static int is_complete(struct jr3_sensor __iomem *sensor)
-{
- return get_s16(&sensor->command_word0) == 0;
-}
-
-static void set_transforms(struct jr3_sensor __iomem *sensor,
- const struct jr3_pci_transform *transf, short num)
-{
- int i;
-
- num &= 0x000f; /* Make sure that 0 <= num <= 15 */
- for (i = 0; i < 8; i++) {
- set_u16(&sensor->transforms[num].link[i].link_type,
- transf->link[i].link_type);
- udelay(1);
- set_s16(&sensor->transforms[num].link[i].link_amount,
- transf->link[i].link_amount);
- udelay(1);
- if (transf->link[i].link_type == end_x_form)
- break;
- }
-}
-
-static void use_transform(struct jr3_sensor __iomem *sensor,
- short transf_num)
-{
- set_s16(&sensor->command_word0, 0x0500 + (transf_num & 0x000f));
-}
-
-static void use_offset(struct jr3_sensor __iomem *sensor, short offset_num)
-{
- set_s16(&sensor->command_word0, 0x0600 + (offset_num & 0x000f));
-}
-
-static void set_offset(struct jr3_sensor __iomem *sensor)
-{
- set_s16(&sensor->command_word0, 0x0700);
-}
-
-struct six_axis_t {
- s16 fx;
- s16 fy;
- s16 fz;
- s16 mx;
- s16 my;
- s16 mz;
-};
-
-static void set_full_scales(struct jr3_sensor __iomem *sensor,
- struct six_axis_t full_scale)
-{
- set_s16(&sensor->full_scale.fx, full_scale.fx);
- set_s16(&sensor->full_scale.fy, full_scale.fy);
- set_s16(&sensor->full_scale.fz, full_scale.fz);
- set_s16(&sensor->full_scale.mx, full_scale.mx);
- set_s16(&sensor->full_scale.my, full_scale.my);
- set_s16(&sensor->full_scale.mz, full_scale.mz);
- set_s16(&sensor->command_word0, 0x0a00);
-}
-
-static struct six_axis_t get_min_full_scales(struct jr3_sensor __iomem *sensor)
-{
- struct six_axis_t result;
-
- result.fx = get_s16(&sensor->min_full_scale.fx);
- result.fy = get_s16(&sensor->min_full_scale.fy);
- result.fz = get_s16(&sensor->min_full_scale.fz);
- result.mx = get_s16(&sensor->min_full_scale.mx);
- result.my = get_s16(&sensor->min_full_scale.my);
- result.mz = get_s16(&sensor->min_full_scale.mz);
- return result;
-}
-
-static struct six_axis_t get_max_full_scales(struct jr3_sensor __iomem *sensor)
-{
- struct six_axis_t result;
-
- result.fx = get_s16(&sensor->max_full_scale.fx);
- result.fy = get_s16(&sensor->max_full_scale.fy);
- result.fz = get_s16(&sensor->max_full_scale.fz);
- result.mx = get_s16(&sensor->max_full_scale.mx);
- result.my = get_s16(&sensor->max_full_scale.my);
- result.mz = get_s16(&sensor->max_full_scale.mz);
- return result;
-}
-
-static unsigned int jr3_pci_ai_read_chan(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chan)
-{
- struct jr3_pci_subdev_private *spriv = s->private;
- unsigned int val = 0;
-
- if (spriv->state != state_jr3_done)
- return 0;
-
- if (chan < 56) {
- unsigned int axis = chan % 8;
- unsigned int filter = chan / 8;
-
- switch (axis) {
- case 0:
- val = get_s16(&spriv->sensor->filter[filter].fx);
- break;
- case 1:
- val = get_s16(&spriv->sensor->filter[filter].fy);
- break;
- case 2:
- val = get_s16(&spriv->sensor->filter[filter].fz);
- break;
- case 3:
- val = get_s16(&spriv->sensor->filter[filter].mx);
- break;
- case 4:
- val = get_s16(&spriv->sensor->filter[filter].my);
- break;
- case 5:
- val = get_s16(&spriv->sensor->filter[filter].mz);
- break;
- case 6:
- val = get_s16(&spriv->sensor->filter[filter].v1);
- break;
- case 7:
- val = get_s16(&spriv->sensor->filter[filter].v2);
- break;
- }
- val += 0x4000;
- } else if (chan == 56) {
- val = get_u16(&spriv->sensor->model_no);
- } else if (chan == 57) {
- val = get_u16(&spriv->sensor->serial_no);
- }
-
- return val;
-}
-
-static int jr3_pci_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct jr3_pci_subdev_private *spriv = s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- u16 errors;
- int i;
-
- errors = get_u16(&spriv->sensor->errors);
- if (spriv->state != state_jr3_done ||
- (errors & (watch_dog | watch_dog2 | sensor_change))) {
- /* No sensor or sensor changed */
- if (spriv->state == state_jr3_done) {
- /* Restart polling */
- spriv->state = state_jr3_poll;
- }
- return -EAGAIN;
- }
-
- for (i = 0; i < insn->n; i++)
- data[i] = jr3_pci_ai_read_chan(dev, s, chan);
-
- return insn->n;
-}
-
-static int jr3_pci_open(struct comedi_device *dev)
-{
- struct jr3_pci_subdev_private *spriv;
- struct comedi_subdevice *s;
- int i;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- spriv = s->private;
- dev_dbg(dev->class_dev, "serial[%d]: %d\n", s->index,
- spriv->serial_no);
- }
- return 0;
-}
-
-static int read_idm_word(const u8 *data, size_t size, int *pos,
- unsigned int *val)
-{
- int result = 0;
- int value;
-
- if (pos && val) {
- /* Skip over non hex */
- for (; *pos < size && !isxdigit(data[*pos]); (*pos)++)
- ;
- /* Collect value */
- *val = 0;
- for (; *pos < size; (*pos)++) {
- value = hex_to_bin(data[*pos]);
- if (value >= 0) {
- result = 1;
- *val = (*val << 4) + value;
- } else {
- break;
- }
- }
- }
- return result;
-}
-
-static int jr3_check_firmware(struct comedi_device *dev,
- const u8 *data, size_t size)
-{
- int more = 1;
- int pos = 0;
-
- /*
- * IDM file format is:
- * { count, address, data <count> } *
- * ffff
- */
- while (more) {
- unsigned int count = 0;
- unsigned int addr = 0;
-
- more = more && read_idm_word(data, size, &pos, &count);
- if (more && count == 0xffff)
- return 0;
-
- more = more && read_idm_word(data, size, &pos, &addr);
- while (more && count > 0) {
- unsigned int dummy = 0;
-
- more = more && read_idm_word(data, size, &pos, &dummy);
- count--;
- }
- }
-
- return -ENODATA;
-}
-
-static void jr3_write_firmware(struct comedi_device *dev,
- int subdev, const u8 *data, size_t size)
-{
- struct jr3_block __iomem *block = dev->mmio;
- u32 __iomem *lo;
- u32 __iomem *hi;
- int more = 1;
- int pos = 0;
-
- while (more) {
- unsigned int count = 0;
- unsigned int addr = 0;
-
- more = more && read_idm_word(data, size, &pos, &count);
- if (more && count == 0xffff)
- return;
-
- more = more && read_idm_word(data, size, &pos, &addr);
-
- dev_dbg(dev->class_dev, "Loading#%d %4.4x bytes at %4.4x\n",
- subdev, count, addr);
-
- while (more && count > 0) {
- if (addr & 0x4000) {
- /* 16 bit data, never seen in real life!! */
- unsigned int data1 = 0;
-
- more = more &&
- read_idm_word(data, size, &pos, &data1);
- count--;
- /* jr3[addr + 0x20000 * pnum] = data1; */
- } else {
- /* Download 24 bit program */
- unsigned int data1 = 0;
- unsigned int data2 = 0;
-
- lo = &block[subdev].program_lo[addr];
- hi = &block[subdev].program_hi[addr];
-
- more = more &&
- read_idm_word(data, size, &pos, &data1);
- more = more &&
- read_idm_word(data, size, &pos, &data2);
- count -= 2;
- if (more) {
- set_u16(lo, data1);
- udelay(1);
- set_u16(hi, data2);
- udelay(1);
- }
- }
- addr++;
- }
- }
-}
-
-static int jr3_download_firmware(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context)
-{
- int subdev;
- int ret;
-
- /* verify IDM file format */
- ret = jr3_check_firmware(dev, data, size);
- if (ret)
- return ret;
-
- /* write firmware to each subdevice */
- for (subdev = 0; subdev < dev->n_subdevices; subdev++)
- jr3_write_firmware(dev, subdev, data, size);
-
- return 0;
-}
-
-static struct jr3_pci_poll_delay
-jr3_pci_poll_subdevice(struct comedi_subdevice *s)
-{
- struct jr3_pci_subdev_private *spriv = s->private;
- struct jr3_pci_poll_delay result = poll_delay_min_max(1000, 2000);
- struct jr3_sensor __iomem *sensor;
- u16 model_no;
- u16 serial_no;
- int errors;
- int i;
-
- sensor = spriv->sensor;
- errors = get_u16(&sensor->errors);
-
- if (errors != spriv->errors)
- spriv->errors = errors;
-
- /* Sensor communication lost? force poll mode */
- if (errors & (watch_dog | watch_dog2 | sensor_change))
- spriv->state = state_jr3_poll;
-
- switch (spriv->state) {
- case state_jr3_poll:
- model_no = get_u16(&sensor->model_no);
- serial_no = get_u16(&sensor->serial_no);
-
- if ((errors & (watch_dog | watch_dog2)) ||
- model_no == 0 || serial_no == 0) {
- /*
- * Still no sensor, keep on polling.
- * Since it takes up to 10 seconds for offsets to
- * stabilize, polling each second should suffice.
- */
- } else {
- spriv->retries = 0;
- spriv->state = state_jr3_init_wait_for_offset;
- }
- break;
- case state_jr3_init_wait_for_offset:
- spriv->retries++;
- if (spriv->retries < 10) {
- /*
- * Wait for offeset to stabilize
- * (< 10 s according to manual)
- */
- } else {
- struct jr3_pci_transform transf;
-
- spriv->model_no = get_u16(&sensor->model_no);
- spriv->serial_no = get_u16(&sensor->serial_no);
-
- /* Transformation all zeros */
- for (i = 0; i < ARRAY_SIZE(transf.link); i++) {
- transf.link[i].link_type = (enum link_types)0;
- transf.link[i].link_amount = 0;
- }
-
- set_transforms(sensor, &transf, 0);
- use_transform(sensor, 0);
- spriv->state = state_jr3_init_transform_complete;
- /* Allow 20 ms for completion */
- result = poll_delay_min_max(20, 100);
- }
- break;
- case state_jr3_init_transform_complete:
- if (!is_complete(sensor)) {
- result = poll_delay_min_max(20, 100);
- } else {
- /* Set full scale */
- struct six_axis_t min_full_scale;
- struct six_axis_t max_full_scale;
-
- min_full_scale = get_min_full_scales(sensor);
- max_full_scale = get_max_full_scales(sensor);
- set_full_scales(sensor, max_full_scale);
-
- spriv->state = state_jr3_init_set_full_scale_complete;
- /* Allow 20 ms for completion */
- result = poll_delay_min_max(20, 100);
- }
- break;
- case state_jr3_init_set_full_scale_complete:
- if (!is_complete(sensor)) {
- result = poll_delay_min_max(20, 100);
- } else {
- struct force_array __iomem *fs = &sensor->full_scale;
- union jr3_pci_single_range *r = spriv->range;
-
- /* Use ranges in kN or we will overflow around 2000N! */
- r[0].l.range[0].min = -get_s16(&fs->fx) * 1000;
- r[0].l.range[0].max = get_s16(&fs->fx) * 1000;
- r[1].l.range[0].min = -get_s16(&fs->fy) * 1000;
- r[1].l.range[0].max = get_s16(&fs->fy) * 1000;
- r[2].l.range[0].min = -get_s16(&fs->fz) * 1000;
- r[2].l.range[0].max = get_s16(&fs->fz) * 1000;
- r[3].l.range[0].min = -get_s16(&fs->mx) * 100;
- r[3].l.range[0].max = get_s16(&fs->mx) * 100;
- r[4].l.range[0].min = -get_s16(&fs->my) * 100;
- r[4].l.range[0].max = get_s16(&fs->my) * 100;
- r[5].l.range[0].min = -get_s16(&fs->mz) * 100;
- /* the next five are questionable */
- r[5].l.range[0].max = get_s16(&fs->mz) * 100;
- r[6].l.range[0].min = -get_s16(&fs->v1) * 100;
- r[6].l.range[0].max = get_s16(&fs->v1) * 100;
- r[7].l.range[0].min = -get_s16(&fs->v2) * 100;
- r[7].l.range[0].max = get_s16(&fs->v2) * 100;
- r[8].l.range[0].min = 0;
- r[8].l.range[0].max = 65535;
-
- use_offset(sensor, 0);
- spriv->state = state_jr3_init_use_offset_complete;
- /* Allow 40 ms for completion */
- result = poll_delay_min_max(40, 100);
- }
- break;
- case state_jr3_init_use_offset_complete:
- if (!is_complete(sensor)) {
- result = poll_delay_min_max(20, 100);
- } else {
- set_s16(&sensor->offsets.fx, 0);
- set_s16(&sensor->offsets.fy, 0);
- set_s16(&sensor->offsets.fz, 0);
- set_s16(&sensor->offsets.mx, 0);
- set_s16(&sensor->offsets.my, 0);
- set_s16(&sensor->offsets.mz, 0);
-
- set_offset(sensor);
-
- spriv->state = state_jr3_done;
- }
- break;
- case state_jr3_done:
- result = poll_delay_min_max(10000, 20000);
- break;
- default:
- break;
- }
-
- return result;
-}
-
-static void jr3_pci_poll_dev(struct timer_list *t)
-{
- struct jr3_pci_dev_private *devpriv = from_timer(devpriv, t, timer);
- struct comedi_device *dev = devpriv->dev;
- struct jr3_pci_subdev_private *spriv;
- struct comedi_subdevice *s;
- unsigned long flags;
- unsigned long now;
- int delay;
- int i;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- delay = 1000;
- now = jiffies;
-
- /* Poll all sensors that are ready to be polled */
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- spriv = s->private;
-
- if (time_after_eq(now, spriv->next_time_min)) {
- struct jr3_pci_poll_delay sub_delay;
-
- sub_delay = jr3_pci_poll_subdevice(s);
-
- spriv->next_time_min = jiffies +
- msecs_to_jiffies(sub_delay.min);
-
- if (sub_delay.max && sub_delay.max < delay)
- /*
- * Wake up as late as possible ->
- * poll as many sensors as possible at once.
- */
- delay = sub_delay.max;
- }
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
- add_timer(&devpriv->timer);
-}
-
-static struct jr3_pci_subdev_private *
-jr3_pci_alloc_spriv(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct jr3_block __iomem *block = dev->mmio;
- struct jr3_pci_subdev_private *spriv;
- int j;
- int k;
-
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return NULL;
-
- spriv->sensor = &block[s->index].sensor;
-
- for (j = 0; j < 8; j++) {
- spriv->range[j].l.length = 1;
- spriv->range[j].l.range[0].min = -1000000;
- spriv->range[j].l.range[0].max = 1000000;
-
- for (k = 0; k < 7; k++) {
- spriv->range_table_list[j + k * 8] = &spriv->range[j].l;
- spriv->maxdata_list[j + k * 8] = 0x7fff;
- }
- }
- spriv->range[8].l.length = 1;
- spriv->range[8].l.range[0].min = 0;
- spriv->range[8].l.range[0].max = 65535;
-
- spriv->range_table_list[56] = &spriv->range[8].l;
- spriv->range_table_list[57] = &spriv->range[8].l;
- spriv->maxdata_list[56] = 0xffff;
- spriv->maxdata_list[57] = 0xffff;
-
- return spriv;
-}
-
-static void jr3_pci_show_copyright(struct comedi_device *dev)
-{
- struct jr3_block __iomem *block = dev->mmio;
- struct jr3_sensor __iomem *sensor0 = &block[0].sensor;
- char copy[ARRAY_SIZE(sensor0->copyright) + 1];
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sensor0->copyright); i++)
- copy[i] = (char)(get_u16(&sensor0->copyright[i]) >> 8);
- copy[i] = '\0';
- dev_dbg(dev->class_dev, "Firmware copyright: %s\n", copy);
-}
-
-static int jr3_pci_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- static const struct jr3_pci_board *board;
- struct jr3_pci_dev_private *devpriv;
- struct jr3_pci_subdev_private *spriv;
- struct jr3_block __iomem *block;
- struct comedi_subdevice *s;
- int ret;
- int i;
-
- BUILD_BUG_ON(sizeof(struct jr3_block) != 0x80000);
-
- if (context < ARRAY_SIZE(jr3_pci_boards))
- board = &jr3_pci_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- if (pci_resource_len(pcidev, 0) < board->n_subdevs * sizeof(*block))
- return -ENXIO;
-
- dev->mmio = pci_ioremap_bar(pcidev, 0);
- if (!dev->mmio)
- return -ENOMEM;
-
- block = dev->mmio;
-
- ret = comedi_alloc_subdevices(dev, board->n_subdevs);
- if (ret)
- return ret;
-
- dev->open = jr3_pci_open;
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 8 * 7 + 2;
- s->insn_read = jr3_pci_ai_insn_read;
-
- spriv = jr3_pci_alloc_spriv(dev, s);
- if (!spriv)
- return -ENOMEM;
-
- /* Channel specific range and maxdata */
- s->range_table_list = spriv->range_table_list;
- s->maxdata_list = spriv->maxdata_list;
- }
-
- /* Reset DSP card */
- for (i = 0; i < dev->n_subdevices; i++)
- writel(0, &block[i].reset);
-
- ret = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
- "comedi/jr3pci.idm",
- jr3_download_firmware, 0);
- dev_dbg(dev->class_dev, "Firmware load %d\n", ret);
- if (ret < 0)
- return ret;
- /*
- * TODO: use firmware to load preferred offset tables. Suggested
- * format:
- * model serial Fx Fy Fz Mx My Mz\n
- *
- * comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
- * "comedi/jr3_offsets_table",
- * jr3_download_firmware, 1);
- */
-
- /*
- * It takes a few milliseconds for software to settle as much as we
- * can read firmware version
- */
- msleep_interruptible(25);
- jr3_pci_show_copyright(dev);
-
- /* Start card timer */
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- spriv = s->private;
-
- spriv->next_time_min = jiffies + msecs_to_jiffies(500);
- }
-
- devpriv->dev = dev;
- timer_setup(&devpriv->timer, jr3_pci_poll_dev, 0);
- devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
- add_timer(&devpriv->timer);
-
- return 0;
-}
-
-static void jr3_pci_detach(struct comedi_device *dev)
-{
- struct jr3_pci_dev_private *devpriv = dev->private;
-
- if (devpriv)
- del_timer_sync(&devpriv->timer);
-
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver jr3_pci_driver = {
- .driver_name = "jr3_pci",
- .module = THIS_MODULE,
- .auto_attach = jr3_pci_auto_attach,
- .detach = jr3_pci_detach,
-};
-
-static int jr3_pci_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &jr3_pci_driver, id->driver_data);
-}
-
-static const struct pci_device_id jr3_pci_pci_table[] = {
- { PCI_VDEVICE(JR3, 0x1111), BOARD_JR3_1 },
- { PCI_VDEVICE(JR3, 0x3111), BOARD_JR3_1 },
- { PCI_VDEVICE(JR3, 0x3112), BOARD_JR3_2 },
- { PCI_VDEVICE(JR3, 0x3113), BOARD_JR3_3 },
- { PCI_VDEVICE(JR3, 0x3114), BOARD_JR3_4 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
-
-static struct pci_driver jr3_pci_pci_driver = {
- .name = "jr3_pci",
- .id_table = jr3_pci_pci_table,
- .probe = jr3_pci_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(jr3_pci_driver, jr3_pci_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for JR3/PCI force sensor board");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("comedi/jr3pci.idm");
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
deleted file mode 100644
index acd4e5456ceb..000000000000
--- a/drivers/staging/comedi/drivers/jr3_pci.h
+++ /dev/null
@@ -1,735 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Helper types to take care of the fact that the DSP card memory
- * is 16 bits, but aligned on a 32 bit PCI boundary
- */
-
-static inline u16 get_u16(const u32 __iomem *p)
-{
- return (u16)readl(p);
-}
-
-static inline void set_u16(u32 __iomem *p, u16 val)
-{
- writel(val, p);
-}
-
-static inline s16 get_s16(const s32 __iomem *p)
-{
- return (s16)readl(p);
-}
-
-static inline void set_s16(s32 __iomem *p, s16 val)
-{
- writel(val, p);
-}
-
-/*
- * The raw data is stored in a format which facilitates rapid
- * processing by the JR3 DSP chip. The raw_channel structure shows the
- * format for a single channel of data. Each channel takes four,
- * two-byte words.
- *
- * Raw_time is an unsigned integer which shows the value of the JR3
- * DSP's internal clock at the time the sample was received. The clock
- * runs at 1/10 the JR3 DSP cycle time. JR3's slowest DSP runs at 10
- * Mhz. At 10 Mhz raw_time would therefore clock at 1 Mhz.
- *
- * Raw_data is the raw data received directly from the sensor. The
- * sensor data stream is capable of representing 16 different
- * channels. Channel 0 shows the excitation voltage at the sensor. It
- * is used to regulate the voltage over various cable lengths.
- * Channels 1-6 contain the coupled force data Fx through Mz. Channel
- * 7 contains the sensor's calibration data. The use of channels 8-15
- * varies with different sensors.
- */
-
-struct raw_channel {
- u32 raw_time;
- s32 raw_data;
- s32 reserved[2];
-};
-
-/*
- * The force_array structure shows the layout for the decoupled and
- * filtered force data.
- */
-struct force_array {
- s32 fx;
- s32 fy;
- s32 fz;
- s32 mx;
- s32 my;
- s32 mz;
- s32 v1;
- s32 v2;
-};
-
-/*
- * The six_axis_array structure shows the layout for the offsets and
- * the full scales.
- */
-struct six_axis_array {
- s32 fx;
- s32 fy;
- s32 fz;
- s32 mx;
- s32 my;
- s32 mz;
-};
-
-/* VECT_BITS */
-/*
- * The vect_bits structure shows the layout for indicating
- * which axes to use in computing the vectors. Each bit signifies
- * selection of a single axis. The V1x axis bit corresponds to a hex
- * value of 0x0001 and the V2z bit corresponds to a hex value of
- * 0x0020. Example: to specify the axes V1x, V1y, V2x, and V2z the
- * pattern would be 0x002b. Vector 1 defaults to a force vector and
- * vector 2 defaults to a moment vector. It is possible to change one
- * or the other so that two force vectors or two moment vectors are
- * calculated. Setting the changeV1 bit or the changeV2 bit will
- * change that vector to be the opposite of its default. Therefore to
- * have two force vectors, set changeV1 to 1.
- */
-
-/* vect_bits appears to be unused at this time */
-enum {
- fx = 0x0001,
- fy = 0x0002,
- fz = 0x0004,
- mx = 0x0008,
- my = 0x0010,
- mz = 0x0020,
- changeV2 = 0x0040,
- changeV1 = 0x0080
-};
-
-/* WARNING_BITS */
-/*
- * The warning_bits structure shows the bit pattern for the warning
- * word. The bit fields are shown from bit 0 (lsb) to bit 15 (msb).
- */
-
-/* XX_NEAR_SET */
-/*
- * The xx_near_sat bits signify that the indicated axis has reached or
- * exceeded the near saturation value.
- */
-
-enum {
- fx_near_sat = 0x0001,
- fy_near_sat = 0x0002,
- fz_near_sat = 0x0004,
- mx_near_sat = 0x0008,
- my_near_sat = 0x0010,
- mz_near_sat = 0x0020
-};
-
-/* ERROR_BITS */
-/* XX_SAT */
-/* MEMORY_ERROR */
-/* SENSOR_CHANGE */
-
-/*
- * The error_bits structure shows the bit pattern for the error word.
- * The bit fields are shown from bit 0 (lsb) to bit 15 (msb). The
- * xx_sat bits signify that the indicated axis has reached or exceeded
- * the saturation value. The memory_error bit indicates that a problem
- * was detected in the on-board RAM during the power-up
- * initialization. The sensor_change bit indicates that a sensor other
- * than the one originally plugged in has passed its CRC check. This
- * bit latches, and must be reset by the user.
- *
- */
-
-/* SYSTEM_BUSY */
-
-/*
- * The system_busy bit indicates that the JR3 DSP is currently busy
- * and is not calculating force data. This occurs when a new
- * coordinate transformation, or new sensor full scale is set by the
- * user. A very fast system using the force data for feedback might
- * become unstable during the approximately 4 ms needed to accomplish
- * these calculations. This bit will also become active when a new
- * sensor is plugged in and the system needs to recalculate the
- * calibration CRC.
- */
-
-/* CAL_CRC_BAD */
-
-/*
- * The cal_crc_bad bit indicates that the calibration CRC has not
- * calculated to zero. CRC is short for cyclic redundancy code. It is
- * a method for determining the integrity of messages in data
- * communication. The calibration data stored inside the sensor is
- * transmitted to the JR3 DSP along with the sensor data. The
- * calibration data has a CRC attached to the end of it, to assist in
- * determining the completeness and integrity of the calibration data
- * received from the sensor. There are two reasons the CRC may not
- * have calculated to zero. The first is that all the calibration data
- * has not yet been received, the second is that the calibration data
- * has been corrupted. A typical sensor transmits the entire contents
- * of its calibration matrix over 30 times a second. Therefore, if
- * this bit is not zero within a couple of seconds after the sensor
- * has been plugged in, there is a problem with the sensor's
- * calibration data.
- */
-
-/* WATCH_DOG */
-/* WATCH_DOG2 */
-
-/*
- * The watch_dog and watch_dog2 bits are sensor, not processor, watch
- * dog bits. Watch_dog indicates that the sensor data line seems to be
- * acting correctly, while watch_dog2 indicates that sensor data and
- * clock are being received. It is possible for watch_dog2 to go off
- * while watch_dog does not. This would indicate an improper clock
- * signal, while data is acting correctly. If either watch dog barks,
- * the sensor data is not being received correctly.
- */
-
-enum error_bits_t {
- fx_sat = 0x0001,
- fy_sat = 0x0002,
- fz_sat = 0x0004,
- mx_sat = 0x0008,
- my_sat = 0x0010,
- mz_sat = 0x0020,
- memory_error = 0x0400,
- sensor_change = 0x0800,
- system_busy = 0x1000,
- cal_crc_bad = 0x2000,
- watch_dog2 = 0x4000,
- watch_dog = 0x8000
-};
-
-/* THRESH_STRUCT */
-
-/*
- * This structure shows the layout for a single threshold packet inside of a
- * load envelope. Each load envelope can contain several threshold structures.
- * 1. data_address contains the address of the data for that threshold. This
- * includes filtered, unfiltered, raw, rate, counters, error and warning data
- * 2. threshold is the is the value at which, if data is above or below, the
- * bits will be set ... (pag.24).
- * 3. bit_pattern contains the bits that will be set if the threshold value is
- * met or exceeded.
- */
-
-struct thresh_struct {
- s32 data_address;
- s32 threshold;
- s32 bit_pattern;
-};
-
-/* LE_STRUCT */
-
-/*
- * Layout of a load enveloped packet. Four thresholds are showed ... for more
- * see manual (pag.25)
- * 1. latch_bits is a bit pattern that show which bits the user wants to latch.
- * The latched bits will not be reset once the threshold which set them is
- * no longer true. In that case the user must reset them using the reset_bit
- * command.
- * 2. number_of_xx_thresholds specify how many GE/LE threshold there are.
- */
-struct le_struct {
- s32 latch_bits;
- s32 number_of_ge_thresholds;
- s32 number_of_le_thresholds;
- struct thresh_struct thresholds[4];
- s32 reserved;
-};
-
-/* LINK_TYPES */
-/*
- * Link types is an enumerated value showing the different possible transform
- * link types.
- * 0 - end transform packet
- * 1 - translate along X axis (TX)
- * 2 - translate along Y axis (TY)
- * 3 - translate along Z axis (TZ)
- * 4 - rotate about X axis (RX)
- * 5 - rotate about Y axis (RY)
- * 6 - rotate about Z axis (RZ)
- * 7 - negate all axes (NEG)
- */
-
-enum link_types {
- end_x_form,
- tx,
- ty,
- tz,
- rx,
- ry,
- rz,
- neg
-};
-
-/* TRANSFORM */
-/* Structure used to describe a transform. */
-struct intern_transform {
- struct {
- u32 link_type;
- s32 link_amount;
- } link[8];
-};
-
-/*
- * JR3 force/torque sensor data definition. For more information see sensor
- * and hardware manuals.
- */
-
-struct jr3_sensor {
- /*
- * Raw_channels is the area used to store the raw data coming from
- * the sensor.
- */
-
- struct raw_channel raw_channels[16]; /* offset 0x0000 */
-
- /*
- * Copyright is a null terminated ASCII string containing the JR3
- * copyright notice.
- */
-
- u32 copyright[0x0018]; /* offset 0x0040 */
- s32 reserved1[0x0008]; /* offset 0x0058 */
-
- /*
- * Shunts contains the sensor shunt readings. Some JR3 sensors have
- * the ability to have their gains adjusted. This allows the
- * hardware full scales to be adjusted to potentially allow
- * better resolution or dynamic range. For sensors that have
- * this ability, the gain of each sensor channel is measured at
- * the time of calibration using a shunt resistor. The shunt
- * resistor is placed across one arm of the resistor bridge, and
- * the resulting change in the output of that channel is
- * measured. This measurement is called the shunt reading, and
- * is recorded here. If the user has changed the gain of the //
- * sensor, and made new shunt measurements, those shunt
- * measurements can be placed here. The JR3 DSP will then scale
- * the calibration matrix such so that the gains are again
- * proper for the indicated shunt readings. If shunts is 0, then
- * the sensor cannot have its gain changed. For details on
- * changing the sensor gain, and making shunts readings, please
- * see the sensor manual. To make these values take effect the
- * user must call either command (5) use transform # (pg. 33) or
- * command (10) set new full scales (pg. 38).
- */
-
- struct six_axis_array shunts; /* offset 0x0060 */
- s32 reserved2[2]; /* offset 0x0066 */
-
- /*
- * Default_FS contains the full scale that is used if the user does
- * not set a full scale.
- */
-
- struct six_axis_array default_FS; /* offset 0x0068 */
- s32 reserved3; /* offset 0x006e */
-
- /*
- * Load_envelope_num is the load envelope number that is currently
- * in use. This value is set by the user after one of the load
- * envelopes has been initialized.
- */
-
- s32 load_envelope_num; /* offset 0x006f */
-
- /* Min_full_scale is the recommend minimum full scale. */
-
- /*
- * These values in conjunction with max_full_scale (pg. 9) helps
- * determine the appropriate value for setting the full scales. The
- * software allows the user to set the sensor full scale to an
- * arbitrary value. But setting the full scales has some hazards. If
- * the full scale is set too low, the data will saturate
- * prematurely, and dynamic range will be lost. If the full scale is
- * set too high, then resolution is lost as the data is shifted to
- * the right and the least significant bits are lost. Therefore the
- * maximum full scale is the maximum value at which no resolution is
- * lost, and the minimum full scale is the value at which the data
- * will not saturate prematurely. These values are calculated
- * whenever a new coordinate transformation is calculated. It is
- * possible for the recommended maximum to be less than the
- * recommended minimum. This comes about primarily when using
- * coordinate translations. If this is the case, it means that any
- * full scale selection will be a compromise between dynamic range
- * and resolution. It is usually recommended to compromise in favor
- * of resolution which means that the recommend maximum full scale
- * should be chosen.
- *
- * WARNING: Be sure that the full scale is no less than 0.4% of the
- * recommended minimum full scale. Full scales below this value will
- * cause erroneous results.
- */
-
- struct six_axis_array min_full_scale; /* offset 0x0070 */
- s32 reserved4; /* offset 0x0076 */
-
- /*
- * Transform_num is the transform number that is currently in use.
- * This value is set by the JR3 DSP after the user has used command
- * (5) use transform # (pg. 33).
- */
-
- s32 transform_num; /* offset 0x0077 */
-
- /*
- * Max_full_scale is the recommended maximum full scale.
- * See min_full_scale (pg. 9) for more details.
- */
-
- struct six_axis_array max_full_scale; /* offset 0x0078 */
- s32 reserved5; /* offset 0x007e */
-
- /*
- * Peak_address is the address of the data which will be monitored
- * by the peak routine. This value is set by the user. The peak
- * routine will monitor any 8 contiguous addresses for peak values.
- * (ex. to watch filter3 data for peaks, set this value to 0x00a8).
- */
-
- s32 peak_address; /* offset 0x007f */
-
- /*
- * Full_scale is the sensor full scales which are currently in use.
- * Decoupled and filtered data is scaled so that +/- 16384 is equal
- * to the full scales. The engineering units used are indicated by
- * the units value discussed on page 16. The full scales for Fx, Fy,
- * Fz, Mx, My and Mz can be written by the user prior to calling
- * command (10) set new full scales (pg. 38). The full scales for V1
- * and V2 are set whenever the full scales are changed or when the
- * axes used to calculate the vectors are changed. The full scale of
- * V1 and V2 will always be equal to the largest full scale of the
- * axes used for each vector respectively.
- */
-
- struct force_array full_scale; /* offset 0x0080 */
-
- /*
- * Offsets contains the sensor offsets. These values are subtracted from
- * the sensor data to obtain the decoupled data. The offsets are set a
- * few seconds (< 10) after the calibration data has been received.
- * They are set so that the output data will be zero. These values
- * can be written as well as read. The JR3 DSP will use the values
- * written here within 2 ms of being written. To set future
- * decoupled data to zero, add these values to the current decoupled
- * data values and place the sum here. The JR3 DSP will change these
- * values when a new transform is applied. So if the offsets are
- * such that FX is 5 and all other values are zero, after rotating
- * about Z by 90 degrees, FY would be 5 and all others would be zero.
- */
-
- struct six_axis_array offsets; /* offset 0x0088 */
-
- /*
- * Offset_num is the number of the offset currently in use. This
- * value is set by the JR3 DSP after the user has executed the use
- * offset # command (pg. 34). It can vary between 0 and 15.
- */
-
- s32 offset_num; /* offset 0x008e */
-
- /*
- * Vect_axes is a bit map showing which of the axes are being used
- * in the vector calculations. This value is set by the JR3 DSP
- * after the user has executed the set vector axes command (pg. 37).
- */
-
- u32 vect_axes; /* offset 0x008f */
-
- /*
- * Filter0 is the decoupled, unfiltered data from the JR3 sensor.
- * This data has had the offsets removed.
- *
- * These force_arrays hold the filtered data. The decoupled data is
- * passed through cascaded low pass filters. Each succeeding filter
- * has a cutoff frequency of 1/4 of the preceding filter. The cutoff
- * frequency of filter1 is 1/16 of the sample rate from the sensor.
- * For a typical sensor with a sample rate of 8 kHz, the cutoff
- * frequency of filter1 would be 500 Hz. The following filters would
- * cutoff at 125 Hz, 31.25 Hz, 7.813 Hz, 1.953 Hz and 0.4883 Hz.
- */
-
- struct force_array filter[7]; /*
- * offset 0x0090,
- * offset 0x0098,
- * offset 0x00a0,
- * offset 0x00a8,
- * offset 0x00b0,
- * offset 0x00b8,
- * offset 0x00c0
- */
-
- /*
- * Rate_data is the calculated rate data. It is a first derivative
- * calculation. It is calculated at a frequency specified by the
- * variable rate_divisor (pg. 12). The data on which the rate is
- * calculated is specified by the variable rate_address (pg. 12).
- */
-
- struct force_array rate_data; /* offset 0x00c8 */
-
- /*
- * Minimum_data & maximum_data are the minimum and maximum (peak)
- * data values. The JR3 DSP can monitor any 8 contiguous data items
- * for minimums and maximums at full sensor bandwidth. This area is
- * only updated at user request. This is done so that the user does
- * not miss any peaks. To read the data, use either the read peaks
- * command (pg. 40), or the read and reset peaks command (pg. 39).
- * The address of the data to watch for peaks is stored in the
- * variable peak_address (pg. 10). Peak data is lost when executing
- * a coordinate transformation or a full scale change. Peak data is
- * also lost when plugging in a new sensor.
- */
-
- struct force_array minimum_data; /* offset 0x00d0 */
- struct force_array maximum_data; /* offset 0x00d8 */
-
- /*
- * Near_sat_value & sat_value contain the value used to determine if
- * the raw sensor is saturated. Because of decoupling and offset
- * removal, it is difficult to tell from the processed data if the
- * sensor is saturated. These values, in conjunction with the error
- * and warning words (pg. 14), provide this critical information.
- * These two values may be set by the host processor. These values
- * are positive signed values, since the saturation logic uses the
- * absolute values of the raw data. The near_sat_value defaults to
- * approximately 80% of the ADC's full scale, which is 26214, while
- * sat_value defaults to the ADC's full scale:
- *
- * sat_value = 32768 - 2^(16 - ADC bits)
- */
-
- s32 near_sat_value; /* offset 0x00e0 */
- s32 sat_value; /* offset 0x00e1 */
-
- /*
- * Rate_address, rate_divisor & rate_count contain the data used to
- * control the calculations of the rates. Rate_address is the
- * address of the data used for the rate calculation. The JR3 DSP
- * will calculate rates for any 8 contiguous values (ex. to
- * calculate rates for filter3 data set rate_address to 0x00a8).
- * Rate_divisor is how often the rate is calculated. If rate_divisor
- * is 1, the rates are calculated at full sensor bandwidth. If
- * rate_divisor is 200, rates are calculated every 200 samples.
- * Rate_divisor can be any value between 1 and 65536. Set
- * rate_divisor to 0 to calculate rates every 65536 samples.
- * Rate_count starts at zero and counts until it equals
- * rate_divisor, at which point the rates are calculated, and
- * rate_count is reset to 0. When setting a new rate divisor, it is
- * a good idea to set rate_count to one less than rate divisor. This
- * will minimize the time necessary to start the rate calculations.
- */
-
- s32 rate_address; /* offset 0x00e2 */
- u32 rate_divisor; /* offset 0x00e3 */
- u32 rate_count; /* offset 0x00e4 */
-
- /*
- * Command_word2 through command_word0 are the locations used to
- * send commands to the JR3 DSP. Their usage varies with the command
- * and is detailed later in the Command Definitions section (pg.
- * 29). In general the user places values into various memory
- * locations, and then places the command word into command_word0.
- * The JR3 DSP will process the command and place a 0 into
- * command_word0 to indicate successful completion. Alternatively
- * the JR3 DSP will place a negative number into command_word0 to
- * indicate an error condition. Please note the command locations
- * are numbered backwards. (I.E. command_word2 comes before
- * command_word1).
- */
-
- s32 command_word2; /* offset 0x00e5 */
- s32 command_word1; /* offset 0x00e6 */
- s32 command_word0; /* offset 0x00e7 */
-
- /*
- * Count1 through count6 are unsigned counters which are incremented
- * every time the matching filters are calculated. Filter1 is
- * calculated at the sensor data bandwidth. So this counter would
- * increment at 8 kHz for a typical sensor. The rest of the counters
- * are incremented at 1/4 the interval of the counter immediately
- * preceding it, so they would count at 2 kHz, 500 Hz, 125 Hz etc.
- * These counters can be used to wait for data. Each time the
- * counter changes, the corresponding data set can be sampled, and
- * this will insure that the user gets each sample, once, and only
- * once.
- */
-
- u32 count1; /* offset 0x00e8 */
- u32 count2; /* offset 0x00e9 */
- u32 count3; /* offset 0x00ea */
- u32 count4; /* offset 0x00eb */
- u32 count5; /* offset 0x00ec */
- u32 count6; /* offset 0x00ed */
-
- /*
- * Error_count is a running count of data reception errors. If this
- * counter is changing rapidly, it probably indicates a bad sensor
- * cable connection or other hardware problem. In most installations
- * error_count should not change at all. But it is possible in an
- * extremely noisy environment to experience occasional errors even
- * without a hardware problem. If the sensor is well grounded, this
- * is probably unavoidable in these environments. On the occasions
- * where this counter counts a bad sample, that sample is ignored.
- */
-
- u32 error_count; /* offset 0x00ee */
-
- /*
- * Count_x is a counter which is incremented every time the JR3 DSP
- * searches its job queues and finds nothing to do. It indicates the
- * amount of idle time the JR3 DSP has available. It can also be
- * used to determine if the JR3 DSP is alive. See the Performance
- * Issues section on pg. 49 for more details.
- */
-
- u32 count_x; /* offset 0x00ef */
-
- /*
- * Warnings & errors contain the warning and error bits
- * respectively. The format of these two words is discussed on page
- * 21 under the headings warnings_bits and error_bits.
- */
-
- u32 warnings; /* offset 0x00f0 */
- u32 errors; /* offset 0x00f1 */
-
- /*
- * Threshold_bits is a word containing the bits that are set by the
- * load envelopes. See load_envelopes (pg. 17) and thresh_struct
- * (pg. 23) for more details.
- */
-
- s32 threshold_bits; /* offset 0x00f2 */
-
- /*
- * Last_crc is the value that shows the actual calculated CRC. CRC
- * is short for cyclic redundancy code. It should be zero. See the
- * description for cal_crc_bad (pg. 21) for more information.
- */
-
- s32 last_CRC; /* offset 0x00f3 */
-
- /*
- * EEProm_ver_no contains the version number of the sensor EEProm.
- * EEProm version numbers can vary between 0 and 255.
- * Software_ver_no contains the software version number. Version
- * 3.02 would be stored as 302.
- */
-
- s32 eeprom_ver_no; /* offset 0x00f4 */
- s32 software_ver_no; /* offset 0x00f5 */
-
- /*
- * Software_day & software_year are the release date of the software
- * the JR3 DSP is currently running. Day is the day of the year,
- * with January 1 being 1, and December 31, being 365 for non leap
- * years.
- */
-
- s32 software_day; /* offset 0x00f6 */
- s32 software_year; /* offset 0x00f7 */
-
- /*
- * Serial_no & model_no are the two values which uniquely identify a
- * sensor. This model number does not directly correspond to the JR3
- * model number, but it will provide a unique identifier for
- * different sensor configurations.
- */
-
- u32 serial_no; /* offset 0x00f8 */
- u32 model_no; /* offset 0x00f9 */
-
- /*
- * Cal_day & cal_year are the sensor calibration date. Day is the
- * day of the year, with January 1 being 1, and December 31, being
- * 366 for leap years.
- */
-
- s32 cal_day; /* offset 0x00fa */
- s32 cal_year; /* offset 0x00fb */
-
- /*
- * Units is an enumerated read only value defining the engineering
- * units used in the sensor full scale. The meanings of particular
- * values are discussed in the section detailing the force_units
- * structure on page 22. The engineering units are setto customer
- * specifications during sensor manufacture and cannot be changed by
- * writing to Units.
- *
- * Bits contains the number of bits of resolution of the ADC
- * currently in use.
- *
- * Channels is a bit field showing which channels the current sensor
- * is capable of sending. If bit 0 is active, this sensor can send
- * channel 0, if bit 13 is active, this sensor can send channel 13,
- * etc. This bit can be active, even if the sensor is not currently
- * sending this channel. Some sensors are configurable as to which
- * channels to send, and this field only contains information on the
- * channels available to send, not on the current configuration. To
- * find which channels are currently being sent, monitor the
- * Raw_time fields (pg. 19) in the raw_channels array (pg. 7). If
- * the time is changing periodically, then that channel is being
- * received.
- */
-
- u32 units; /* offset 0x00fc */
- s32 bits; /* offset 0x00fd */
- s32 channels; /* offset 0x00fe */
-
- /*
- * Thickness specifies the overall thickness of the sensor from
- * flange to flange. The engineering units for this value are
- * contained in units (pg. 16). The sensor calibration is relative
- * to the center of the sensor. This value allows easy coordinate
- * transformation from the center of the sensor to either flange.
- */
-
- s32 thickness; /* offset 0x00ff */
-
- /*
- * Load_envelopes is a table containing the load envelope
- * descriptions. There are 16 possible load envelope slots in the
- * table. The slots are on 16 word boundaries and are numbered 0-15.
- * Each load envelope needs to start at the beginning of a slot but
- * need not be fully contained in that slot. That is to say that a
- * single load envelope can be larger than a single slot. The
- * software has been tested and ran satisfactorily with 50
- * thresholds active. A single load envelope this large would take
- * up 5 of the 16 slots. The load envelope data is laid out in an
- * order that is most efficient for the JR3 DSP. The structure is
- * detailed later in the section showing the definition of the
- * le_struct structure (pg. 23).
- */
-
- struct le_struct load_envelopes[0x10]; /* offset 0x0100 */
-
- /*
- * Transforms is a table containing the transform descriptions.
- * There are 16 possible transform slots in the table. The slots are
- * on 16 word boundaries and are numbered 0-15. Each transform needs
- * to start at the beginning of a slot but need not be fully
- * contained in that slot. That is to say that a single transform
- * can be larger than a single slot. A transform is 2 * no of links
- * + 1 words in length. So a single slot can contain a transform
- * with 7 links. Two slots can contain a transform that is 15 links.
- * The layout is detailed later in the section showing the
- * definition of the transform structure (pg. 26).
- */
-
- struct intern_transform transforms[0x10]; /* offset 0x0200 */
-};
-
-struct jr3_block {
- u32 program_lo[0x4000]; /* 0x00000 - 0x10000 */
- struct jr3_sensor sensor; /* 0x10000 - 0x10c00 */
- char pad2[0x30000 - 0x00c00]; /* 0x10c00 - 0x40000 */
- u32 program_hi[0x8000]; /* 0x40000 - 0x60000 */
- u32 reset; /* 0x60000 - 0x60004 */
- char pad3[0x20000 - 0x00004]; /* 0x60004 - 0x80000 */
-};
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
deleted file mode 100644
index bef1b20c1c8d..000000000000
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ /dev/null
@@ -1,232 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * ke_counter.c
- * Comedi driver for Kolter-Electronic PCI Counter 1 Card
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ke_counter
- * Description: Driver for Kolter Electronic Counter Card
- * Devices: [Kolter Electronic] PCI Counter Card (ke_counter)
- * Author: Michael Hillmann
- * Updated: Mon, 14 Apr 2008 15:42:42 +0100
- * Status: tested
- *
- * Configuration Options: not applicable, uses PCI auto config
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI BAR 0 Register I/O map
- */
-#define KE_RESET_REG(x) (0x00 + ((x) * 0x20))
-#define KE_LATCH_REG(x) (0x00 + ((x) * 0x20))
-#define KE_LSB_REG(x) (0x04 + ((x) * 0x20))
-#define KE_MID_REG(x) (0x08 + ((x) * 0x20))
-#define KE_MSB_REG(x) (0x0c + ((x) * 0x20))
-#define KE_SIGN_REG(x) (0x10 + ((x) * 0x20))
-#define KE_OSC_SEL_REG 0xf8
-#define KE_OSC_SEL_CLK(x) (((x) & 0x3) << 0)
-#define KE_OSC_SEL_EXT KE_OSC_SEL_CLK(1)
-#define KE_OSC_SEL_4MHZ KE_OSC_SEL_CLK(2)
-#define KE_OSC_SEL_20MHZ KE_OSC_SEL_CLK(3)
-#define KE_DO_REG 0xfc
-
-static int ke_counter_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[0];
-
- /* Order matters */
- outb((val >> 24) & 0xff, dev->iobase + KE_SIGN_REG(chan));
- outb((val >> 16) & 0xff, dev->iobase + KE_MSB_REG(chan));
- outb((val >> 8) & 0xff, dev->iobase + KE_MID_REG(chan));
- outb((val >> 0) & 0xff, dev->iobase + KE_LSB_REG(chan));
- }
-
- return insn->n;
-}
-
-static int ke_counter_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- /* Order matters */
- inb(dev->iobase + KE_LATCH_REG(chan));
-
- val = inb(dev->iobase + KE_LSB_REG(chan));
- val |= (inb(dev->iobase + KE_MID_REG(chan)) << 8);
- val |= (inb(dev->iobase + KE_MSB_REG(chan)) << 16);
- val |= (inb(dev->iobase + KE_SIGN_REG(chan)) << 24);
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static void ke_counter_reset(struct comedi_device *dev)
-{
- unsigned int chan;
-
- for (chan = 0; chan < 3; chan++)
- outb(0, dev->iobase + KE_RESET_REG(chan));
-}
-
-static int ke_counter_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned char src;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_CLOCK_SRC:
- switch (data[1]) {
- case KE_CLK_20MHZ: /* default */
- src = KE_OSC_SEL_20MHZ;
- break;
- case KE_CLK_4MHZ: /* option */
- src = KE_OSC_SEL_4MHZ;
- break;
- case KE_CLK_EXT: /* Pin 21 on D-sub */
- src = KE_OSC_SEL_EXT;
- break;
- default:
- return -EINVAL;
- }
- outb(src, dev->iobase + KE_OSC_SEL_REG);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- src = inb(dev->iobase + KE_OSC_SEL_REG);
- switch (src) {
- case KE_OSC_SEL_20MHZ:
- data[1] = KE_CLK_20MHZ;
- data[2] = 50; /* 50ns */
- break;
- case KE_OSC_SEL_4MHZ:
- data[1] = KE_CLK_4MHZ;
- data[2] = 250; /* 250ns */
- break;
- case KE_OSC_SEL_EXT:
- data[1] = KE_CLK_EXT;
- data[2] = 0; /* Unknown */
- break;
- default:
- return -EINVAL;
- }
- break;
- case INSN_CONFIG_RESET:
- ke_counter_reset(dev);
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int ke_counter_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + KE_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int ke_counter_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
- dev->iobase = pci_resource_start(pcidev, 0);
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 3;
- s->maxdata = 0x01ffffff;
- s->range_table = &range_unknown;
- s->insn_read = ke_counter_insn_read;
- s->insn_write = ke_counter_insn_write;
- s->insn_config = ke_counter_insn_config;
-
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 3;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ke_counter_do_insn_bits;
-
- outb(KE_OSC_SEL_20MHZ, dev->iobase + KE_OSC_SEL_REG);
-
- ke_counter_reset(dev);
-
- return 0;
-}
-
-static struct comedi_driver ke_counter_driver = {
- .driver_name = "ke_counter",
- .module = THIS_MODULE,
- .auto_attach = ke_counter_auto_attach,
- .detach = comedi_pci_detach,
-};
-
-static int ke_counter_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &ke_counter_driver,
- id->driver_data);
-}
-
-static const struct pci_device_id ke_counter_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, 0x0014) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ke_counter_pci_table);
-
-static struct pci_driver ke_counter_pci_driver = {
- .name = "ke_counter",
- .id_table = ke_counter_pci_table,
- .probe = ke_counter_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(ke_counter_driver, ke_counter_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Kolter Electronic Counter Card");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
deleted file mode 100644
index 0d3d4cafce2e..000000000000
--- a/drivers/staging/comedi/drivers/me4000.c
+++ /dev/null
@@ -1,1278 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * me4000.c
- * Source code for the Meilhaus ME-4000 board family.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: me4000
- * Description: Meilhaus ME-4000 series boards
- * Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i,
- * ME-4680is
- * Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
- * Updated: Mon, 18 Mar 2002 15:34:01 -0800
- * Status: untested
- *
- * Supports:
- * - Analog Input
- * - Analog Output
- * - Digital I/O
- * - Counter
- *
- * Configuration Options: not applicable, uses PCI auto config
- *
- * The firmware required by these boards is available in the
- * comedi_nonfree_firmware tarball available from
- * https://www.comedi.org.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "comedi_8254.h"
-#include "plx9052.h"
-
-#define ME4000_FIRMWARE "me4000_firmware.bin"
-
-/*
- * ME4000 Register map and bit defines
- */
-#define ME4000_AO_CHAN(x) ((x) * 0x18)
-
-#define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
-#define ME4000_AO_CTRL_MODE_0 BIT(0)
-#define ME4000_AO_CTRL_MODE_1 BIT(1)
-#define ME4000_AO_CTRL_STOP BIT(2)
-#define ME4000_AO_CTRL_ENABLE_FIFO BIT(3)
-#define ME4000_AO_CTRL_ENABLE_EX_TRIG BIT(4)
-#define ME4000_AO_CTRL_EX_TRIG_EDGE BIT(5)
-#define ME4000_AO_CTRL_IMMEDIATE_STOP BIT(7)
-#define ME4000_AO_CTRL_ENABLE_DO BIT(8)
-#define ME4000_AO_CTRL_ENABLE_IRQ BIT(9)
-#define ME4000_AO_CTRL_RESET_IRQ BIT(10)
-#define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
-#define ME4000_AO_STATUS_FSM BIT(0)
-#define ME4000_AO_STATUS_FF BIT(1)
-#define ME4000_AO_STATUS_HF BIT(2)
-#define ME4000_AO_STATUS_EF BIT(3)
-#define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
-#define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
-#define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
-#define ME4000_AI_CTRL_REG 0x74
-#define ME4000_AI_STATUS_REG 0x74
-#define ME4000_AI_CTRL_MODE_0 BIT(0)
-#define ME4000_AI_CTRL_MODE_1 BIT(1)
-#define ME4000_AI_CTRL_MODE_2 BIT(2)
-#define ME4000_AI_CTRL_SAMPLE_HOLD BIT(3)
-#define ME4000_AI_CTRL_IMMEDIATE_STOP BIT(4)
-#define ME4000_AI_CTRL_STOP BIT(5)
-#define ME4000_AI_CTRL_CHANNEL_FIFO BIT(6)
-#define ME4000_AI_CTRL_DATA_FIFO BIT(7)
-#define ME4000_AI_CTRL_FULLSCALE BIT(8)
-#define ME4000_AI_CTRL_OFFSET BIT(9)
-#define ME4000_AI_CTRL_EX_TRIG_ANALOG BIT(10)
-#define ME4000_AI_CTRL_EX_TRIG BIT(11)
-#define ME4000_AI_CTRL_EX_TRIG_FALLING BIT(12)
-#define ME4000_AI_CTRL_EX_IRQ BIT(13)
-#define ME4000_AI_CTRL_EX_IRQ_RESET BIT(14)
-#define ME4000_AI_CTRL_LE_IRQ BIT(15)
-#define ME4000_AI_CTRL_LE_IRQ_RESET BIT(16)
-#define ME4000_AI_CTRL_HF_IRQ BIT(17)
-#define ME4000_AI_CTRL_HF_IRQ_RESET BIT(18)
-#define ME4000_AI_CTRL_SC_IRQ BIT(19)
-#define ME4000_AI_CTRL_SC_IRQ_RESET BIT(20)
-#define ME4000_AI_CTRL_SC_RELOAD BIT(21)
-#define ME4000_AI_STATUS_EF_CHANNEL BIT(22)
-#define ME4000_AI_STATUS_HF_CHANNEL BIT(23)
-#define ME4000_AI_STATUS_FF_CHANNEL BIT(24)
-#define ME4000_AI_STATUS_EF_DATA BIT(25)
-#define ME4000_AI_STATUS_HF_DATA BIT(26)
-#define ME4000_AI_STATUS_FF_DATA BIT(27)
-#define ME4000_AI_STATUS_LE BIT(28)
-#define ME4000_AI_STATUS_FSM BIT(29)
-#define ME4000_AI_CTRL_EX_TRIG_BOTH BIT(31)
-#define ME4000_AI_CHANNEL_LIST_REG 0x78
-#define ME4000_AI_LIST_INPUT_DIFFERENTIAL BIT(5)
-#define ME4000_AI_LIST_RANGE(x) ((3 - ((x) & 3)) << 6)
-#define ME4000_AI_LIST_LAST_ENTRY BIT(8)
-#define ME4000_AI_DATA_REG 0x7c
-#define ME4000_AI_CHAN_TIMER_REG 0x80
-#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
-#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
-#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
-#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
-#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
-#define ME4000_AI_START_REG 0x98
-#define ME4000_IRQ_STATUS_REG 0x9c
-#define ME4000_IRQ_STATUS_EX BIT(0)
-#define ME4000_IRQ_STATUS_LE BIT(1)
-#define ME4000_IRQ_STATUS_AI_HF BIT(2)
-#define ME4000_IRQ_STATUS_AO_0_HF BIT(3)
-#define ME4000_IRQ_STATUS_AO_1_HF BIT(4)
-#define ME4000_IRQ_STATUS_AO_2_HF BIT(5)
-#define ME4000_IRQ_STATUS_AO_3_HF BIT(6)
-#define ME4000_IRQ_STATUS_SC BIT(7)
-#define ME4000_DIO_PORT_0_REG 0xa0
-#define ME4000_DIO_PORT_1_REG 0xa4
-#define ME4000_DIO_PORT_2_REG 0xa8
-#define ME4000_DIO_PORT_3_REG 0xac
-#define ME4000_DIO_DIR_REG 0xb0
-#define ME4000_AO_LOADSETREG_XX 0xb4
-#define ME4000_DIO_CTRL_REG 0xb8
-#define ME4000_DIO_CTRL_MODE_0 BIT(0)
-#define ME4000_DIO_CTRL_MODE_1 BIT(1)
-#define ME4000_DIO_CTRL_MODE_2 BIT(2)
-#define ME4000_DIO_CTRL_MODE_3 BIT(3)
-#define ME4000_DIO_CTRL_MODE_4 BIT(4)
-#define ME4000_DIO_CTRL_MODE_5 BIT(5)
-#define ME4000_DIO_CTRL_MODE_6 BIT(6)
-#define ME4000_DIO_CTRL_MODE_7 BIT(7)
-#define ME4000_DIO_CTRL_FUNCTION_0 BIT(8)
-#define ME4000_DIO_CTRL_FUNCTION_1 BIT(9)
-#define ME4000_DIO_CTRL_FIFO_HIGH_0 BIT(10)
-#define ME4000_DIO_CTRL_FIFO_HIGH_1 BIT(11)
-#define ME4000_DIO_CTRL_FIFO_HIGH_2 BIT(12)
-#define ME4000_DIO_CTRL_FIFO_HIGH_3 BIT(13)
-#define ME4000_AO_DEMUX_ADJUST_REG 0xbc
-#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
-#define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
-
-#define ME4000_AI_FIFO_COUNT 2048
-
-#define ME4000_AI_MIN_TICKS 66
-#define ME4000_AI_MIN_SAMPLE_TIME 2000
-
-#define ME4000_AI_CHANNEL_LIST_COUNT 1024
-
-struct me4000_private {
- unsigned long plx_regbase;
- unsigned int ai_ctrl_mode;
- unsigned int ai_init_ticks;
- unsigned int ai_scan_ticks;
- unsigned int ai_chan_ticks;
-};
-
-enum me4000_boardid {
- BOARD_ME4650,
- BOARD_ME4660,
- BOARD_ME4660I,
- BOARD_ME4660S,
- BOARD_ME4660IS,
- BOARD_ME4670,
- BOARD_ME4670I,
- BOARD_ME4670S,
- BOARD_ME4670IS,
- BOARD_ME4680,
- BOARD_ME4680I,
- BOARD_ME4680S,
- BOARD_ME4680IS,
-};
-
-struct me4000_board {
- const char *name;
- int ai_nchan;
- unsigned int can_do_diff_ai:1;
- unsigned int can_do_sh_ai:1; /* sample & hold (8 channels) */
- unsigned int ex_trig_analog:1;
- unsigned int has_ao:1;
- unsigned int has_ao_fifo:1;
- unsigned int has_counter:1;
-};
-
-static const struct me4000_board me4000_boards[] = {
- [BOARD_ME4650] = {
- .name = "ME-4650",
- .ai_nchan = 16,
- },
- [BOARD_ME4660] = {
- .name = "ME-4660",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .has_counter = 1,
- },
- [BOARD_ME4660I] = {
- .name = "ME-4660i",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .has_counter = 1,
- },
- [BOARD_ME4660S] = {
- .name = "ME-4660s",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .can_do_sh_ai = 1,
- .has_counter = 1,
- },
- [BOARD_ME4660IS] = {
- .name = "ME-4660is",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .can_do_sh_ai = 1,
- .has_counter = 1,
- },
- [BOARD_ME4670] = {
- .name = "ME-4670",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_counter = 1,
- },
- [BOARD_ME4670I] = {
- .name = "ME-4670i",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_counter = 1,
- },
- [BOARD_ME4670S] = {
- .name = "ME-4670s",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .can_do_sh_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_counter = 1,
- },
- [BOARD_ME4670IS] = {
- .name = "ME-4670is",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .can_do_sh_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_counter = 1,
- },
- [BOARD_ME4680] = {
- .name = "ME-4680",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_ao_fifo = 1,
- .has_counter = 1,
- },
- [BOARD_ME4680I] = {
- .name = "ME-4680i",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_ao_fifo = 1,
- .has_counter = 1,
- },
- [BOARD_ME4680S] = {
- .name = "ME-4680s",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .can_do_sh_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_ao_fifo = 1,
- .has_counter = 1,
- },
- [BOARD_ME4680IS] = {
- .name = "ME-4680is",
- .ai_nchan = 32,
- .can_do_diff_ai = 1,
- .can_do_sh_ai = 1,
- .ex_trig_analog = 1,
- .has_ao = 1,
- .has_ao_fifo = 1,
- .has_counter = 1,
- },
-};
-
-/*
- * NOTE: the ranges here are inverted compared to the values
- * written to the ME4000_AI_CHANNEL_LIST_REG,
- *
- * The ME4000_AI_LIST_RANGE() macro handles the inversion.
- */
-static const struct comedi_lrange me4000_ai_range = {
- 4, {
- UNI_RANGE(2.5),
- UNI_RANGE(10),
- BIP_RANGE(2.5),
- BIP_RANGE(10)
- }
-};
-
-static int me4000_xilinx_download(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct me4000_private *devpriv = dev->private;
- unsigned long xilinx_iobase = pci_resource_start(pcidev, 5);
- unsigned int file_length;
- unsigned int val;
- unsigned int i;
-
- if (!xilinx_iobase)
- return -ENODEV;
-
- /*
- * Set PLX local interrupt 2 polarity to high.
- * Interrupt is thrown by init pin of xilinx.
- */
- outl(PLX9052_INTCSR_LI2POL, devpriv->plx_regbase + PLX9052_INTCSR);
-
- /* Set /CS and /WRITE of the Xilinx */
- val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
- val |= PLX9052_CNTRL_UIO2_DATA;
- outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
-
- /* Init Xilinx with CS1 */
- inb(xilinx_iobase + 0xC8);
-
- /* Wait until /INIT pin is set */
- usleep_range(20, 1000);
- val = inl(devpriv->plx_regbase + PLX9052_INTCSR);
- if (!(val & PLX9052_INTCSR_LI2STAT)) {
- dev_err(dev->class_dev, "Can't init Xilinx\n");
- return -EIO;
- }
-
- /* Reset /CS and /WRITE of the Xilinx */
- val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
- val &= ~PLX9052_CNTRL_UIO2_DATA;
- outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
-
- /* Download Xilinx firmware */
- file_length = (((unsigned int)data[0] & 0xff) << 24) +
- (((unsigned int)data[1] & 0xff) << 16) +
- (((unsigned int)data[2] & 0xff) << 8) +
- ((unsigned int)data[3] & 0xff);
- usleep_range(10, 1000);
-
- for (i = 0; i < file_length; i++) {
- outb(data[16 + i], xilinx_iobase);
- usleep_range(10, 1000);
-
- /* Check if BUSY flag is low */
- val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
- if (val & PLX9052_CNTRL_UIO1_DATA) {
- dev_err(dev->class_dev,
- "Xilinx is still busy (i = %d)\n", i);
- return -EIO;
- }
- }
-
- /* If done flag is high download was successful */
- val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
- if (!(val & PLX9052_CNTRL_UIO0_DATA)) {
- dev_err(dev->class_dev, "DONE flag is not set\n");
- dev_err(dev->class_dev, "Download not successful\n");
- return -EIO;
- }
-
- /* Set /CS and /WRITE */
- val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
- val |= PLX9052_CNTRL_UIO2_DATA;
- outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
-
- return 0;
-}
-
-static void me4000_ai_reset(struct comedi_device *dev)
-{
- unsigned int ctrl;
-
- /* Stop any running conversion */
- ctrl = inl(dev->iobase + ME4000_AI_CTRL_REG);
- ctrl |= ME4000_AI_CTRL_STOP | ME4000_AI_CTRL_IMMEDIATE_STOP;
- outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
-
- /* Clear the control register */
- outl(0x0, dev->iobase + ME4000_AI_CTRL_REG);
-}
-
-static void me4000_reset(struct comedi_device *dev)
-{
- struct me4000_private *devpriv = dev->private;
- unsigned int val;
- int chan;
-
- /* Disable interrupts on the PLX */
- outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
-
- /* Software reset the PLX */
- val = inl(devpriv->plx_regbase + PLX9052_CNTRL);
- val |= PLX9052_CNTRL_PCI_RESET;
- outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
- val &= ~PLX9052_CNTRL_PCI_RESET;
- outl(val, devpriv->plx_regbase + PLX9052_CNTRL);
-
- /* 0x8000 to the DACs means an output voltage of 0V */
- for (chan = 0; chan < 4; chan++)
- outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan));
-
- me4000_ai_reset(dev);
-
- /* Set both stop bits in the analog output control register */
- val = ME4000_AO_CTRL_IMMEDIATE_STOP | ME4000_AO_CTRL_STOP;
- for (chan = 0; chan < 4; chan++)
- outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
-
- /* Set the adustment register for AO demux */
- outl(ME4000_AO_DEMUX_ADJUST_VALUE,
- dev->iobase + ME4000_AO_DEMUX_ADJUST_REG);
-
- /*
- * Set digital I/O direction for port 0
- * to output on isolated versions
- */
- if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1))
- outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG);
-}
-
-static unsigned int me4000_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- /* read two's complement value and munge to offset binary */
- val = inl(dev->iobase + ME4000_AI_DATA_REG);
- return comedi_offset_munge(s, val);
-}
-
-static int me4000_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inl(dev->iobase + ME4000_AI_STATUS_REG);
- if (status & ME4000_AI_STATUS_EF_DATA)
- return 0;
- return -EBUSY;
-}
-
-static int me4000_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- unsigned int entry;
- int ret = 0;
- int i;
-
- entry = chan | ME4000_AI_LIST_RANGE(range);
- if (aref == AREF_DIFF) {
- if (!(s->subdev_flags & SDF_DIFF)) {
- dev_err(dev->class_dev,
- "Differential inputs are not available\n");
- return -EINVAL;
- }
-
- if (!comedi_range_is_bipolar(s, range)) {
- dev_err(dev->class_dev,
- "Range must be bipolar when aref = diff\n");
- return -EINVAL;
- }
-
- if (chan >= (s->n_chan / 2)) {
- dev_err(dev->class_dev,
- "Analog input is not available\n");
- return -EINVAL;
- }
- entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
- }
-
- entry |= ME4000_AI_LIST_LAST_ENTRY;
-
- /* Enable channel list and data fifo for single acquisition mode */
- outl(ME4000_AI_CTRL_CHANNEL_FIFO | ME4000_AI_CTRL_DATA_FIFO,
- dev->iobase + ME4000_AI_CTRL_REG);
-
- /* Generate channel list entry */
- outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
-
- /* Set the timer to maximum sample rate */
- outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG);
- outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val;
-
- /* start conversion by dummy read */
- inl(dev->iobase + ME4000_AI_START_REG);
-
- ret = comedi_timeout(dev, s, insn, me4000_ai_eoc, 0);
- if (ret)
- break;
-
- val = me4000_ai_get_sample(dev, s);
- data[i] = comedi_offset_munge(s, val);
- }
-
- me4000_ai_reset(dev);
-
- return ret ? ret : insn->n;
-}
-
-static int me4000_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- me4000_ai_reset(dev);
-
- return 0;
-}
-
-static int me4000_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- if (aref != aref0) {
- dev_dbg(dev->class_dev,
- "Mode is not equal for all entries\n");
- return -EINVAL;
- }
-
- if (aref == AREF_DIFF) {
- if (!(s->subdev_flags & SDF_DIFF)) {
- dev_err(dev->class_dev,
- "Differential inputs are not available\n");
- return -EINVAL;
- }
-
- if (chan >= (s->n_chan / 2)) {
- dev_dbg(dev->class_dev,
- "Channel number to high\n");
- return -EINVAL;
- }
-
- if (!comedi_range_is_bipolar(s, range)) {
- dev_dbg(dev->class_dev,
- "Bipolar is not selected in differential mode\n");
- return -EINVAL;
- }
- }
- }
-
- return 0;
-}
-
-static void me4000_ai_round_cmd_args(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct me4000_private *devpriv = dev->private;
- int rest;
-
- devpriv->ai_init_ticks = 0;
- devpriv->ai_scan_ticks = 0;
- devpriv->ai_chan_ticks = 0;
-
- if (cmd->start_arg) {
- devpriv->ai_init_ticks = (cmd->start_arg * 33) / 1000;
- rest = (cmd->start_arg * 33) % 1000;
-
- if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
- if (rest > 33)
- devpriv->ai_init_ticks++;
- } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
- if (rest)
- devpriv->ai_init_ticks++;
- }
- }
-
- if (cmd->scan_begin_arg) {
- devpriv->ai_scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
- rest = (cmd->scan_begin_arg * 33) % 1000;
-
- if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
- if (rest > 33)
- devpriv->ai_scan_ticks++;
- } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
- if (rest)
- devpriv->ai_scan_ticks++;
- }
- }
-
- if (cmd->convert_arg) {
- devpriv->ai_chan_ticks = (cmd->convert_arg * 33) / 1000;
- rest = (cmd->convert_arg * 33) % 1000;
-
- if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) {
- if (rest > 33)
- devpriv->ai_chan_ticks++;
- } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) {
- if (rest)
- devpriv->ai_chan_ticks++;
- }
- }
-}
-
-static void me4000_ai_write_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
- unsigned int entry;
-
- entry = chan | ME4000_AI_LIST_RANGE(range);
-
- if (aref == AREF_DIFF)
- entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
-
- if (i == (cmd->chanlist_len - 1))
- entry |= ME4000_AI_LIST_LAST_ENTRY;
-
- outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG);
- }
-}
-
-static int me4000_ai_do_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct me4000_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int ctrl;
-
- /* Write timer arguments */
- outl(devpriv->ai_init_ticks - 1,
- dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG);
- outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG);
-
- if (devpriv->ai_scan_ticks) {
- outl(devpriv->ai_scan_ticks - 1,
- dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG);
- outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG);
- }
-
- outl(devpriv->ai_chan_ticks - 1,
- dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG);
- outl(devpriv->ai_chan_ticks - 1,
- dev->iobase + ME4000_AI_CHAN_TIMER_REG);
-
- /* Start sources */
- ctrl = devpriv->ai_ctrl_mode |
- ME4000_AI_CTRL_CHANNEL_FIFO |
- ME4000_AI_CTRL_DATA_FIFO;
-
- /* Stop triggers */
- if (cmd->stop_src == TRIG_COUNT) {
- outl(cmd->chanlist_len * cmd->stop_arg,
- dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
- ctrl |= ME4000_AI_CTRL_SC_IRQ;
- } else if (cmd->stop_src == TRIG_NONE &&
- cmd->scan_end_src == TRIG_COUNT) {
- outl(cmd->scan_end_arg,
- dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG);
- ctrl |= ME4000_AI_CTRL_SC_IRQ;
- }
- ctrl |= ME4000_AI_CTRL_HF_IRQ;
-
- /* Write the setup to the control register */
- outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG);
-
- /* Write the channel list */
- me4000_ai_write_chanlist(dev, s, cmd);
-
- /* Start acquistion by dummy read */
- inl(dev->iobase + ME4000_AI_START_REG);
-
- return 0;
-}
-
-static int me4000_ai_do_cmd_test(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct me4000_private *devpriv = dev->private;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src,
- TRIG_NONE | TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_end_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->start_src == TRIG_NOW &&
- cmd->scan_begin_src == TRIG_TIMER &&
- cmd->convert_src == TRIG_TIMER) {
- devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
- } else if (cmd->start_src == TRIG_NOW &&
- cmd->scan_begin_src == TRIG_FOLLOW &&
- cmd->convert_src == TRIG_TIMER) {
- devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0;
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_TIMER &&
- cmd->convert_src == TRIG_TIMER) {
- devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_FOLLOW &&
- cmd->convert_src == TRIG_TIMER) {
- devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1;
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_EXT &&
- cmd->convert_src == TRIG_TIMER) {
- devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_2;
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_EXT &&
- cmd->convert_src == TRIG_EXT) {
- devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0 |
- ME4000_AI_CTRL_MODE_1;
- } else {
- err |= -EINVAL;
- }
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->chanlist_len < 1) {
- cmd->chanlist_len = 1;
- err |= -EINVAL;
- }
-
- /* Round the timer arguments */
- me4000_ai_round_cmd_args(dev, s, cmd);
-
- if (devpriv->ai_init_ticks < 66) {
- cmd->start_arg = 2000;
- err |= -EINVAL;
- }
- if (devpriv->ai_scan_ticks && devpriv->ai_scan_ticks < 67) {
- cmd->scan_begin_arg = 2031;
- err |= -EINVAL;
- }
- if (devpriv->ai_chan_ticks < 66) {
- cmd->convert_arg = 2000;
- err |= -EINVAL;
- }
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /*
- * Stage 4. Check for argument conflicts.
- */
- if (cmd->start_src == TRIG_NOW &&
- cmd->scan_begin_src == TRIG_TIMER &&
- cmd->convert_src == TRIG_TIMER) {
- /* Check timer arguments */
- if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid start arg\n");
- cmd->start_arg = 2000; /* 66 ticks at least */
- err++;
- }
- if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid convert arg\n");
- cmd->convert_arg = 2000; /* 66 ticks at least */
- err++;
- }
- if (devpriv->ai_scan_ticks <=
- cmd->chanlist_len * devpriv->ai_chan_ticks) {
- dev_err(dev->class_dev, "Invalid scan end arg\n");
-
- /* At least one tick more */
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
- err++;
- }
- } else if (cmd->start_src == TRIG_NOW &&
- cmd->scan_begin_src == TRIG_FOLLOW &&
- cmd->convert_src == TRIG_TIMER) {
- /* Check timer arguments */
- if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid start arg\n");
- cmd->start_arg = 2000; /* 66 ticks at least */
- err++;
- }
- if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid convert arg\n");
- cmd->convert_arg = 2000; /* 66 ticks at least */
- err++;
- }
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_TIMER &&
- cmd->convert_src == TRIG_TIMER) {
- /* Check timer arguments */
- if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid start arg\n");
- cmd->start_arg = 2000; /* 66 ticks at least */
- err++;
- }
- if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid convert arg\n");
- cmd->convert_arg = 2000; /* 66 ticks at least */
- err++;
- }
- if (devpriv->ai_scan_ticks <=
- cmd->chanlist_len * devpriv->ai_chan_ticks) {
- dev_err(dev->class_dev, "Invalid scan end arg\n");
-
- /* At least one tick more */
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;
- err++;
- }
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_FOLLOW &&
- cmd->convert_src == TRIG_TIMER) {
- /* Check timer arguments */
- if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid start arg\n");
- cmd->start_arg = 2000; /* 66 ticks at least */
- err++;
- }
- if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid convert arg\n");
- cmd->convert_arg = 2000; /* 66 ticks at least */
- err++;
- }
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_EXT &&
- cmd->convert_src == TRIG_TIMER) {
- /* Check timer arguments */
- if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid start arg\n");
- cmd->start_arg = 2000; /* 66 ticks at least */
- err++;
- }
- if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid convert arg\n");
- cmd->convert_arg = 2000; /* 66 ticks at least */
- err++;
- }
- } else if (cmd->start_src == TRIG_EXT &&
- cmd->scan_begin_src == TRIG_EXT &&
- cmd->convert_src == TRIG_EXT) {
- /* Check timer arguments */
- if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) {
- dev_err(dev->class_dev, "Invalid start arg\n");
- cmd->start_arg = 2000; /* 66 ticks at least */
- err++;
- }
- }
- if (cmd->scan_end_src == TRIG_COUNT) {
- if (cmd->scan_end_arg == 0) {
- dev_err(dev->class_dev, "Invalid scan end arg\n");
- cmd->scan_end_arg = 1;
- err++;
- }
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= me4000_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
-{
- unsigned int tmp;
- struct comedi_device *dev = dev_id;
- struct comedi_subdevice *s = dev->read_subdev;
- int i;
- int c = 0;
- unsigned short lval;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
- ME4000_IRQ_STATUS_AI_HF) {
- /* Read status register to find out what happened */
- tmp = inl(dev->iobase + ME4000_AI_STATUS_REG);
-
- if (!(tmp & ME4000_AI_STATUS_FF_DATA) &&
- !(tmp & ME4000_AI_STATUS_HF_DATA) &&
- (tmp & ME4000_AI_STATUS_EF_DATA)) {
- dev_err(dev->class_dev, "FIFO overflow\n");
- s->async->events |= COMEDI_CB_ERROR;
- c = ME4000_AI_FIFO_COUNT;
- } else if ((tmp & ME4000_AI_STATUS_FF_DATA) &&
- !(tmp & ME4000_AI_STATUS_HF_DATA) &&
- (tmp & ME4000_AI_STATUS_EF_DATA)) {
- c = ME4000_AI_FIFO_COUNT / 2;
- } else {
- dev_err(dev->class_dev, "Undefined FIFO state\n");
- s->async->events |= COMEDI_CB_ERROR;
- c = 0;
- }
-
- for (i = 0; i < c; i++) {
- lval = me4000_ai_get_sample(dev, s);
- if (!comedi_buf_write_samples(s, &lval, 1))
- break;
- }
-
- /* Work is done, so reset the interrupt */
- tmp |= ME4000_AI_CTRL_HF_IRQ_RESET;
- outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
- tmp &= ~ME4000_AI_CTRL_HF_IRQ_RESET;
- outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
- }
-
- if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) &
- ME4000_IRQ_STATUS_SC) {
- /* Acquisition is complete */
- s->async->events |= COMEDI_CB_EOA;
-
- /* Poll data until fifo empty */
- while (inl(dev->iobase + ME4000_AI_STATUS_REG) &
- ME4000_AI_STATUS_EF_DATA) {
- lval = me4000_ai_get_sample(dev, s);
- if (!comedi_buf_write_samples(s, &lval, 1))
- break;
- }
-
- /* Work is done, so reset the interrupt */
- tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
- tmp |= ME4000_AI_CTRL_SC_IRQ_RESET;
- outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
- tmp &= ~ME4000_AI_CTRL_SC_IRQ_RESET;
- outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
- }
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int me4000_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int tmp;
-
- /* Stop any running conversion */
- tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan));
- tmp |= ME4000_AO_CTRL_IMMEDIATE_STOP;
- outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan));
-
- /* Clear control register and set to single mode */
- outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan));
-
- /* Write data value */
- outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan));
-
- /* Store in the mirror */
- s->readback[chan] = data[0];
-
- return 1;
-}
-
-static int me4000_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- outl((s->state >> 0) & 0xFF,
- dev->iobase + ME4000_DIO_PORT_0_REG);
- outl((s->state >> 8) & 0xFF,
- dev->iobase + ME4000_DIO_PORT_1_REG);
- outl((s->state >> 16) & 0xFF,
- dev->iobase + ME4000_DIO_PORT_2_REG);
- outl((s->state >> 24) & 0xFF,
- dev->iobase + ME4000_DIO_PORT_3_REG);
- }
-
- data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
- ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
- ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
- ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24);
-
- return insn->n;
-}
-
-static int me4000_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- unsigned int tmp;
- int ret;
-
- if (chan < 8)
- mask = 0x000000ff;
- else if (chan < 16)
- mask = 0x0000ff00;
- else if (chan < 24)
- mask = 0x00ff0000;
- else
- mask = 0xff000000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
- tmp &= ~(ME4000_DIO_CTRL_MODE_0 | ME4000_DIO_CTRL_MODE_1 |
- ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3 |
- ME4000_DIO_CTRL_MODE_4 | ME4000_DIO_CTRL_MODE_5 |
- ME4000_DIO_CTRL_MODE_6 | ME4000_DIO_CTRL_MODE_7);
- if (s->io_bits & 0x000000ff)
- tmp |= ME4000_DIO_CTRL_MODE_0;
- if (s->io_bits & 0x0000ff00)
- tmp |= ME4000_DIO_CTRL_MODE_2;
- if (s->io_bits & 0x00ff0000)
- tmp |= ME4000_DIO_CTRL_MODE_4;
- if (s->io_bits & 0xff000000)
- tmp |= ME4000_DIO_CTRL_MODE_6;
-
- /*
- * Check for optoisolated ME-4000 version.
- * If one the first port is a fixed output
- * port and the second is a fixed input port.
- */
- if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
- s->io_bits |= 0x000000ff;
- s->io_bits &= ~0x0000ff00;
- tmp |= ME4000_DIO_CTRL_MODE_0;
- tmp &= ~(ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3);
- }
-
- outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
-
- return insn->n;
-}
-
-static int me4000_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct me4000_board *board = NULL;
- struct me4000_private *devpriv;
- struct comedi_subdevice *s;
- int result;
-
- if (context < ARRAY_SIZE(me4000_boards))
- board = &me4000_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- result = comedi_pci_enable(dev);
- if (result)
- return result;
-
- devpriv->plx_regbase = pci_resource_start(pcidev, 1);
- dev->iobase = pci_resource_start(pcidev, 2);
- if (!devpriv->plx_regbase || !dev->iobase)
- return -ENODEV;
-
- result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE,
- me4000_xilinx_download, 0);
- if (result < 0)
- return result;
-
- me4000_reset(dev);
-
- if (pcidev->irq > 0) {
- result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED,
- dev->board_name, dev);
- if (result == 0) {
- dev->irq = pcidev->irq;
-
- /* Enable interrupts on the PLX */
- outl(PLX9052_INTCSR_LI1ENAB | PLX9052_INTCSR_LI1POL |
- PLX9052_INTCSR_PCIENAB,
- devpriv->plx_regbase + PLX9052_INTCSR);
- }
- }
-
- result = comedi_alloc_subdevices(dev, 4);
- if (result)
- return result;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
- if (board->can_do_diff_ai)
- s->subdev_flags |= SDF_DIFF;
- s->n_chan = board->ai_nchan;
- s->maxdata = 0xffff;
- s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
- s->range_table = &me4000_ai_range;
- s->insn_read = me4000_ai_insn_read;
-
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->cancel = me4000_ai_cancel;
- s->do_cmdtest = me4000_ai_do_cmd_test;
- s->do_cmd = me4000_ai_do_cmd;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_COMMON | SDF_GROUND;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar10;
- s->insn_write = me4000_ao_insn_write;
-
- result = comedi_alloc_subdev_readback(s);
- if (result)
- return result;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = me4000_dio_insn_bits;
- s->insn_config = me4000_dio_insn_config;
-
- /*
- * Check for optoisolated ME-4000 version. If one the first
- * port is a fixed output port and the second is a fixed input port.
- */
- if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) {
- s->io_bits |= 0xFF;
- outl(ME4000_DIO_CTRL_MODE_0,
- dev->iobase + ME4000_DIO_DIR_REG);
- }
-
- /* Counter subdevice (8254) */
- s = &dev->subdevices[3];
- if (board->has_counter) {
- unsigned long timer_base = pci_resource_start(pcidev, 3);
-
- if (!timer_base)
- return -ENODEV;
-
- dev->pacer = comedi_8254_init(timer_base, 0, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- comedi_8254_subdevice_init(s, dev->pacer);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- return 0;
-}
-
-static void me4000_detach(struct comedi_device *dev)
-{
- if (dev->irq) {
- struct me4000_private *devpriv = dev->private;
-
- /* Disable interrupts on the PLX */
- outl(0, devpriv->plx_regbase + PLX9052_INTCSR);
- }
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver me4000_driver = {
- .driver_name = "me4000",
- .module = THIS_MODULE,
- .auto_attach = me4000_auto_attach,
- .detach = me4000_detach,
-};
-
-static int me4000_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
-}
-
-static const struct pci_device_id me4000_pci_table[] = {
- { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
- { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
- { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
- { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
- { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
- { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
- { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
- { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
- { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
- { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
- { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
- { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
- { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, me4000_pci_table);
-
-static struct pci_driver me4000_pci_driver = {
- .name = "me4000",
- .id_table = me4000_pci_table,
- .probe = me4000_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(me4000_driver, me4000_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Meilhaus ME-4000 series boards");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(ME4000_FIRMWARE);
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
deleted file mode 100644
index ef18e387471b..000000000000
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ /dev/null
@@ -1,556 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/me_daq.c
- * Hardware driver for Meilhaus data acquisition cards:
- * ME-2000i, ME-2600i, ME-3000vm1
- *
- * Copyright (C) 2002 Michael Hillmann <hillmann@syscongroup.de>
- */
-
-/*
- * Driver: me_daq
- * Description: Meilhaus PCI data acquisition cards
- * Devices: [Meilhaus] ME-2600i (me-2600i), ME-2000i (me-2000i)
- * Author: Michael Hillmann <hillmann@syscongroup.de>
- * Status: experimental
- *
- * Configuration options: not applicable, uses PCI auto config
- *
- * Supports:
- * Analog Input, Analog Output, Digital I/O
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-
-#include "../comedi_pci.h"
-
-#include "plx9052.h"
-
-#define ME2600_FIRMWARE "me2600_firmware.bin"
-
-#define XILINX_DOWNLOAD_RESET 0x42 /* Xilinx registers */
-
-/*
- * PCI BAR2 Memory map (dev->mmio)
- */
-#define ME_CTRL1_REG 0x00 /* R (ai start) | W */
-#define ME_CTRL1_INT_ENA BIT(15)
-#define ME_CTRL1_COUNTER_B_IRQ BIT(12)
-#define ME_CTRL1_COUNTER_A_IRQ BIT(11)
-#define ME_CTRL1_CHANLIST_READY_IRQ BIT(10)
-#define ME_CTRL1_EXT_IRQ BIT(9)
-#define ME_CTRL1_ADFIFO_HALFFULL_IRQ BIT(8)
-#define ME_CTRL1_SCAN_COUNT_ENA BIT(5)
-#define ME_CTRL1_SIMULTANEOUS_ENA BIT(4)
-#define ME_CTRL1_TRIGGER_FALLING_EDGE BIT(3)
-#define ME_CTRL1_CONTINUOUS_MODE BIT(2)
-#define ME_CTRL1_ADC_MODE(x) (((x) & 0x3) << 0)
-#define ME_CTRL1_ADC_MODE_DISABLE ME_CTRL1_ADC_MODE(0)
-#define ME_CTRL1_ADC_MODE_SOFT_TRIG ME_CTRL1_ADC_MODE(1)
-#define ME_CTRL1_ADC_MODE_SCAN_TRIG ME_CTRL1_ADC_MODE(2)
-#define ME_CTRL1_ADC_MODE_EXT_TRIG ME_CTRL1_ADC_MODE(3)
-#define ME_CTRL1_ADC_MODE_MASK ME_CTRL1_ADC_MODE(3)
-#define ME_CTRL2_REG 0x02 /* R (dac update) | W */
-#define ME_CTRL2_ADFIFO_ENA BIT(10)
-#define ME_CTRL2_CHANLIST_ENA BIT(9)
-#define ME_CTRL2_PORT_B_ENA BIT(7)
-#define ME_CTRL2_PORT_A_ENA BIT(6)
-#define ME_CTRL2_COUNTER_B_ENA BIT(4)
-#define ME_CTRL2_COUNTER_A_ENA BIT(3)
-#define ME_CTRL2_DAC_ENA BIT(1)
-#define ME_CTRL2_BUFFERED_DAC BIT(0)
-#define ME_STATUS_REG 0x04 /* R | W (clears interrupts) */
-#define ME_STATUS_COUNTER_B_IRQ BIT(12)
-#define ME_STATUS_COUNTER_A_IRQ BIT(11)
-#define ME_STATUS_CHANLIST_READY_IRQ BIT(10)
-#define ME_STATUS_EXT_IRQ BIT(9)
-#define ME_STATUS_ADFIFO_HALFFULL_IRQ BIT(8)
-#define ME_STATUS_ADFIFO_FULL BIT(4)
-#define ME_STATUS_ADFIFO_HALFFULL BIT(3)
-#define ME_STATUS_ADFIFO_EMPTY BIT(2)
-#define ME_STATUS_CHANLIST_FULL BIT(1)
-#define ME_STATUS_FST_ACTIVE BIT(0)
-#define ME_DIO_PORT_A_REG 0x06 /* R | W */
-#define ME_DIO_PORT_B_REG 0x08 /* R | W */
-#define ME_TIMER_DATA_REG(x) (0x0a + ((x) * 2)) /* - | W */
-#define ME_AI_FIFO_REG 0x10 /* R (fifo) | W (chanlist) */
-#define ME_AI_FIFO_CHANLIST_DIFF BIT(7)
-#define ME_AI_FIFO_CHANLIST_UNIPOLAR BIT(6)
-#define ME_AI_FIFO_CHANLIST_GAIN(x) (((x) & 0x3) << 4)
-#define ME_AI_FIFO_CHANLIST_CHAN(x) (((x) & 0xf) << 0)
-#define ME_DAC_CTRL_REG 0x12 /* R (updates) | W */
-#define ME_DAC_CTRL_BIPOLAR(x) BIT(7 - ((x) & 0x3))
-#define ME_DAC_CTRL_GAIN(x) BIT(11 - ((x) & 0x3))
-#define ME_DAC_CTRL_MASK(x) (ME_DAC_CTRL_BIPOLAR(x) | \
- ME_DAC_CTRL_GAIN(x))
-#define ME_AO_DATA_REG(x) (0x14 + ((x) * 2)) /* - | W */
-#define ME_COUNTER_ENDDATA_REG(x) (0x1c + ((x) * 2)) /* - | W */
-#define ME_COUNTER_STARTDATA_REG(x) (0x20 + ((x) * 2)) /* - | W */
-#define ME_COUNTER_VALUE_REG(x) (0x20 + ((x) * 2)) /* R | - */
-
-static const struct comedi_lrange me_ai_range = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange me_ao_range = {
- 3, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-enum me_boardid {
- BOARD_ME2600,
- BOARD_ME2000,
-};
-
-struct me_board {
- const char *name;
- int needs_firmware;
- int has_ao;
-};
-
-static const struct me_board me_boards[] = {
- [BOARD_ME2600] = {
- .name = "me-2600i",
- .needs_firmware = 1,
- .has_ao = 1,
- },
- [BOARD_ME2000] = {
- .name = "me-2000i",
- },
-};
-
-struct me_private_data {
- void __iomem *plx_regbase; /* PLX configuration base address */
-
- unsigned short ctrl1; /* Mirror of CONTROL_1 register */
- unsigned short ctrl2; /* Mirror of CONTROL_2 register */
- unsigned short dac_ctrl; /* Mirror of the DAC_CONTROL register */
-};
-
-static inline void sleep(unsigned int sec)
-{
- schedule_timeout_interruptible(sec * HZ);
-}
-
-static int me_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct me_private_data *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 16)
- mask = 0x0000ffff;
- else
- mask = 0xffff0000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- if (s->io_bits & 0x0000ffff)
- devpriv->ctrl2 |= ME_CTRL2_PORT_A_ENA;
- else
- devpriv->ctrl2 &= ~ME_CTRL2_PORT_A_ENA;
- if (s->io_bits & 0xffff0000)
- devpriv->ctrl2 |= ME_CTRL2_PORT_B_ENA;
- else
- devpriv->ctrl2 &= ~ME_CTRL2_PORT_B_ENA;
-
- writew(devpriv->ctrl2, dev->mmio + ME_CTRL2_REG);
-
- return insn->n;
-}
-
-static int me_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- void __iomem *mmio_porta = dev->mmio + ME_DIO_PORT_A_REG;
- void __iomem *mmio_portb = dev->mmio + ME_DIO_PORT_B_REG;
- unsigned int mask;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0x0000ffff)
- writew((s->state & 0xffff), mmio_porta);
- if (mask & 0xffff0000)
- writew(((s->state >> 16) & 0xffff), mmio_portb);
- }
-
- if (s->io_bits & 0x0000ffff)
- val = s->state & 0xffff;
- else
- val = readw(mmio_porta);
-
- if (s->io_bits & 0xffff0000)
- val |= (s->state & 0xffff0000);
- else
- val |= (readw(mmio_portb) << 16);
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int me_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = readw(dev->mmio + ME_STATUS_REG);
- if ((status & ME_STATUS_ADFIFO_EMPTY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int me_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct me_private_data *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- unsigned int val;
- int ret = 0;
- int i;
-
- /*
- * For differential operation, there are only 8 input channels
- * and only bipolar ranges are available.
- */
- if (aref & AREF_DIFF) {
- if (chan > 7 || comedi_range_is_unipolar(s, range))
- return -EINVAL;
- }
-
- /* clear chanlist and ad fifo */
- devpriv->ctrl2 &= ~(ME_CTRL2_ADFIFO_ENA | ME_CTRL2_CHANLIST_ENA);
- writew(devpriv->ctrl2, dev->mmio + ME_CTRL2_REG);
-
- writew(0x00, dev->mmio + ME_STATUS_REG); /* clear interrupts */
-
- /* enable the chanlist and ADC fifo */
- devpriv->ctrl2 |= (ME_CTRL2_ADFIFO_ENA | ME_CTRL2_CHANLIST_ENA);
- writew(devpriv->ctrl2, dev->mmio + ME_CTRL2_REG);
-
- /* write to channel list fifo */
- val = ME_AI_FIFO_CHANLIST_CHAN(chan) | ME_AI_FIFO_CHANLIST_GAIN(range);
- if (comedi_range_is_unipolar(s, range))
- val |= ME_AI_FIFO_CHANLIST_UNIPOLAR;
- if (aref & AREF_DIFF)
- val |= ME_AI_FIFO_CHANLIST_DIFF;
- writew(val, dev->mmio + ME_AI_FIFO_REG);
-
- /* set ADC mode to software trigger */
- devpriv->ctrl1 |= ME_CTRL1_ADC_MODE_SOFT_TRIG;
- writew(devpriv->ctrl1, dev->mmio + ME_CTRL1_REG);
-
- for (i = 0; i < insn->n; i++) {
- /* start ai conversion */
- readw(dev->mmio + ME_CTRL1_REG);
-
- /* wait for ADC fifo not empty flag */
- ret = comedi_timeout(dev, s, insn, me_ai_eoc, 0);
- if (ret)
- break;
-
- /* get value from ADC fifo */
- val = readw(dev->mmio + ME_AI_FIFO_REG) & s->maxdata;
-
- /* munge 2's complement value to offset binary */
- data[i] = comedi_offset_munge(s, val);
- }
-
- /* stop any running conversion */
- devpriv->ctrl1 &= ~ME_CTRL1_ADC_MODE_MASK;
- writew(devpriv->ctrl1, dev->mmio + ME_CTRL1_REG);
-
- return ret ? ret : insn->n;
-}
-
-static int me_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct me_private_data *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- /* Enable all DAC */
- devpriv->ctrl2 |= ME_CTRL2_DAC_ENA;
- writew(devpriv->ctrl2, dev->mmio + ME_CTRL2_REG);
-
- /* and set DAC to "buffered" mode */
- devpriv->ctrl2 |= ME_CTRL2_BUFFERED_DAC;
- writew(devpriv->ctrl2, dev->mmio + ME_CTRL2_REG);
-
- /* Set dac-control register */
- devpriv->dac_ctrl &= ~ME_DAC_CTRL_MASK(chan);
- if (range == 0)
- devpriv->dac_ctrl |= ME_DAC_CTRL_GAIN(chan);
- if (comedi_range_is_bipolar(s, range))
- devpriv->dac_ctrl |= ME_DAC_CTRL_BIPOLAR(chan);
- writew(devpriv->dac_ctrl, dev->mmio + ME_DAC_CTRL_REG);
-
- /* Update dac-control register */
- readw(dev->mmio + ME_DAC_CTRL_REG);
-
- /* Set data register */
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- writew(val, dev->mmio + ME_AO_DATA_REG(chan));
- }
- s->readback[chan] = val;
-
- /* Update dac with data registers */
- readw(dev->mmio + ME_CTRL2_REG);
-
- return insn->n;
-}
-
-static int me2600_xilinx_download(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context)
-{
- struct me_private_data *devpriv = dev->private;
- unsigned int value;
- unsigned int file_length;
- unsigned int i;
-
- /* disable irq's on PLX */
- writel(0x00, devpriv->plx_regbase + PLX9052_INTCSR);
-
- /* First, make a dummy read to reset xilinx */
- value = readw(dev->mmio + XILINX_DOWNLOAD_RESET);
-
- /* Wait until reset is over */
- sleep(1);
-
- /* Write a dummy value to Xilinx */
- writeb(0x00, dev->mmio + 0x0);
- sleep(1);
-
- /*
- * Format of the firmware
- * Build longs from the byte-wise coded header
- * Byte 1-3: length of the array
- * Byte 4-7: version
- * Byte 8-11: date
- * Byte 12-15: reserved
- */
- if (size < 16)
- return -EINVAL;
-
- file_length = (((unsigned int)data[0] & 0xff) << 24) +
- (((unsigned int)data[1] & 0xff) << 16) +
- (((unsigned int)data[2] & 0xff) << 8) +
- ((unsigned int)data[3] & 0xff);
-
- /*
- * Loop for writing firmware byte by byte to xilinx
- * Firmware data start at offset 16
- */
- for (i = 0; i < file_length; i++)
- writeb((data[16 + i] & 0xff), dev->mmio + 0x0);
-
- /* Write 5 dummy values to xilinx */
- for (i = 0; i < 5; i++)
- writeb(0x00, dev->mmio + 0x0);
-
- /* Test if there was an error during download -> INTB was thrown */
- value = readl(devpriv->plx_regbase + PLX9052_INTCSR);
- if (value & PLX9052_INTCSR_LI2STAT) {
- /* Disable interrupt */
- writel(0x00, devpriv->plx_regbase + PLX9052_INTCSR);
- dev_err(dev->class_dev, "Xilinx download failed\n");
- return -EIO;
- }
-
- /* Wait until the Xilinx is ready for real work */
- sleep(1);
-
- /* Enable PLX-Interrupts */
- writel(PLX9052_INTCSR_LI1ENAB |
- PLX9052_INTCSR_LI1POL |
- PLX9052_INTCSR_PCIENAB,
- devpriv->plx_regbase + PLX9052_INTCSR);
-
- return 0;
-}
-
-static int me_reset(struct comedi_device *dev)
-{
- struct me_private_data *devpriv = dev->private;
-
- /* Reset board */
- writew(0x00, dev->mmio + ME_CTRL1_REG);
- writew(0x00, dev->mmio + ME_CTRL2_REG);
- writew(0x00, dev->mmio + ME_STATUS_REG); /* clear interrupts */
- writew(0x00, dev->mmio + ME_DAC_CTRL_REG);
-
- /* Save values in the board context */
- devpriv->dac_ctrl = 0;
- devpriv->ctrl1 = 0;
- devpriv->ctrl2 = 0;
-
- return 0;
-}
-
-static int me_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct me_board *board = NULL;
- struct me_private_data *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- if (context < ARRAY_SIZE(me_boards))
- board = &me_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv->plx_regbase = pci_ioremap_bar(pcidev, 0);
- if (!devpriv->plx_regbase)
- return -ENOMEM;
-
- dev->mmio = pci_ioremap_bar(pcidev, 2);
- if (!dev->mmio)
- return -ENOMEM;
-
- /* Download firmware and reset card */
- if (board->needs_firmware) {
- ret = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
- ME2600_FIRMWARE,
- me2600_xilinx_download, 0);
- if (ret < 0)
- return ret;
- }
- me_reset(dev);
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = 0x0fff;
- s->len_chanlist = 16;
- s->range_table = &me_ai_range;
- s->insn_read = me_ai_insn_read;
-
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_COMMON;
- s->n_chan = 4;
- s->maxdata = 0x0fff;
- s->len_chanlist = 4;
- s->range_table = &me_ao_range;
- s->insn_write = me_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 32;
- s->maxdata = 1;
- s->len_chanlist = 32;
- s->range_table = &range_digital;
- s->insn_bits = me_dio_insn_bits;
- s->insn_config = me_dio_insn_config;
-
- return 0;
-}
-
-static void me_detach(struct comedi_device *dev)
-{
- struct me_private_data *devpriv = dev->private;
-
- if (devpriv) {
- if (dev->mmio)
- me_reset(dev);
- if (devpriv->plx_regbase)
- iounmap(devpriv->plx_regbase);
- }
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver me_daq_driver = {
- .driver_name = "me_daq",
- .module = THIS_MODULE,
- .auto_attach = me_auto_attach,
- .detach = me_detach,
-};
-
-static int me_daq_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &me_daq_driver, id->driver_data);
-}
-
-static const struct pci_device_id me_daq_pci_table[] = {
- { PCI_VDEVICE(MEILHAUS, 0x2600), BOARD_ME2600 },
- { PCI_VDEVICE(MEILHAUS, 0x2000), BOARD_ME2000 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, me_daq_pci_table);
-
-static struct pci_driver me_daq_pci_driver = {
- .name = "me_daq",
- .id_table = me_daq_pci_table,
- .probe = me_daq_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(ME2600_FIRMWARE);
diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c
deleted file mode 100644
index 9da8dd748078..000000000000
--- a/drivers/staging/comedi/drivers/mf6x4.c
+++ /dev/null
@@ -1,311 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/mf6x4.c
- * Driver for Humusoft MF634 and MF624 Data acquisition cards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-/*
- * Driver: mf6x4
- * Description: Humusoft MF634 and MF624 Data acquisition card driver
- * Devices: [Humusoft] MF634 (mf634), MF624 (mf624)
- * Author: Rostislav Lisovy <lisovy@gmail.com>
- * Status: works
- * Updated:
- * Configuration Options: none
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedi_pci.h"
-
-/* Registers present in BAR0 memory region */
-#define MF624_GPIOC_REG 0x54
-
-#define MF6X4_GPIOC_EOLC BIT(17) /* End Of Last Conversion */
-#define MF6X4_GPIOC_LDAC BIT(23) /* Load DACs */
-#define MF6X4_GPIOC_DACEN BIT(26)
-
-/* BAR1 registers */
-#define MF6X4_ADDATA_REG 0x00
-#define MF6X4_ADCTRL_REG 0x00
-#define MF6X4_ADCTRL_CHAN(x) BIT(chan)
-#define MF6X4_DIN_REG 0x10
-#define MF6X4_DIN_MASK 0xff
-#define MF6X4_DOUT_REG 0x10
-#define MF6X4_ADSTART_REG 0x20
-#define MF6X4_DAC_REG(x) (0x20 + ((x) * 2))
-
-/* BAR2 registers */
-#define MF634_GPIOC_REG 0x68
-
-enum mf6x4_boardid {
- BOARD_MF634,
- BOARD_MF624,
-};
-
-struct mf6x4_board {
- const char *name;
- /* We need to keep track of the order of BARs used by the cards */
- unsigned int bar_nums[3];
-};
-
-static const struct mf6x4_board mf6x4_boards[] = {
- [BOARD_MF634] = {
- .name = "mf634",
- .bar_nums = {0, 2, 3},
- },
- [BOARD_MF624] = {
- .name = "mf624",
- .bar_nums = {0, 2, 4},
- },
-};
-
-struct mf6x4_private {
- /*
- * Documentation for both MF634 and MF624 describes registers
- * present in BAR0, 1 and 2 regions.
- * The real (i.e. in HW) BAR numbers are different for MF624
- * and MF634 yet we will call them 0, 1, 2
- */
- void __iomem *bar0_mem;
- void __iomem *bar2_mem;
-
- /*
- * This configuration register has the same function and fields
- * for both cards however it lies in different BARs on different
- * offsets -- this variable makes the access easier
- */
- void __iomem *gpioc_reg;
-};
-
-static int mf6x4_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = ioread16(dev->mmio + MF6X4_DIN_REG) & MF6X4_DIN_MASK;
-
- return insn->n;
-}
-
-static int mf6x4_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- iowrite16(s->state, dev->mmio + MF6X4_DOUT_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int mf6x4_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- struct mf6x4_private *devpriv = dev->private;
- unsigned int status;
-
- /* EOLC goes low at end of conversion. */
- status = ioread32(devpriv->gpioc_reg);
- if ((status & MF6X4_GPIOC_EOLC) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int mf6x4_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int d;
- int ret;
- int i;
-
- /* Set the ADC channel number in the scan list */
- iowrite16(MF6X4_ADCTRL_CHAN(chan), dev->mmio + MF6X4_ADCTRL_REG);
-
- for (i = 0; i < insn->n; i++) {
- /* Trigger ADC conversion by reading ADSTART */
- ioread16(dev->mmio + MF6X4_ADSTART_REG);
-
- ret = comedi_timeout(dev, s, insn, mf6x4_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* Read the actual value */
- d = ioread16(dev->mmio + MF6X4_ADDATA_REG);
- d &= s->maxdata;
- /* munge the 2's complement data to offset binary */
- data[i] = comedi_offset_munge(s, d);
- }
-
- iowrite16(0x0, dev->mmio + MF6X4_ADCTRL_REG);
-
- return insn->n;
-}
-
-static int mf6x4_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct mf6x4_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- unsigned int gpioc;
- int i;
-
- /* Enable instantaneous update of converters outputs + Enable DACs */
- gpioc = ioread32(devpriv->gpioc_reg);
- iowrite32((gpioc & ~MF6X4_GPIOC_LDAC) | MF6X4_GPIOC_DACEN,
- devpriv->gpioc_reg);
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- iowrite16(val, dev->mmio + MF6X4_DAC_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int mf6x4_auto_attach(struct comedi_device *dev, unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct mf6x4_board *board = NULL;
- struct mf6x4_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- if (context < ARRAY_SIZE(mf6x4_boards))
- board = &mf6x4_boards[context];
- else
- return -ENODEV;
-
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- devpriv->bar0_mem = pci_ioremap_bar(pcidev, board->bar_nums[0]);
- if (!devpriv->bar0_mem)
- return -ENODEV;
-
- dev->mmio = pci_ioremap_bar(pcidev, board->bar_nums[1]);
- if (!dev->mmio)
- return -ENODEV;
-
- devpriv->bar2_mem = pci_ioremap_bar(pcidev, board->bar_nums[2]);
- if (!devpriv->bar2_mem)
- return -ENODEV;
-
- if (board == &mf6x4_boards[BOARD_MF634])
- devpriv->gpioc_reg = devpriv->bar2_mem + MF634_GPIOC_REG;
- else
- devpriv->gpioc_reg = devpriv->bar0_mem + MF624_GPIOC_REG;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 8;
- s->maxdata = 0x3fff;
- s->range_table = &range_bipolar10;
- s->insn_read = mf6x4_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 0x3fff;
- s->range_table = &range_bipolar10;
- s->insn_write = mf6x4_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = mf6x4_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = mf6x4_do_insn_bits;
-
- return 0;
-}
-
-static void mf6x4_detach(struct comedi_device *dev)
-{
- struct mf6x4_private *devpriv = dev->private;
-
- if (devpriv) {
- if (devpriv->bar0_mem)
- iounmap(devpriv->bar0_mem);
- if (devpriv->bar2_mem)
- iounmap(devpriv->bar2_mem);
- }
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver mf6x4_driver = {
- .driver_name = "mf6x4",
- .module = THIS_MODULE,
- .auto_attach = mf6x4_auto_attach,
- .detach = mf6x4_detach,
-};
-
-static int mf6x4_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &mf6x4_driver, id->driver_data);
-}
-
-static const struct pci_device_id mf6x4_pci_table[] = {
- { PCI_VDEVICE(HUMUSOFT, 0x0634), BOARD_MF634 },
- { PCI_VDEVICE(HUMUSOFT, 0x0624), BOARD_MF624 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, mf6x4_pci_table);
-
-static struct pci_driver mf6x4_pci_driver = {
- .name = "mf6x4",
- .id_table = mf6x4_pci_table,
- .probe = mf6x4_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-
-module_comedi_pci_driver(mf6x4_driver, mf6x4_pci_driver);
-
-MODULE_AUTHOR("Rostislav Lisovy <lisovy@gmail.com>");
-MODULE_DESCRIPTION("Comedi MF634 and MF624 DAQ cards driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
deleted file mode 100644
index 70960e3ba878..000000000000
--- a/drivers/staging/comedi/drivers/mite.c
+++ /dev/null
@@ -1,938 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/mite.c
- * Hardware driver for NI Mite PCI interface chip
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2002 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * The PCI-MIO E series driver was originally written by
- * Tomasz Motylewski <...>, and ported to comedi by ds.
- *
- * References for specifications:
- *
- * 321747b.pdf Register Level Programmer Manual (obsolete)
- * 321747c.pdf Register Level Programmer Manual (new)
- * DAQ-STC reference manual
- *
- * Other possibly relevant info:
- *
- * 320517c.pdf User manual (obsolete)
- * 320517f.pdf User manual (new)
- * 320889a.pdf delete
- * 320906c.pdf maximum signal ratings
- * 321066a.pdf about 16x
- * 321791a.pdf discontinuation of at-mio-16e-10 rev. c
- * 321808a.pdf about at-mio-16e-10 rev P
- * 321837a.pdf discontinuation of at-mio-16de-10 rev d
- * 321838a.pdf about at-mio-16de-10 rev N
- *
- * ISSUES:
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/log2.h>
-
-#include "../comedi_pci.h"
-
-#include "mite.h"
-
-/*
- * Mite registers
- */
-#define MITE_UNKNOWN_DMA_BURST_REG 0x28
-#define UNKNOWN_DMA_BURST_ENABLE_BITS 0x600
-
-#define MITE_PCI_CONFIG_OFFSET 0x300
-#define MITE_CSIGR 0x460 /* chip signature */
-#define CSIGR_TO_IOWINS(x) (((x) >> 29) & 0x7)
-#define CSIGR_TO_WINS(x) (((x) >> 24) & 0x1f)
-#define CSIGR_TO_WPDEP(x) (((x) >> 20) & 0x7)
-#define CSIGR_TO_DMAC(x) (((x) >> 16) & 0xf)
-#define CSIGR_TO_IMODE(x) (((x) >> 12) & 0x3) /* pci=0x3 */
-#define CSIGR_TO_MMODE(x) (((x) >> 8) & 0x3) /* minimite=1 */
-#define CSIGR_TO_TYPE(x) (((x) >> 4) & 0xf) /* mite=0, minimite=1 */
-#define CSIGR_TO_VER(x) (((x) >> 0) & 0xf)
-
-#define MITE_CHAN(x) (0x500 + 0x100 * (x))
-#define MITE_CHOR(x) (0x00 + MITE_CHAN(x)) /* channel operation */
-#define CHOR_DMARESET BIT(31)
-#define CHOR_SET_SEND_TC BIT(11)
-#define CHOR_CLR_SEND_TC BIT(10)
-#define CHOR_SET_LPAUSE BIT(9)
-#define CHOR_CLR_LPAUSE BIT(8)
-#define CHOR_CLRDONE BIT(7)
-#define CHOR_CLRRB BIT(6)
-#define CHOR_CLRLC BIT(5)
-#define CHOR_FRESET BIT(4)
-#define CHOR_ABORT BIT(3) /* stop without emptying fifo */
-#define CHOR_STOP BIT(2) /* stop after emptying fifo */
-#define CHOR_CONT BIT(1)
-#define CHOR_START BIT(0)
-#define MITE_CHCR(x) (0x04 + MITE_CHAN(x)) /* channel control */
-#define CHCR_SET_DMA_IE BIT(31)
-#define CHCR_CLR_DMA_IE BIT(30)
-#define CHCR_SET_LINKP_IE BIT(29)
-#define CHCR_CLR_LINKP_IE BIT(28)
-#define CHCR_SET_SAR_IE BIT(27)
-#define CHCR_CLR_SAR_IE BIT(26)
-#define CHCR_SET_DONE_IE BIT(25)
-#define CHCR_CLR_DONE_IE BIT(24)
-#define CHCR_SET_MRDY_IE BIT(23)
-#define CHCR_CLR_MRDY_IE BIT(22)
-#define CHCR_SET_DRDY_IE BIT(21)
-#define CHCR_CLR_DRDY_IE BIT(20)
-#define CHCR_SET_LC_IE BIT(19)
-#define CHCR_CLR_LC_IE BIT(18)
-#define CHCR_SET_CONT_RB_IE BIT(17)
-#define CHCR_CLR_CONT_RB_IE BIT(16)
-#define CHCR_FIFO(x) (((x) & 0x1) << 15)
-#define CHCR_FIFODIS CHCR_FIFO(1)
-#define CHCR_FIFO_ON CHCR_FIFO(0)
-#define CHCR_BURST(x) (((x) & 0x1) << 14)
-#define CHCR_BURSTEN CHCR_BURST(1)
-#define CHCR_NO_BURSTEN CHCR_BURST(0)
-#define CHCR_BYTE_SWAP_DEVICE BIT(6)
-#define CHCR_BYTE_SWAP_MEMORY BIT(4)
-#define CHCR_DIR(x) (((x) & 0x1) << 3)
-#define CHCR_DEV_TO_MEM CHCR_DIR(1)
-#define CHCR_MEM_TO_DEV CHCR_DIR(0)
-#define CHCR_MODE(x) (((x) & 0x7) << 0)
-#define CHCR_NORMAL CHCR_MODE(0)
-#define CHCR_CONTINUE CHCR_MODE(1)
-#define CHCR_RINGBUFF CHCR_MODE(2)
-#define CHCR_LINKSHORT CHCR_MODE(4)
-#define CHCR_LINKLONG CHCR_MODE(5)
-#define MITE_TCR(x) (0x08 + MITE_CHAN(x)) /* transfer count */
-#define MITE_MCR(x) (0x0c + MITE_CHAN(x)) /* memory config */
-#define MITE_MAR(x) (0x10 + MITE_CHAN(x)) /* memory address */
-#define MITE_DCR(x) (0x14 + MITE_CHAN(x)) /* device config */
-#define DCR_NORMAL BIT(29)
-#define MITE_DAR(x) (0x18 + MITE_CHAN(x)) /* device address */
-#define MITE_LKCR(x) (0x1c + MITE_CHAN(x)) /* link config */
-#define MITE_LKAR(x) (0x20 + MITE_CHAN(x)) /* link address */
-#define MITE_LLKAR(x) (0x24 + MITE_CHAN(x)) /* see tnt5002 manual */
-#define MITE_BAR(x) (0x28 + MITE_CHAN(x)) /* base address */
-#define MITE_BCR(x) (0x2c + MITE_CHAN(x)) /* base count */
-#define MITE_SAR(x) (0x30 + MITE_CHAN(x)) /* ? address */
-#define MITE_WSCR(x) (0x34 + MITE_CHAN(x)) /* ? */
-#define MITE_WSER(x) (0x38 + MITE_CHAN(x)) /* ? */
-#define MITE_CHSR(x) (0x3c + MITE_CHAN(x)) /* channel status */
-#define CHSR_INT BIT(31)
-#define CHSR_LPAUSES BIT(29)
-#define CHSR_SARS BIT(27)
-#define CHSR_DONE BIT(25)
-#define CHSR_MRDY BIT(23)
-#define CHSR_DRDY BIT(21)
-#define CHSR_LINKC BIT(19)
-#define CHSR_CONTS_RB BIT(17)
-#define CHSR_ERROR BIT(15)
-#define CHSR_SABORT BIT(14)
-#define CHSR_HABORT BIT(13)
-#define CHSR_STOPS BIT(12)
-#define CHSR_OPERR(x) (((x) & 0x3) << 10)
-#define CHSR_OPERR_MASK CHSR_OPERR(3)
-#define CHSR_OPERR_NOERROR CHSR_OPERR(0)
-#define CHSR_OPERR_FIFOERROR CHSR_OPERR(1)
-#define CHSR_OPERR_LINKERROR CHSR_OPERR(1) /* ??? */
-#define CHSR_XFERR BIT(9)
-#define CHSR_END BIT(8)
-#define CHSR_DRQ1 BIT(7)
-#define CHSR_DRQ0 BIT(6)
-#define CHSR_LERR(x) (((x) & 0x3) << 4)
-#define CHSR_LERR_MASK CHSR_LERR(3)
-#define CHSR_LBERR CHSR_LERR(1)
-#define CHSR_LRERR CHSR_LERR(2)
-#define CHSR_LOERR CHSR_LERR(3)
-#define CHSR_MERR(x) (((x) & 0x3) << 2)
-#define CHSR_MERR_MASK CHSR_MERR(3)
-#define CHSR_MBERR CHSR_MERR(1)
-#define CHSR_MRERR CHSR_MERR(2)
-#define CHSR_MOERR CHSR_MERR(3)
-#define CHSR_DERR(x) (((x) & 0x3) << 0)
-#define CHSR_DERR_MASK CHSR_DERR(3)
-#define CHSR_DBERR CHSR_DERR(1)
-#define CHSR_DRERR CHSR_DERR(2)
-#define CHSR_DOERR CHSR_DERR(3)
-#define MITE_FCR(x) (0x40 + MITE_CHAN(x)) /* fifo count */
-
-/* common bits for the memory/device/link config registers */
-#define CR_RL(x) (((x) & 0x7) << 21)
-#define CR_REQS(x) (((x) & 0x7) << 16)
-#define CR_REQS_MASK CR_REQS(7)
-#define CR_ASEQ(x) (((x) & 0x3) << 10)
-#define CR_ASEQDONT CR_ASEQ(0)
-#define CR_ASEQUP CR_ASEQ(1)
-#define CR_ASEQDOWN CR_ASEQ(2)
-#define CR_ASEQ_MASK CR_ASEQ(3)
-#define CR_PSIZE(x) (((x) & 0x3) << 8)
-#define CR_PSIZE8 CR_PSIZE(1)
-#define CR_PSIZE16 CR_PSIZE(2)
-#define CR_PSIZE32 CR_PSIZE(3)
-#define CR_PORT(x) (((x) & 0x3) << 6)
-#define CR_PORTCPU CR_PORT(0)
-#define CR_PORTIO CR_PORT(1)
-#define CR_PORTVXI CR_PORT(2)
-#define CR_PORTMXI CR_PORT(3)
-#define CR_AMDEVICE BIT(0)
-
-static unsigned int MITE_IODWBSR_1_WSIZE_bits(unsigned int size)
-{
- return (ilog2(size) - 1) & 0x1f;
-}
-
-static unsigned int mite_retry_limit(unsigned int retry_limit)
-{
- unsigned int value = 0;
-
- if (retry_limit)
- value = 1 + ilog2(retry_limit);
- if (value > 0x7)
- value = 0x7;
- return CR_RL(value);
-}
-
-static unsigned int mite_drq_reqs(unsigned int drq_line)
-{
- /* This also works on m-series when using channels (drq_line) 4 or 5. */
- return CR_REQS((drq_line & 0x3) | 0x4);
-}
-
-static unsigned int mite_fifo_size(struct mite *mite, unsigned int channel)
-{
- unsigned int fcr_bits = readl(mite->mmio + MITE_FCR(channel));
- unsigned int empty_count = (fcr_bits >> 16) & 0xff;
- unsigned int full_count = fcr_bits & 0xff;
-
- return empty_count + full_count;
-}
-
-static u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
-{
- struct mite *mite = mite_chan->mite;
-
- return readl(mite->mmio + MITE_DAR(mite_chan->channel));
-}
-
-/**
- * mite_bytes_in_transit() - Returns the number of unread bytes in the fifo.
- * @mite_chan: MITE dma channel.
- */
-u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
-{
- struct mite *mite = mite_chan->mite;
-
- return readl(mite->mmio + MITE_FCR(mite_chan->channel)) & 0xff;
-}
-EXPORT_SYMBOL_GPL(mite_bytes_in_transit);
-
-/* returns lower bound for number of bytes transferred from device to memory */
-static u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
-{
- u32 device_byte_count;
-
- device_byte_count = mite_device_bytes_transferred(mite_chan);
- return device_byte_count - mite_bytes_in_transit(mite_chan);
-}
-
-/* returns upper bound for number of bytes transferred from device to memory */
-static u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
-{
- u32 in_transit_count;
-
- in_transit_count = mite_bytes_in_transit(mite_chan);
- return mite_device_bytes_transferred(mite_chan) - in_transit_count;
-}
-
-/* returns lower bound for number of bytes read from memory to device */
-static u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
-{
- u32 device_byte_count;
-
- device_byte_count = mite_device_bytes_transferred(mite_chan);
- return device_byte_count + mite_bytes_in_transit(mite_chan);
-}
-
-/* returns upper bound for number of bytes read from memory to device */
-static u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
-{
- u32 in_transit_count;
-
- in_transit_count = mite_bytes_in_transit(mite_chan);
- return mite_device_bytes_transferred(mite_chan) + in_transit_count;
-}
-
-static void mite_sync_input_dma(struct mite_channel *mite_chan,
- struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- int count;
- unsigned int nbytes, old_alloc_count;
-
- old_alloc_count = async->buf_write_alloc_count;
- /* write alloc as much as we can */
- comedi_buf_write_alloc(s, async->prealloc_bufsz);
-
- nbytes = mite_bytes_written_to_memory_lb(mite_chan);
- if ((int)(mite_bytes_written_to_memory_ub(mite_chan) -
- old_alloc_count) > 0) {
- dev_warn(s->device->class_dev,
- "mite: DMA overwrite of free area\n");
- async->events |= COMEDI_CB_OVERFLOW;
- return;
- }
-
- count = nbytes - async->buf_write_count;
- /*
- * it's possible count will be negative due to conservative value
- * returned by mite_bytes_written_to_memory_lb
- */
- if (count > 0) {
- comedi_buf_write_free(s, count);
- comedi_inc_scan_progress(s, count);
- async->events |= COMEDI_CB_BLOCK;
- }
-}
-
-static void mite_sync_output_dma(struct mite_channel *mite_chan,
- struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u32 stop_count = cmd->stop_arg * comedi_bytes_per_scan(s);
- unsigned int old_alloc_count = async->buf_read_alloc_count;
- u32 nbytes_ub, nbytes_lb;
- int count;
- bool finite_regen = (cmd->stop_src == TRIG_NONE && stop_count != 0);
-
- /* read alloc as much as we can */
- comedi_buf_read_alloc(s, async->prealloc_bufsz);
- nbytes_lb = mite_bytes_read_from_memory_lb(mite_chan);
- if (cmd->stop_src == TRIG_COUNT && (int)(nbytes_lb - stop_count) > 0)
- nbytes_lb = stop_count;
- nbytes_ub = mite_bytes_read_from_memory_ub(mite_chan);
- if (cmd->stop_src == TRIG_COUNT && (int)(nbytes_ub - stop_count) > 0)
- nbytes_ub = stop_count;
-
- if ((!finite_regen || stop_count > old_alloc_count) &&
- ((int)(nbytes_ub - old_alloc_count) > 0)) {
- dev_warn(s->device->class_dev, "mite: DMA underrun\n");
- async->events |= COMEDI_CB_OVERFLOW;
- return;
- }
-
- if (finite_regen) {
- /*
- * This is a special case where we continuously output a finite
- * buffer. In this case, we do not free any of the memory,
- * hence we expect that old_alloc_count will reach a maximum of
- * stop_count bytes.
- */
- return;
- }
-
- count = nbytes_lb - async->buf_read_count;
- if (count > 0) {
- comedi_buf_read_free(s, count);
- async->events |= COMEDI_CB_BLOCK;
- }
-}
-
-/**
- * mite_sync_dma() - Sync the MITE dma with the COMEDI async buffer.
- * @mite_chan: MITE dma channel.
- * @s: COMEDI subdevice.
- */
-void mite_sync_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s)
-{
- if (mite_chan->dir == COMEDI_INPUT)
- mite_sync_input_dma(mite_chan, s);
- else
- mite_sync_output_dma(mite_chan, s);
-}
-EXPORT_SYMBOL_GPL(mite_sync_dma);
-
-static unsigned int mite_get_status(struct mite_channel *mite_chan)
-{
- struct mite *mite = mite_chan->mite;
- unsigned int status;
- unsigned long flags;
-
- spin_lock_irqsave(&mite->lock, flags);
- status = readl(mite->mmio + MITE_CHSR(mite_chan->channel));
- if (status & CHSR_DONE) {
- mite_chan->done = 1;
- writel(CHOR_CLRDONE,
- mite->mmio + MITE_CHOR(mite_chan->channel));
- }
- spin_unlock_irqrestore(&mite->lock, flags);
- return status;
-}
-
-/**
- * mite_ack_linkc() - Check and ack the LINKC interrupt,
- * @mite_chan: MITE dma channel.
- * @s: COMEDI subdevice.
- * @sync: flag to force a mite_sync_dma().
- *
- * This will also ack the DONE interrupt if active.
- */
-void mite_ack_linkc(struct mite_channel *mite_chan,
- struct comedi_subdevice *s,
- bool sync)
-{
- struct mite *mite = mite_chan->mite;
- unsigned int status;
-
- status = mite_get_status(mite_chan);
- if (status & CHSR_LINKC) {
- writel(CHOR_CLRLC, mite->mmio + MITE_CHOR(mite_chan->channel));
- sync = true;
- }
- if (sync)
- mite_sync_dma(mite_chan, s);
-
- if (status & CHSR_XFERR) {
- dev_err(s->device->class_dev,
- "mite: transfer error %08x\n", status);
- s->async->events |= COMEDI_CB_ERROR;
- }
-}
-EXPORT_SYMBOL_GPL(mite_ack_linkc);
-
-/**
- * mite_done() - Check is a MITE dma transfer is complete.
- * @mite_chan: MITE dma channel.
- *
- * This will also ack the DONE interrupt if active.
- */
-int mite_done(struct mite_channel *mite_chan)
-{
- struct mite *mite = mite_chan->mite;
- unsigned long flags;
- int done;
-
- mite_get_status(mite_chan);
- spin_lock_irqsave(&mite->lock, flags);
- done = mite_chan->done;
- spin_unlock_irqrestore(&mite->lock, flags);
- return done;
-}
-EXPORT_SYMBOL_GPL(mite_done);
-
-static void mite_dma_reset(struct mite_channel *mite_chan)
-{
- writel(CHOR_DMARESET | CHOR_FRESET,
- mite_chan->mite->mmio + MITE_CHOR(mite_chan->channel));
-}
-
-/**
- * mite_dma_arm() - Start a MITE dma transfer.
- * @mite_chan: MITE dma channel.
- */
-void mite_dma_arm(struct mite_channel *mite_chan)
-{
- struct mite *mite = mite_chan->mite;
- unsigned long flags;
-
- /*
- * memory barrier is intended to insure any twiddling with the buffer
- * is done before writing to the mite to arm dma transfer
- */
- smp_mb();
- spin_lock_irqsave(&mite->lock, flags);
- mite_chan->done = 0;
- /* arm */
- writel(CHOR_START, mite->mmio + MITE_CHOR(mite_chan->channel));
- spin_unlock_irqrestore(&mite->lock, flags);
-}
-EXPORT_SYMBOL_GPL(mite_dma_arm);
-
-/**
- * mite_dma_disarm() - Stop a MITE dma transfer.
- * @mite_chan: MITE dma channel.
- */
-void mite_dma_disarm(struct mite_channel *mite_chan)
-{
- struct mite *mite = mite_chan->mite;
-
- /* disarm */
- writel(CHOR_ABORT, mite->mmio + MITE_CHOR(mite_chan->channel));
-}
-EXPORT_SYMBOL_GPL(mite_dma_disarm);
-
-/**
- * mite_prep_dma() - Prepare a MITE dma channel for transfers.
- * @mite_chan: MITE dma channel.
- * @num_device_bits: device transfer size (8, 16, or 32-bits).
- * @num_memory_bits: memory transfer size (8, 16, or 32-bits).
- */
-void mite_prep_dma(struct mite_channel *mite_chan,
- unsigned int num_device_bits, unsigned int num_memory_bits)
-{
- struct mite *mite = mite_chan->mite;
- unsigned int chcr, mcr, dcr, lkcr;
-
- mite_dma_reset(mite_chan);
-
- /* short link chaining mode */
- chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE |
- CHCR_BURSTEN;
- /*
- * Link Complete Interrupt: interrupt every time a link
- * in MITE_RING is completed. This can generate a lot of
- * extra interrupts, but right now we update the values
- * of buf_int_ptr and buf_int_count at each interrupt. A
- * better method is to poll the MITE before each user
- * "read()" to calculate the number of bytes available.
- */
- chcr |= CHCR_SET_LC_IE;
- if (num_memory_bits == 32 && num_device_bits == 16) {
- /*
- * Doing a combined 32 and 16 bit byteswap gets the 16 bit
- * samples into the fifo in the right order. Tested doing 32 bit
- * memory to 16 bit device transfers to the analog out of a
- * pxi-6281, which has mite version = 1, type = 4. This also
- * works for dma reads from the counters on e-series boards.
- */
- chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
- }
- if (mite_chan->dir == COMEDI_INPUT)
- chcr |= CHCR_DEV_TO_MEM;
-
- writel(chcr, mite->mmio + MITE_CHCR(mite_chan->channel));
-
- /* to/from memory */
- mcr = mite_retry_limit(64) | CR_ASEQUP;
- switch (num_memory_bits) {
- case 8:
- mcr |= CR_PSIZE8;
- break;
- case 16:
- mcr |= CR_PSIZE16;
- break;
- case 32:
- mcr |= CR_PSIZE32;
- break;
- default:
- pr_warn("bug! invalid mem bit width for dma transfer\n");
- break;
- }
- writel(mcr, mite->mmio + MITE_MCR(mite_chan->channel));
-
- /* from/to device */
- dcr = mite_retry_limit(64) | CR_ASEQUP;
- dcr |= CR_PORTIO | CR_AMDEVICE | mite_drq_reqs(mite_chan->channel);
- switch (num_device_bits) {
- case 8:
- dcr |= CR_PSIZE8;
- break;
- case 16:
- dcr |= CR_PSIZE16;
- break;
- case 32:
- dcr |= CR_PSIZE32;
- break;
- default:
- pr_warn("bug! invalid dev bit width for dma transfer\n");
- break;
- }
- writel(dcr, mite->mmio + MITE_DCR(mite_chan->channel));
-
- /* reset the DAR */
- writel(0, mite->mmio + MITE_DAR(mite_chan->channel));
-
- /* the link is 32bits */
- lkcr = mite_retry_limit(64) | CR_ASEQUP | CR_PSIZE32;
- writel(lkcr, mite->mmio + MITE_LKCR(mite_chan->channel));
-
- /* starting address for link chaining */
- writel(mite_chan->ring->dma_addr,
- mite->mmio + MITE_LKAR(mite_chan->channel));
-}
-EXPORT_SYMBOL_GPL(mite_prep_dma);
-
-/**
- * mite_request_channel_in_range() - Request a MITE dma channel.
- * @mite: MITE device.
- * @ring: MITE dma ring.
- * @min_channel: minimum channel index to use.
- * @max_channel: maximum channel index to use.
- */
-struct mite_channel *mite_request_channel_in_range(struct mite *mite,
- struct mite_ring *ring,
- unsigned int min_channel,
- unsigned int max_channel)
-{
- struct mite_channel *mite_chan = NULL;
- unsigned long flags;
- int i;
-
- /*
- * spin lock so mite_release_channel can be called safely
- * from interrupts
- */
- spin_lock_irqsave(&mite->lock, flags);
- for (i = min_channel; i <= max_channel; ++i) {
- mite_chan = &mite->channels[i];
- if (!mite_chan->ring) {
- mite_chan->ring = ring;
- break;
- }
- mite_chan = NULL;
- }
- spin_unlock_irqrestore(&mite->lock, flags);
- return mite_chan;
-}
-EXPORT_SYMBOL_GPL(mite_request_channel_in_range);
-
-/**
- * mite_request_channel() - Request a MITE dma channel.
- * @mite: MITE device.
- * @ring: MITE dma ring.
- */
-struct mite_channel *mite_request_channel(struct mite *mite,
- struct mite_ring *ring)
-{
- return mite_request_channel_in_range(mite, ring, 0,
- mite->num_channels - 1);
-}
-EXPORT_SYMBOL_GPL(mite_request_channel);
-
-/**
- * mite_release_channel() - Release a MITE dma channel.
- * @mite_chan: MITE dma channel.
- */
-void mite_release_channel(struct mite_channel *mite_chan)
-{
- struct mite *mite = mite_chan->mite;
- unsigned long flags;
-
- /* spin lock to prevent races with mite_request_channel */
- spin_lock_irqsave(&mite->lock, flags);
- if (mite_chan->ring) {
- mite_dma_disarm(mite_chan);
- mite_dma_reset(mite_chan);
- /*
- * disable all channel's interrupts (do it after disarm/reset so
- * MITE_CHCR reg isn't changed while dma is still active!)
- */
- writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE |
- CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE |
- CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
- CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
- mite->mmio + MITE_CHCR(mite_chan->channel));
- mite_chan->ring = NULL;
- }
- spin_unlock_irqrestore(&mite->lock, flags);
-}
-EXPORT_SYMBOL_GPL(mite_release_channel);
-
-/**
- * mite_init_ring_descriptors() - Initialize a MITE dma ring descriptors.
- * @ring: MITE dma ring.
- * @s: COMEDI subdevice.
- * @nbytes: the size of the dma ring (in bytes).
- *
- * Initializes the ring buffer descriptors to provide correct DMA transfer
- * links to the exact amount of memory required. When the ring buffer is
- * allocated by mite_buf_change(), the default is to initialize the ring
- * to refer to the entire DMA data buffer. A command may call this function
- * later to re-initialize and shorten the amount of memory that will be
- * transferred.
- */
-int mite_init_ring_descriptors(struct mite_ring *ring,
- struct comedi_subdevice *s,
- unsigned int nbytes)
-{
- struct comedi_async *async = s->async;
- struct mite_dma_desc *desc = NULL;
- unsigned int n_full_links = nbytes >> PAGE_SHIFT;
- unsigned int remainder = nbytes % PAGE_SIZE;
- int i;
-
- dev_dbg(s->device->class_dev,
- "mite: init ring buffer to %u bytes\n", nbytes);
-
- if ((n_full_links + (remainder > 0 ? 1 : 0)) > ring->n_links) {
- dev_err(s->device->class_dev,
- "mite: ring buffer too small for requested init\n");
- return -ENOMEM;
- }
-
- /* We set the descriptors for all full links. */
- for (i = 0; i < n_full_links; ++i) {
- desc = &ring->descs[i];
- desc->count = cpu_to_le32(PAGE_SIZE);
- desc->addr = cpu_to_le32(async->buf_map->page_list[i].dma_addr);
- desc->next = cpu_to_le32(ring->dma_addr +
- (i + 1) * sizeof(*desc));
- }
-
- /* the last link is either a remainder or was a full link. */
- if (remainder > 0) {
- desc = &ring->descs[i];
- /* set the lesser count for the remainder link */
- desc->count = cpu_to_le32(remainder);
- desc->addr = cpu_to_le32(async->buf_map->page_list[i].dma_addr);
- }
-
- /* Assign the last link->next to point back to the head of the list. */
- desc->next = cpu_to_le32(ring->dma_addr);
-
- /*
- * barrier is meant to insure that all the writes to the dma descriptors
- * have completed before the dma controller is commanded to read them
- */
- smp_wmb();
- return 0;
-}
-EXPORT_SYMBOL_GPL(mite_init_ring_descriptors);
-
-static void mite_free_dma_descs(struct mite_ring *ring)
-{
- struct mite_dma_desc *descs = ring->descs;
-
- if (descs) {
- dma_free_coherent(ring->hw_dev,
- ring->n_links * sizeof(*descs),
- descs, ring->dma_addr);
- ring->descs = NULL;
- ring->dma_addr = 0;
- ring->n_links = 0;
- }
-}
-
-/**
- * mite_buf_change() - COMEDI subdevice (*buf_change) for a MITE dma ring.
- * @ring: MITE dma ring.
- * @s: COMEDI subdevice.
- */
-int mite_buf_change(struct mite_ring *ring, struct comedi_subdevice *s)
-{
- struct comedi_async *async = s->async;
- struct mite_dma_desc *descs;
- unsigned int n_links;
-
- mite_free_dma_descs(ring);
-
- if (async->prealloc_bufsz == 0)
- return 0;
-
- n_links = async->prealloc_bufsz >> PAGE_SHIFT;
-
- descs = dma_alloc_coherent(ring->hw_dev,
- n_links * sizeof(*descs),
- &ring->dma_addr, GFP_KERNEL);
- if (!descs) {
- dev_err(s->device->class_dev,
- "mite: ring buffer allocation failed\n");
- return -ENOMEM;
- }
- ring->descs = descs;
- ring->n_links = n_links;
-
- return mite_init_ring_descriptors(ring, s, n_links << PAGE_SHIFT);
-}
-EXPORT_SYMBOL_GPL(mite_buf_change);
-
-/**
- * mite_alloc_ring() - Allocate a MITE dma ring.
- * @mite: MITE device.
- */
-struct mite_ring *mite_alloc_ring(struct mite *mite)
-{
- struct mite_ring *ring;
-
- ring = kmalloc(sizeof(*ring), GFP_KERNEL);
- if (!ring)
- return NULL;
- ring->hw_dev = get_device(&mite->pcidev->dev);
- if (!ring->hw_dev) {
- kfree(ring);
- return NULL;
- }
- ring->n_links = 0;
- ring->descs = NULL;
- ring->dma_addr = 0;
- return ring;
-}
-EXPORT_SYMBOL_GPL(mite_alloc_ring);
-
-/**
- * mite_free_ring() - Free a MITE dma ring and its descriptors.
- * @ring: MITE dma ring.
- */
-void mite_free_ring(struct mite_ring *ring)
-{
- if (ring) {
- mite_free_dma_descs(ring);
- put_device(ring->hw_dev);
- kfree(ring);
- }
-}
-EXPORT_SYMBOL_GPL(mite_free_ring);
-
-static int mite_setup(struct comedi_device *dev, struct mite *mite,
- bool use_win1)
-{
- resource_size_t daq_phys_addr;
- unsigned long length;
- int i;
- u32 csigr_bits;
- unsigned int unknown_dma_burst_bits;
- unsigned int wpdep;
-
- pci_set_master(mite->pcidev);
-
- mite->mmio = pci_ioremap_bar(mite->pcidev, 0);
- if (!mite->mmio)
- return -ENOMEM;
-
- dev->mmio = pci_ioremap_bar(mite->pcidev, 1);
- if (!dev->mmio)
- return -ENOMEM;
- daq_phys_addr = pci_resource_start(mite->pcidev, 1);
- length = pci_resource_len(mite->pcidev, 1);
-
- if (use_win1) {
- writel(0, mite->mmio + MITE_IODWBSR);
- dev_dbg(dev->class_dev,
- "mite: using I/O Window Base Size register 1\n");
- writel(daq_phys_addr | WENAB |
- MITE_IODWBSR_1_WSIZE_bits(length),
- mite->mmio + MITE_IODWBSR_1);
- writel(0, mite->mmio + MITE_IODWCR_1);
- } else {
- writel(daq_phys_addr | WENAB, mite->mmio + MITE_IODWBSR);
- }
- /*
- * Make sure dma bursts work. I got this from running a bus analyzer
- * on a pxi-6281 and a pxi-6713. 6713 powered up with register value
- * of 0x61f and bursts worked. 6281 powered up with register value of
- * 0x1f and bursts didn't work. The NI windows driver reads the
- * register, then does a bitwise-or of 0x600 with it and writes it back.
- *
- * The bits 0x90180700 in MITE_UNKNOWN_DMA_BURST_REG can be
- * written and read back. The bits 0x1f always read as 1.
- * The rest always read as zero.
- */
- unknown_dma_burst_bits = readl(mite->mmio + MITE_UNKNOWN_DMA_BURST_REG);
- unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS;
- writel(unknown_dma_burst_bits, mite->mmio + MITE_UNKNOWN_DMA_BURST_REG);
-
- csigr_bits = readl(mite->mmio + MITE_CSIGR);
- mite->num_channels = CSIGR_TO_DMAC(csigr_bits);
- if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
- dev_warn(dev->class_dev,
- "mite: bug? chip claims to have %i dma channels. Setting to %i.\n",
- mite->num_channels, MAX_MITE_DMA_CHANNELS);
- mite->num_channels = MAX_MITE_DMA_CHANNELS;
- }
-
- /* get the wpdep bits and convert it to the write port fifo depth */
- wpdep = CSIGR_TO_WPDEP(csigr_bits);
- if (wpdep)
- wpdep = BIT(wpdep);
-
- dev_dbg(dev->class_dev,
- "mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n",
- CSIGR_TO_VER(csigr_bits), CSIGR_TO_TYPE(csigr_bits),
- CSIGR_TO_MMODE(csigr_bits), CSIGR_TO_IMODE(csigr_bits));
- dev_dbg(dev->class_dev,
- "mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n",
- CSIGR_TO_DMAC(csigr_bits), wpdep,
- CSIGR_TO_WINS(csigr_bits), CSIGR_TO_IOWINS(csigr_bits));
-
- for (i = 0; i < mite->num_channels; i++) {
- writel(CHOR_DMARESET, mite->mmio + MITE_CHOR(i));
- /* disable interrupts */
- writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
- CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
- CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
- mite->mmio + MITE_CHCR(i));
- }
- mite->fifo_size = mite_fifo_size(mite, 0);
- dev_dbg(dev->class_dev, "mite: fifo size is %i.\n", mite->fifo_size);
- return 0;
-}
-
-/**
- * mite_attach() - Allocate and initialize a MITE device for a comedi driver.
- * @dev: COMEDI device.
- * @use_win1: flag to use I/O Window 1 instead of I/O Window 0.
- *
- * Called by a COMEDI drivers (*auto_attach).
- *
- * Returns a pointer to the MITE device on success, or NULL if the MITE cannot
- * be allocated or remapped.
- */
-struct mite *mite_attach(struct comedi_device *dev, bool use_win1)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct mite *mite;
- unsigned int i;
- int ret;
-
- mite = kzalloc(sizeof(*mite), GFP_KERNEL);
- if (!mite)
- return NULL;
-
- spin_lock_init(&mite->lock);
- mite->pcidev = pcidev;
- for (i = 0; i < MAX_MITE_DMA_CHANNELS; ++i) {
- mite->channels[i].mite = mite;
- mite->channels[i].channel = i;
- mite->channels[i].done = 1;
- }
-
- ret = mite_setup(dev, mite, use_win1);
- if (ret) {
- if (mite->mmio)
- iounmap(mite->mmio);
- kfree(mite);
- return NULL;
- }
-
- return mite;
-}
-EXPORT_SYMBOL_GPL(mite_attach);
-
-/**
- * mite_detach() - Unmap and free a MITE device for a comedi driver.
- * @mite: MITE device.
- *
- * Called by a COMEDI drivers (*detach).
- */
-void mite_detach(struct mite *mite)
-{
- if (!mite)
- return;
-
- if (mite->mmio)
- iounmap(mite->mmio);
-
- kfree(mite);
-}
-EXPORT_SYMBOL_GPL(mite_detach);
-
-static int __init mite_module_init(void)
-{
- return 0;
-}
-module_init(mite_module_init);
-
-static void __exit mite_module_exit(void)
-{
-}
-module_exit(mite_module_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi helper for NI Mite PCI interface chip");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
deleted file mode 100644
index c6c056069bb7..000000000000
--- a/drivers/staging/comedi/drivers/mite.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * module/mite.h
- * Hardware driver for NI Mite PCI interface chip
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _MITE_H_
-#define _MITE_H_
-
-#include <linux/spinlock.h>
-
-#define MAX_MITE_DMA_CHANNELS 8
-
-struct comedi_device;
-struct comedi_subdevice;
-struct device;
-struct pci_dev;
-
-struct mite_dma_desc {
- __le32 count;
- __le32 addr;
- __le32 next;
- u32 dar;
-};
-
-struct mite_ring {
- struct device *hw_dev;
- unsigned int n_links;
- struct mite_dma_desc *descs;
- dma_addr_t dma_addr;
-};
-
-struct mite_channel {
- struct mite *mite;
- unsigned int channel;
- int dir;
- int done;
- struct mite_ring *ring;
-};
-
-struct mite {
- struct pci_dev *pcidev;
- void __iomem *mmio;
- struct mite_channel channels[MAX_MITE_DMA_CHANNELS];
- int num_channels;
- unsigned int fifo_size;
- /* protects mite_channel from being released by the driver */
- spinlock_t lock;
-};
-
-u32 mite_bytes_in_transit(struct mite_channel *mite_chan);
-
-void mite_sync_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s);
-void mite_ack_linkc(struct mite_channel *mite_chan, struct comedi_subdevice *s,
- bool sync);
-int mite_done(struct mite_channel *mite_chan);
-
-void mite_dma_arm(struct mite_channel *mite_chan);
-void mite_dma_disarm(struct mite_channel *mite_chan);
-
-void mite_prep_dma(struct mite_channel *mite_chan,
- unsigned int num_device_bits, unsigned int num_memory_bits);
-
-struct mite_channel *mite_request_channel_in_range(struct mite *mite,
- struct mite_ring *ring,
- unsigned int min_channel,
- unsigned int max_channel);
-struct mite_channel *mite_request_channel(struct mite *mite,
- struct mite_ring *ring);
-void mite_release_channel(struct mite_channel *mite_chan);
-
-int mite_init_ring_descriptors(struct mite_ring *ring,
- struct comedi_subdevice *s, unsigned int nbytes);
-int mite_buf_change(struct mite_ring *ring, struct comedi_subdevice *s);
-
-struct mite_ring *mite_alloc_ring(struct mite *mite);
-void mite_free_ring(struct mite_ring *ring);
-
-struct mite *mite_attach(struct comedi_device *dev, bool use_win1);
-void mite_detach(struct mite *mite);
-
-/*
- * Mite registers (used outside of the mite driver)
- */
-#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size */
-#define MITE_IODWBSR_1 0xc4 /* IO Device Window1 Base Size */
-#define WENAB BIT(7) /* window enable */
-#define MITE_IODWCR_1 0xf4
-
-#endif
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
deleted file mode 100644
index 646f4c086204..000000000000
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ /dev/null
@@ -1,311 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * mpc624.c
- * Hardware driver for a Micro/sys inc. MPC-624 PC/104 board
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: mpc624
- * Description: Micro/sys MPC-624 PC/104 board
- * Devices: [Micro/sys] MPC-624 (mpc624)
- * Author: Stanislaw Raczynski <sraczynski@op.pl>
- * Updated: Thu, 15 Sep 2005 12:01:18 +0200
- * Status: working
- *
- * The Micro/sys MPC-624 board is based on the LTC2440 24-bit sigma-delta
- * ADC chip.
- *
- * Subdevices supported by the driver:
- * - Analog In: supported
- * - Digital I/O: not supported
- * - LEDs: not supported
- * - EEPROM: not supported
- *
- * Configuration Options:
- * [0] - I/O base address
- * [1] - conversion rate
- * Conversion rate RMS noise Effective Number Of Bits
- * 0 3.52kHz 23uV 17
- * 1 1.76kHz 3.5uV 20
- * 2 880Hz 2uV 21.3
- * 3 440Hz 1.4uV 21.8
- * 4 220Hz 1uV 22.4
- * 5 110Hz 750uV 22.9
- * 6 55Hz 510nV 23.4
- * 7 27.5Hz 375nV 24
- * 8 13.75Hz 250nV 24.4
- * 9 6.875Hz 200nV 24.6
- * [2] - voltage range
- * 0 -1.01V .. +1.01V
- * 1 -10.1V .. +10.1V
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include <linux/delay.h>
-
-/* Offsets of different ports */
-#define MPC624_MASTER_CONTROL 0 /* not used */
-#define MPC624_GNMUXCH 1 /* Gain, Mux, Channel of ADC */
-#define MPC624_ADC 2 /* read/write to/from ADC */
-#define MPC624_EE 3 /* read/write to/from serial EEPROM via I2C */
-#define MPC624_LEDS 4 /* write to LEDs */
-#define MPC624_DIO 5 /* read/write to/from digital I/O ports */
-#define MPC624_IRQ_MASK 6 /* IRQ masking enable/disable */
-
-/* Register bits' names */
-#define MPC624_ADBUSY BIT(5)
-#define MPC624_ADSDO BIT(4)
-#define MPC624_ADFO BIT(3)
-#define MPC624_ADCS BIT(2)
-#define MPC624_ADSCK BIT(1)
-#define MPC624_ADSDI BIT(0)
-
-/* 32-bit output value bits' names */
-#define MPC624_EOC_BIT BIT(31)
-#define MPC624_DMY_BIT BIT(30)
-#define MPC624_SGN_BIT BIT(29)
-
-/* SDI Speed/Resolution Programming bits */
-#define MPC624_OSR(x) (((x) & 0x1f) << 27)
-#define MPC624_SPEED_3_52_KHZ MPC624_OSR(0x11)
-#define MPC624_SPEED_1_76_KHZ MPC624_OSR(0x12)
-#define MPC624_SPEED_880_HZ MPC624_OSR(0x13)
-#define MPC624_SPEED_440_HZ MPC624_OSR(0x14)
-#define MPC624_SPEED_220_HZ MPC624_OSR(0x15)
-#define MPC624_SPEED_110_HZ MPC624_OSR(0x16)
-#define MPC624_SPEED_55_HZ MPC624_OSR(0x17)
-#define MPC624_SPEED_27_5_HZ MPC624_OSR(0x18)
-#define MPC624_SPEED_13_75_HZ MPC624_OSR(0x19)
-#define MPC624_SPEED_6_875_HZ MPC624_OSR(0x1f)
-
-struct mpc624_private {
- unsigned int ai_speed;
-};
-
-/* -------------------------------------------------------------------------- */
-static const struct comedi_lrange range_mpc624_bipolar1 = {
- 1,
- {
-/* BIP_RANGE(1.01) this is correct, */
- /* but my MPC-624 actually seems to have a range of 2.02 */
- BIP_RANGE(2.02)
- }
-};
-
-static const struct comedi_lrange range_mpc624_bipolar10 = {
- 1,
- {
-/* BIP_RANGE(10.1) this is correct, */
- /* but my MPC-624 actually seems to have a range of 20.2 */
- BIP_RANGE(20.2)
- }
-};
-
-static unsigned int mpc624_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct mpc624_private *devpriv = dev->private;
- unsigned int data_out = devpriv->ai_speed;
- unsigned int data_in = 0;
- unsigned int bit;
- int i;
-
- /* Start reading data */
- udelay(1);
- for (i = 0; i < 32; i++) {
- /* Set the clock low */
- outb(0, dev->iobase + MPC624_ADC);
- udelay(1);
-
- /* Set the ADSDI line for the next bit (send to MPC624) */
- bit = (data_out & BIT(31)) ? MPC624_ADSDI : 0;
- outb(bit, dev->iobase + MPC624_ADC);
- udelay(1);
-
- /* Set the clock high */
- outb(MPC624_ADSCK | bit, dev->iobase + MPC624_ADC);
- udelay(1);
-
- /* Read ADSDO on high clock (receive from MPC624) */
- data_in <<= 1;
- data_in |= (inb(dev->iobase + MPC624_ADC) & MPC624_ADSDO) >> 4;
- udelay(1);
-
- data_out <<= 1;
- }
-
- /*
- * Received 32-bit long value consist of:
- * 31: EOC - (End Of Transmission) bit - should be 0
- * 30: DMY - (Dummy) bit - should be 0
- * 29: SIG - (Sign) bit - 1 if positive, 0 if negative
- * 28: MSB - (Most Significant Bit) - the first bit of the
- * conversion result
- * ....
- * 05: LSB - (Least Significant Bit)- the last bit of the
- * conversion result
- * 04-00: sub-LSB - sub-LSBs are basically noise, but when
- * averaged properly, they can increase
- * conversion precision up to 29 bits;
- * they can be discarded without loss of
- * resolution.
- */
- if (data_in & MPC624_EOC_BIT)
- dev_dbg(dev->class_dev, "EOC bit is set!");
- if (data_in & MPC624_DMY_BIT)
- dev_dbg(dev->class_dev, "DMY bit is set!");
-
- if (data_in & MPC624_SGN_BIT) {
- /*
- * Voltage is positive
- *
- * comedi operates on unsigned numbers, so mask off EOC
- * and DMY and don't clear the SGN bit
- */
- data_in &= 0x3fffffff;
- } else {
- /*
- * The voltage is negative
- *
- * data_in contains a number in 30-bit two's complement
- * code and we must deal with it
- */
- data_in |= MPC624_SGN_BIT;
- data_in = ~data_in;
- data_in += 1;
- /* clear EOC and DMY bits */
- data_in &= ~(MPC624_EOC_BIT | MPC624_DMY_BIT);
- data_in = 0x20000000 - data_in;
- }
- return data_in;
-}
-
-static int mpc624_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + MPC624_ADC);
- if ((status & MPC624_ADBUSY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int mpc624_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- int i;
-
- /*
- * WARNING:
- * We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc
- */
- outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
-
- for (i = 0; i < insn->n; i++) {
- /* Trigger the conversion */
- outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
- udelay(1);
- outb(MPC624_ADCS | MPC624_ADSCK, dev->iobase + MPC624_ADC);
- udelay(1);
- outb(0, dev->iobase + MPC624_ADC);
- udelay(1);
-
- /* Wait for the conversion to end */
- ret = comedi_timeout(dev, s, insn, mpc624_ai_eoc, 0);
- if (ret)
- return ret;
-
- data[i] = mpc624_ai_get_sample(dev, s);
- }
-
- return insn->n;
-}
-
-static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct mpc624_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- switch (it->options[1]) {
- case 0:
- devpriv->ai_speed = MPC624_SPEED_3_52_KHZ;
- break;
- case 1:
- devpriv->ai_speed = MPC624_SPEED_1_76_KHZ;
- break;
- case 2:
- devpriv->ai_speed = MPC624_SPEED_880_HZ;
- break;
- case 3:
- devpriv->ai_speed = MPC624_SPEED_440_HZ;
- break;
- case 4:
- devpriv->ai_speed = MPC624_SPEED_220_HZ;
- break;
- case 5:
- devpriv->ai_speed = MPC624_SPEED_110_HZ;
- break;
- case 6:
- devpriv->ai_speed = MPC624_SPEED_55_HZ;
- break;
- case 7:
- devpriv->ai_speed = MPC624_SPEED_27_5_HZ;
- break;
- case 8:
- devpriv->ai_speed = MPC624_SPEED_13_75_HZ;
- break;
- case 9:
- devpriv->ai_speed = MPC624_SPEED_6_875_HZ;
- break;
- default:
- devpriv->ai_speed = MPC624_SPEED_3_52_KHZ;
- }
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF;
- s->n_chan = 4;
- s->maxdata = 0x3fffffff;
- s->range_table = (it->options[1] == 0) ? &range_mpc624_bipolar1
- : &range_mpc624_bipolar10;
- s->insn_read = mpc624_ai_insn_read;
-
- return 0;
-}
-
-static struct comedi_driver mpc624_driver = {
- .driver_name = "mpc624",
- .module = THIS_MODULE,
- .attach = mpc624_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(mpc624_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Micro/sys MPC-624 PC/104 board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
deleted file mode 100644
index c1897aee9a9a..000000000000
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ /dev/null
@@ -1,332 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * multiq3.c
- * Hardware driver for Quanser Consulting MultiQ-3 board
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
- */
-
-/*
- * Driver: multiq3
- * Description: Quanser Consulting MultiQ-3
- * Devices: [Quanser Consulting] MultiQ-3 (multiq3)
- * Author: Anders Blomdell <anders.blomdell@control.lth.se>
- * Status: works
- *
- * Configuration Options:
- * [0] - I/O port base address
- * [1] - IRQ (not used)
- * [2] - Number of optional encoder chips installed on board
- * 0 = none
- * 1 = 2 inputs (Model -2E)
- * 2 = 4 inputs (Model -4E)
- * 3 = 6 inputs (Model -6E)
- * 4 = 8 inputs (Model -8E)
- */
-
-#include <linux/module.h>
-
-#include "../comedidev.h"
-
-/*
- * Register map
- */
-#define MULTIQ3_DI_REG 0x00
-#define MULTIQ3_DO_REG 0x00
-#define MULTIQ3_AO_REG 0x02
-#define MULTIQ3_AI_REG 0x04
-#define MULTIQ3_AI_CONV_REG 0x04
-#define MULTIQ3_STATUS_REG 0x06
-#define MULTIQ3_STATUS_EOC BIT(3)
-#define MULTIQ3_STATUS_EOC_I BIT(4)
-#define MULTIQ3_CTRL_REG 0x06
-#define MULTIQ3_CTRL_AO_CHAN(x) (((x) & 0x7) << 0)
-#define MULTIQ3_CTRL_RC(x) (((x) & 0x3) << 0)
-#define MULTIQ3_CTRL_AI_CHAN(x) (((x) & 0x7) << 3)
-#define MULTIQ3_CTRL_E_CHAN(x) (((x) & 0x7) << 3)
-#define MULTIQ3_CTRL_EN BIT(6)
-#define MULTIQ3_CTRL_AZ BIT(7)
-#define MULTIQ3_CTRL_CAL BIT(8)
-#define MULTIQ3_CTRL_SH BIT(9)
-#define MULTIQ3_CTRL_CLK BIT(10)
-#define MULTIQ3_CTRL_LD (3 << 11)
-#define MULTIQ3_CLK_REG 0x08
-#define MULTIQ3_ENC_DATA_REG 0x0c
-#define MULTIQ3_ENC_CTRL_REG 0x0e
-
-/*
- * Encoder chip commands (from the programming manual)
- */
-#define MULTIQ3_CLOCK_DATA 0x00 /* FCK frequency divider */
-#define MULTIQ3_CLOCK_SETUP 0x18 /* xfer PR0 to PSC */
-#define MULTIQ3_INPUT_SETUP 0x41 /* enable inputs A and B */
-#define MULTIQ3_QUAD_X4 0x38 /* quadrature */
-#define MULTIQ3_BP_RESET 0x01 /* reset byte pointer */
-#define MULTIQ3_CNTR_RESET 0x02 /* reset counter */
-#define MULTIQ3_TRSFRPR_CTR 0x08 /* xfre preset reg to counter */
-#define MULTIQ3_TRSFRCNTR_OL 0x10 /* xfer CNTR to OL (x and y) */
-#define MULTIQ3_EFLAG_RESET 0x06 /* reset E bit of flag reg */
-
-static void multiq3_set_ctrl(struct comedi_device *dev, unsigned int bits)
-{
- /*
- * According to the programming manual, the SH and CLK bits should
- * be kept high at all times.
- */
- outw(MULTIQ3_CTRL_SH | MULTIQ3_CTRL_CLK | bits,
- dev->iobase + MULTIQ3_CTRL_REG);
-}
-
-static int multiq3_ai_status(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + MULTIQ3_STATUS_REG);
- if (status & context)
- return 0;
- return -EBUSY;
-}
-
-static int multiq3_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
- int ret;
- int i;
-
- multiq3_set_ctrl(dev, MULTIQ3_CTRL_EN | MULTIQ3_CTRL_AI_CHAN(chan));
-
- ret = comedi_timeout(dev, s, insn, multiq3_ai_status,
- MULTIQ3_STATUS_EOC);
- if (ret)
- return ret;
-
- for (i = 0; i < insn->n; i++) {
- outw(0, dev->iobase + MULTIQ3_AI_CONV_REG);
-
- ret = comedi_timeout(dev, s, insn, multiq3_ai_status,
- MULTIQ3_STATUS_EOC_I);
- if (ret)
- return ret;
-
- /* get a 16-bit sample; mask it to the subdevice resolution */
- val = inb(dev->iobase + MULTIQ3_AI_REG) << 8;
- val |= inb(dev->iobase + MULTIQ3_AI_REG);
- val &= s->maxdata;
-
- /* munge the 2's complement value to offset binary */
- data[i] = comedi_offset_munge(s, val);
- }
-
- return insn->n;
-}
-
-static int multiq3_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- multiq3_set_ctrl(dev, MULTIQ3_CTRL_LD |
- MULTIQ3_CTRL_AO_CHAN(chan));
- outw(val, dev->iobase + MULTIQ3_AO_REG);
- multiq3_set_ctrl(dev, 0);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int multiq3_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[1] = inw(dev->iobase + MULTIQ3_DI_REG);
-
- return insn->n;
-}
-
-static int multiq3_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + MULTIQ3_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int multiq3_encoder_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- /* select encoder channel */
- multiq3_set_ctrl(dev, MULTIQ3_CTRL_EN |
- MULTIQ3_CTRL_E_CHAN(chan));
-
- /* reset the byte pointer */
- outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CTRL_REG);
-
- /* latch the data */
- outb(MULTIQ3_TRSFRCNTR_OL, dev->iobase + MULTIQ3_ENC_CTRL_REG);
-
- /* read the 24-bit encoder data (lsb/mid/msb) */
- val = inb(dev->iobase + MULTIQ3_ENC_DATA_REG);
- val |= (inb(dev->iobase + MULTIQ3_ENC_DATA_REG) << 8);
- val |= (inb(dev->iobase + MULTIQ3_ENC_DATA_REG) << 16);
-
- /*
- * Munge the data so that the reset value is in the middle
- * of the maxdata range, i.e.:
- *
- * real value comedi value
- * 0xffffff 0x7fffff 1 negative count
- * 0x000000 0x800000 reset value
- * 0x000001 0x800001 1 positive count
- *
- * It's possible for the 24-bit counter to overflow but it
- * would normally take _quite_ a few turns. A 2000 line
- * encoder in quadrature results in 8000 counts/rev. So about
- * 1048 turns in either direction can be measured without
- * an overflow.
- */
- data[i] = (val + ((s->maxdata + 1) >> 1)) & s->maxdata;
- }
-
- return insn->n;
-}
-
-static void multiq3_encoder_reset(struct comedi_device *dev,
- unsigned int chan)
-{
- multiq3_set_ctrl(dev, MULTIQ3_CTRL_EN | MULTIQ3_CTRL_E_CHAN(chan));
- outb(MULTIQ3_EFLAG_RESET, dev->iobase + MULTIQ3_ENC_CTRL_REG);
- outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CTRL_REG);
- outb(MULTIQ3_CLOCK_DATA, dev->iobase + MULTIQ3_ENC_DATA_REG);
- outb(MULTIQ3_CLOCK_SETUP, dev->iobase + MULTIQ3_ENC_CTRL_REG);
- outb(MULTIQ3_INPUT_SETUP, dev->iobase + MULTIQ3_ENC_CTRL_REG);
- outb(MULTIQ3_QUAD_X4, dev->iobase + MULTIQ3_ENC_CTRL_REG);
- outb(MULTIQ3_CNTR_RESET, dev->iobase + MULTIQ3_ENC_CTRL_REG);
-}
-
-static int multiq3_encoder_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- switch (data[0]) {
- case INSN_CONFIG_RESET:
- multiq3_encoder_reset(dev, chan);
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int multiq3_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
- int i;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 5);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 8;
- s->maxdata = 0x1fff;
- s->range_table = &range_bipolar5;
- s->insn_read = multiq3_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 0x0fff;
- s->range_table = &range_bipolar5;
- s->insn_write = multiq3_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = multiq3_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = multiq3_do_insn_bits;
-
- /* Encoder (Counter) subdevice */
- s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
- s->n_chan = it->options[2] * 2;
- s->maxdata = 0x00ffffff;
- s->range_table = &range_unknown;
- s->insn_read = multiq3_encoder_insn_read;
- s->insn_config = multiq3_encoder_insn_config;
-
- for (i = 0; i < s->n_chan; i++)
- multiq3_encoder_reset(dev, i);
-
- return 0;
-}
-
-static struct comedi_driver multiq3_driver = {
- .driver_name = "multiq3",
- .module = THIS_MODULE,
- .attach = multiq3_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(multiq3_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Quanser Consulting MultiQ-3 board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
deleted file mode 100644
index f1a45cf7342a..000000000000
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ /dev/null
@@ -1,493 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * ni_6527.c
- * Comedi driver for National Instruments PCI-6527
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_6527
- * Description: National Instruments 6527
- * Devices: [National Instruments] PCI-6527 (pci-6527), PXI-6527 (pxi-6527)
- * Author: David A. Schleef <ds@schleef.org>
- * Updated: Sat, 25 Jan 2003 13:24:40 -0800
- * Status: works
- *
- * Configuration Options: not applicable, uses PCI auto config
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI BAR1 - Register memory map
- *
- * Manuals (available from ftp://ftp.natinst.com/support/manuals)
- * 370106b.pdf 6527 Register Level Programmer Manual
- */
-#define NI6527_DI_REG(x) (0x00 + (x))
-#define NI6527_DO_REG(x) (0x03 + (x))
-#define NI6527_ID_REG 0x06
-#define NI6527_CLR_REG 0x07
-#define NI6527_CLR_EDGE BIT(3)
-#define NI6527_CLR_OVERFLOW BIT(2)
-#define NI6527_CLR_FILT BIT(1)
-#define NI6527_CLR_INTERVAL BIT(0)
-#define NI6527_CLR_IRQS (NI6527_CLR_EDGE | NI6527_CLR_OVERFLOW)
-#define NI6527_CLR_RESET_FILT (NI6527_CLR_FILT | NI6527_CLR_INTERVAL)
-#define NI6527_FILT_INTERVAL_REG(x) (0x08 + (x))
-#define NI6527_FILT_ENA_REG(x) (0x0c + (x))
-#define NI6527_STATUS_REG 0x14
-#define NI6527_STATUS_IRQ BIT(2)
-#define NI6527_STATUS_OVERFLOW BIT(1)
-#define NI6527_STATUS_EDGE BIT(0)
-#define NI6527_CTRL_REG 0x15
-#define NI6527_CTRL_FALLING BIT(4)
-#define NI6527_CTRL_RISING BIT(3)
-#define NI6527_CTRL_IRQ BIT(2)
-#define NI6527_CTRL_OVERFLOW BIT(1)
-#define NI6527_CTRL_EDGE BIT(0)
-#define NI6527_CTRL_DISABLE_IRQS 0
-#define NI6527_CTRL_ENABLE_IRQS (NI6527_CTRL_FALLING | \
- NI6527_CTRL_RISING | \
- NI6527_CTRL_IRQ | NI6527_CTRL_EDGE)
-#define NI6527_RISING_EDGE_REG(x) (0x18 + (x))
-#define NI6527_FALLING_EDGE_REG(x) (0x20 + (x))
-
-enum ni6527_boardid {
- BOARD_PCI6527,
- BOARD_PXI6527,
-};
-
-struct ni6527_board {
- const char *name;
-};
-
-static const struct ni6527_board ni6527_boards[] = {
- [BOARD_PCI6527] = {
- .name = "pci-6527",
- },
- [BOARD_PXI6527] = {
- .name = "pxi-6527",
- },
-};
-
-struct ni6527_private {
- unsigned int filter_interval;
- unsigned int filter_enable;
-};
-
-static void ni6527_set_filter_interval(struct comedi_device *dev,
- unsigned int val)
-{
- struct ni6527_private *devpriv = dev->private;
-
- if (val != devpriv->filter_interval) {
- writeb(val & 0xff, dev->mmio + NI6527_FILT_INTERVAL_REG(0));
- writeb((val >> 8) & 0xff,
- dev->mmio + NI6527_FILT_INTERVAL_REG(1));
- writeb((val >> 16) & 0x0f,
- dev->mmio + NI6527_FILT_INTERVAL_REG(2));
-
- writeb(NI6527_CLR_INTERVAL, dev->mmio + NI6527_CLR_REG);
-
- devpriv->filter_interval = val;
- }
-}
-
-static void ni6527_set_filter_enable(struct comedi_device *dev,
- unsigned int val)
-{
- writeb(val & 0xff, dev->mmio + NI6527_FILT_ENA_REG(0));
- writeb((val >> 8) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(1));
- writeb((val >> 16) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(2));
-}
-
-static int ni6527_di_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni6527_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int interval;
-
- switch (data[0]) {
- case INSN_CONFIG_FILTER:
- /*
- * The deglitch filter interval is specified in nanoseconds.
- * The hardware supports intervals in 200ns increments. Round
- * the user values up and return the actual interval.
- */
- interval = (data[1] + 100) / 200;
- data[1] = interval * 200;
-
- if (interval) {
- ni6527_set_filter_interval(dev, interval);
- devpriv->filter_enable |= 1 << chan;
- } else {
- devpriv->filter_enable &= ~(1 << chan);
- }
- ni6527_set_filter_enable(dev, devpriv->filter_enable);
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int ni6527_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int val;
-
- val = readb(dev->mmio + NI6527_DI_REG(0));
- val |= (readb(dev->mmio + NI6527_DI_REG(1)) << 8);
- val |= (readb(dev->mmio + NI6527_DI_REG(2)) << 16);
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int ni6527_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- /* Outputs are inverted */
- unsigned int val = s->state ^ 0xffffff;
-
- if (mask & 0x0000ff)
- writeb(val & 0xff, dev->mmio + NI6527_DO_REG(0));
- if (mask & 0x00ff00)
- writeb((val >> 8) & 0xff,
- dev->mmio + NI6527_DO_REG(1));
- if (mask & 0xff0000)
- writeb((val >> 16) & 0xff,
- dev->mmio + NI6527_DO_REG(2));
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static irqreturn_t ni6527_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int status;
-
- status = readb(dev->mmio + NI6527_STATUS_REG);
- if (!(status & NI6527_STATUS_IRQ))
- return IRQ_NONE;
-
- if (status & NI6527_STATUS_EDGE) {
- unsigned short val = 0;
-
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
- }
-
- writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);
-
- return IRQ_HANDLED;
-}
-
-static int ni6527_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_OTHER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int ni6527_intr_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);
- writeb(NI6527_CTRL_ENABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
-
- return 0;
-}
-
-static int ni6527_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
-
- return 0;
-}
-
-static int ni6527_intr_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[1] = 0;
- return insn->n;
-}
-
-static void ni6527_set_edge_detection(struct comedi_device *dev,
- unsigned int mask,
- unsigned int rising,
- unsigned int falling)
-{
- unsigned int i;
-
- rising &= mask;
- falling &= mask;
- for (i = 0; i < 2; i++) {
- if (mask & 0xff) {
- if (~mask & 0xff) {
- /* preserve rising-edge detection channels */
- rising |= readb(dev->mmio +
- NI6527_RISING_EDGE_REG(i)) &
- (~mask & 0xff);
- /* preserve falling-edge detection channels */
- falling |= readb(dev->mmio +
- NI6527_FALLING_EDGE_REG(i)) &
- (~mask & 0xff);
- }
- /* update rising-edge detection channels */
- writeb(rising & 0xff,
- dev->mmio + NI6527_RISING_EDGE_REG(i));
- /* update falling-edge detection channels */
- writeb(falling & 0xff,
- dev->mmio + NI6527_FALLING_EDGE_REG(i));
- }
- rising >>= 8;
- falling >>= 8;
- mask >>= 8;
- }
-}
-
-static int ni6527_intr_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask = 0xffffffff;
- unsigned int rising, falling, shift;
-
- switch (data[0]) {
- case INSN_CONFIG_CHANGE_NOTIFY:
- /* check_insn_config_length() does not check this instruction */
- if (insn->n != 3)
- return -EINVAL;
- rising = data[1];
- falling = data[2];
- ni6527_set_edge_detection(dev, mask, rising, falling);
- break;
- case INSN_CONFIG_DIGITAL_TRIG:
- /* check trigger number */
- if (data[1] != 0)
- return -EINVAL;
- /* check digital trigger operation */
- switch (data[2]) {
- case COMEDI_DIGITAL_TRIG_DISABLE:
- rising = 0;
- falling = 0;
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
- /* check shift amount */
- shift = data[3];
- if (shift >= 32) {
- mask = 0;
- rising = 0;
- falling = 0;
- } else {
- mask <<= shift;
- rising = data[4] << shift;
- falling = data[5] << shift;
- }
- break;
- default:
- return -EINVAL;
- }
- ni6527_set_edge_detection(dev, mask, rising, falling);
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static void ni6527_reset(struct comedi_device *dev)
-{
- /* disable deglitch filters on all channels */
- ni6527_set_filter_enable(dev, 0);
-
- /* disable edge detection */
- ni6527_set_edge_detection(dev, 0xffffffff, 0, 0);
-
- writeb(NI6527_CLR_IRQS | NI6527_CLR_RESET_FILT,
- dev->mmio + NI6527_CLR_REG);
- writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
-}
-
-static int ni6527_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct ni6527_board *board = NULL;
- struct ni6527_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- if (context < ARRAY_SIZE(ni6527_boards))
- board = &ni6527_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 1);
- if (!dev->mmio)
- return -ENOMEM;
-
- /* make sure this is actually a 6527 device */
- if (readb(dev->mmio + NI6527_ID_REG) != 0x27)
- return -ENODEV;
-
- ni6527_reset(dev);
-
- ret = request_irq(pcidev->irq, ni6527_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = ni6527_di_insn_config;
- s->insn_bits = ni6527_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni6527_do_insn_bits;
-
- /* Edge detection interrupt subdevice */
- s = &dev->subdevices[2];
- if (dev->irq) {
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_config = ni6527_intr_insn_config;
- s->insn_bits = ni6527_intr_insn_bits;
- s->len_chanlist = 1;
- s->do_cmdtest = ni6527_intr_cmdtest;
- s->do_cmd = ni6527_intr_cmd;
- s->cancel = ni6527_intr_cancel;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- return 0;
-}
-
-static void ni6527_detach(struct comedi_device *dev)
-{
- if (dev->mmio)
- ni6527_reset(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver ni6527_driver = {
- .driver_name = "ni_6527",
- .module = THIS_MODULE,
- .auto_attach = ni6527_auto_attach,
- .detach = ni6527_detach,
-};
-
-static int ni6527_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data);
-}
-
-static const struct pci_device_id ni6527_pci_table[] = {
- { PCI_VDEVICE(NI, 0x2b10), BOARD_PXI6527 },
- { PCI_VDEVICE(NI, 0x2b20), BOARD_PCI6527 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
-
-static struct pci_driver ni6527_pci_driver = {
- .name = "ni_6527",
- .id_table = ni6527_pci_table,
- .probe = ni6527_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for National Instruments PCI-6527");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
deleted file mode 100644
index 7cd8497420f2..000000000000
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ /dev/null
@@ -1,823 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * ni_65xx.c
- * Comedi driver for National Instruments PCI-65xx static dio boards
- *
- * Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
- * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_65xx
- * Description: National Instruments 65xx static dio boards
- * Author: Jon Grierson <jd@renko.co.uk>,
- * Frank Mori Hess <fmhess@users.sourceforge.net>
- * Status: testing
- * Devices: [National Instruments] PCI-6509 (pci-6509), PXI-6509 (pxi-6509),
- * PCI-6510 (pci-6510), PCI-6511 (pci-6511), PXI-6511 (pxi-6511),
- * PCI-6512 (pci-6512), PXI-6512 (pxi-6512), PCI-6513 (pci-6513),
- * PXI-6513 (pxi-6513), PCI-6514 (pci-6514), PXI-6514 (pxi-6514),
- * PCI-6515 (pxi-6515), PXI-6515 (pxi-6515), PCI-6516 (pci-6516),
- * PCI-6517 (pci-6517), PCI-6518 (pci-6518), PCI-6519 (pci-6519),
- * PCI-6520 (pci-6520), PCI-6521 (pci-6521), PXI-6521 (pxi-6521),
- * PCI-6528 (pci-6528), PXI-6528 (pxi-6528)
- * Updated: Mon, 21 Jul 2014 12:49:58 +0000
- *
- * Configuration Options: not applicable, uses PCI auto config
- *
- * Based on the PCI-6527 driver by ds.
- * The interrupt subdevice (subdevice 3) is probably broken for all
- * boards except maybe the 6514.
- *
- * This driver previously inverted the outputs on PCI-6513 through to
- * PCI-6519 and on PXI-6513 through to PXI-6515. It no longer inverts
- * outputs on those cards by default as it didn't make much sense. If
- * you require the outputs to be inverted on those cards for legacy
- * reasons, set the module parameter "legacy_invert_outputs=true" when
- * loading the module, or set "ni_65xx.legacy_invert_outputs=true" on
- * the kernel command line if the driver is built in to the kernel.
- */
-
-/*
- * Manuals (available from ftp://ftp.natinst.com/support/manuals)
- *
- * 370106b.pdf 6514 Register Level Programmer Manual
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-/*
- * PCI BAR1 Register Map
- */
-
-/* Non-recurring Registers (8-bit except where noted) */
-#define NI_65XX_ID_REG 0x00
-#define NI_65XX_CLR_REG 0x01
-#define NI_65XX_CLR_WDOG_INT BIT(6)
-#define NI_65XX_CLR_WDOG_PING BIT(5)
-#define NI_65XX_CLR_WDOG_EXP BIT(4)
-#define NI_65XX_CLR_EDGE_INT BIT(3)
-#define NI_65XX_CLR_OVERFLOW_INT BIT(2)
-#define NI_65XX_STATUS_REG 0x02
-#define NI_65XX_STATUS_WDOG_INT BIT(5)
-#define NI_65XX_STATUS_FALL_EDGE BIT(4)
-#define NI_65XX_STATUS_RISE_EDGE BIT(3)
-#define NI_65XX_STATUS_INT BIT(2)
-#define NI_65XX_STATUS_OVERFLOW_INT BIT(1)
-#define NI_65XX_STATUS_EDGE_INT BIT(0)
-#define NI_65XX_CTRL_REG 0x03
-#define NI_65XX_CTRL_WDOG_ENA BIT(5)
-#define NI_65XX_CTRL_FALL_EDGE_ENA BIT(4)
-#define NI_65XX_CTRL_RISE_EDGE_ENA BIT(3)
-#define NI_65XX_CTRL_INT_ENA BIT(2)
-#define NI_65XX_CTRL_OVERFLOW_ENA BIT(1)
-#define NI_65XX_CTRL_EDGE_ENA BIT(0)
-#define NI_65XX_REV_REG 0x04 /* 32-bit */
-#define NI_65XX_FILTER_REG 0x08 /* 32-bit */
-#define NI_65XX_RTSI_ROUTE_REG 0x0c /* 16-bit */
-#define NI_65XX_RTSI_EDGE_REG 0x0e /* 16-bit */
-#define NI_65XX_RTSI_WDOG_REG 0x10 /* 16-bit */
-#define NI_65XX_RTSI_TRIG_REG 0x12 /* 16-bit */
-#define NI_65XX_AUTO_CLK_SEL_REG 0x14 /* PXI-6528 only */
-#define NI_65XX_AUTO_CLK_SEL_STATUS BIT(1)
-#define NI_65XX_AUTO_CLK_SEL_DISABLE BIT(0)
-#define NI_65XX_WDOG_CTRL_REG 0x15
-#define NI_65XX_WDOG_CTRL_ENA BIT(0)
-#define NI_65XX_RTSI_CFG_REG 0x16
-#define NI_65XX_RTSI_CFG_RISE_SENSE BIT(2)
-#define NI_65XX_RTSI_CFG_FALL_SENSE BIT(1)
-#define NI_65XX_RTSI_CFG_SYNC_DETECT BIT(0)
-#define NI_65XX_WDOG_STATUS_REG 0x17
-#define NI_65XX_WDOG_STATUS_EXP BIT(0)
-#define NI_65XX_WDOG_INTERVAL_REG 0x18 /* 32-bit */
-
-/* Recurring port registers (8-bit) */
-#define NI_65XX_PORT(x) ((x) * 0x10)
-#define NI_65XX_IO_DATA_REG(x) (0x40 + NI_65XX_PORT(x))
-#define NI_65XX_IO_SEL_REG(x) (0x41 + NI_65XX_PORT(x))
-#define NI_65XX_IO_SEL_OUTPUT 0
-#define NI_65XX_IO_SEL_INPUT BIT(0)
-#define NI_65XX_RISE_EDGE_ENA_REG(x) (0x42 + NI_65XX_PORT(x))
-#define NI_65XX_FALL_EDGE_ENA_REG(x) (0x43 + NI_65XX_PORT(x))
-#define NI_65XX_FILTER_ENA(x) (0x44 + NI_65XX_PORT(x))
-#define NI_65XX_WDOG_HIZ_REG(x) (0x46 + NI_65XX_PORT(x))
-#define NI_65XX_WDOG_ENA(x) (0x47 + NI_65XX_PORT(x))
-#define NI_65XX_WDOG_HI_LO_REG(x) (0x48 + NI_65XX_PORT(x))
-#define NI_65XX_RTSI_ENA(x) (0x49 + NI_65XX_PORT(x))
-
-#define NI_65XX_PORT_TO_CHAN(x) ((x) * 8)
-#define NI_65XX_CHAN_TO_PORT(x) ((x) / 8)
-#define NI_65XX_CHAN_TO_MASK(x) (1 << ((x) % 8))
-
-enum ni_65xx_boardid {
- BOARD_PCI6509,
- BOARD_PXI6509,
- BOARD_PCI6510,
- BOARD_PCI6511,
- BOARD_PXI6511,
- BOARD_PCI6512,
- BOARD_PXI6512,
- BOARD_PCI6513,
- BOARD_PXI6513,
- BOARD_PCI6514,
- BOARD_PXI6514,
- BOARD_PCI6515,
- BOARD_PXI6515,
- BOARD_PCI6516,
- BOARD_PCI6517,
- BOARD_PCI6518,
- BOARD_PCI6519,
- BOARD_PCI6520,
- BOARD_PCI6521,
- BOARD_PXI6521,
- BOARD_PCI6528,
- BOARD_PXI6528,
-};
-
-struct ni_65xx_board {
- const char *name;
- unsigned int num_dio_ports;
- unsigned int num_di_ports;
- unsigned int num_do_ports;
- unsigned int legacy_invert:1;
-};
-
-static const struct ni_65xx_board ni_65xx_boards[] = {
- [BOARD_PCI6509] = {
- .name = "pci-6509",
- .num_dio_ports = 12,
- },
- [BOARD_PXI6509] = {
- .name = "pxi-6509",
- .num_dio_ports = 12,
- },
- [BOARD_PCI6510] = {
- .name = "pci-6510",
- .num_di_ports = 4,
- },
- [BOARD_PCI6511] = {
- .name = "pci-6511",
- .num_di_ports = 8,
- },
- [BOARD_PXI6511] = {
- .name = "pxi-6511",
- .num_di_ports = 8,
- },
- [BOARD_PCI6512] = {
- .name = "pci-6512",
- .num_do_ports = 8,
- },
- [BOARD_PXI6512] = {
- .name = "pxi-6512",
- .num_do_ports = 8,
- },
- [BOARD_PCI6513] = {
- .name = "pci-6513",
- .num_do_ports = 8,
- .legacy_invert = 1,
- },
- [BOARD_PXI6513] = {
- .name = "pxi-6513",
- .num_do_ports = 8,
- .legacy_invert = 1,
- },
- [BOARD_PCI6514] = {
- .name = "pci-6514",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .legacy_invert = 1,
- },
- [BOARD_PXI6514] = {
- .name = "pxi-6514",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .legacy_invert = 1,
- },
- [BOARD_PCI6515] = {
- .name = "pci-6515",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .legacy_invert = 1,
- },
- [BOARD_PXI6515] = {
- .name = "pxi-6515",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .legacy_invert = 1,
- },
- [BOARD_PCI6516] = {
- .name = "pci-6516",
- .num_do_ports = 4,
- .legacy_invert = 1,
- },
- [BOARD_PCI6517] = {
- .name = "pci-6517",
- .num_do_ports = 4,
- .legacy_invert = 1,
- },
- [BOARD_PCI6518] = {
- .name = "pci-6518",
- .num_di_ports = 2,
- .num_do_ports = 2,
- .legacy_invert = 1,
- },
- [BOARD_PCI6519] = {
- .name = "pci-6519",
- .num_di_ports = 2,
- .num_do_ports = 2,
- .legacy_invert = 1,
- },
- [BOARD_PCI6520] = {
- .name = "pci-6520",
- .num_di_ports = 1,
- .num_do_ports = 1,
- },
- [BOARD_PCI6521] = {
- .name = "pci-6521",
- .num_di_ports = 1,
- .num_do_ports = 1,
- },
- [BOARD_PXI6521] = {
- .name = "pxi-6521",
- .num_di_ports = 1,
- .num_do_ports = 1,
- },
- [BOARD_PCI6528] = {
- .name = "pci-6528",
- .num_di_ports = 3,
- .num_do_ports = 3,
- },
- [BOARD_PXI6528] = {
- .name = "pxi-6528",
- .num_di_ports = 3,
- .num_do_ports = 3,
- },
-};
-
-static bool ni_65xx_legacy_invert_outputs;
-module_param_named(legacy_invert_outputs, ni_65xx_legacy_invert_outputs,
- bool, 0444);
-MODULE_PARM_DESC(legacy_invert_outputs,
- "invert outputs of PCI/PXI-6513/6514/6515/6516/6517/6518/6519 for compatibility with old user code");
-
-static unsigned int ni_65xx_num_ports(struct comedi_device *dev)
-{
- const struct ni_65xx_board *board = dev->board_ptr;
-
- return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
-}
-
-static void ni_65xx_disable_input_filters(struct comedi_device *dev)
-{
- unsigned int num_ports = ni_65xx_num_ports(dev);
- int i;
-
- /* disable input filtering on all ports */
- for (i = 0; i < num_ports; ++i)
- writeb(0x00, dev->mmio + NI_65XX_FILTER_ENA(i));
-
- /* set filter interval to 0 (32bit reg) */
- writel(0x00000000, dev->mmio + NI_65XX_FILTER_REG);
-}
-
-/* updates edge detection for base_chan to base_chan+31 */
-static void ni_65xx_update_edge_detection(struct comedi_device *dev,
- unsigned int base_chan,
- unsigned int rising,
- unsigned int falling)
-{
- unsigned int num_ports = ni_65xx_num_ports(dev);
- unsigned int port;
-
- if (base_chan >= NI_65XX_PORT_TO_CHAN(num_ports))
- return;
-
- for (port = NI_65XX_CHAN_TO_PORT(base_chan); port < num_ports; port++) {
- int bitshift = (int)(NI_65XX_PORT_TO_CHAN(port) - base_chan);
- unsigned int port_mask, port_rising, port_falling;
-
- if (bitshift >= 32)
- break;
-
- if (bitshift >= 0) {
- port_mask = ~0U >> bitshift;
- port_rising = rising >> bitshift;
- port_falling = falling >> bitshift;
- } else {
- port_mask = ~0U << -bitshift;
- port_rising = rising << -bitshift;
- port_falling = falling << -bitshift;
- }
- if (port_mask & 0xff) {
- if (~port_mask & 0xff) {
- port_rising |=
- readb(dev->mmio +
- NI_65XX_RISE_EDGE_ENA_REG(port)) &
- ~port_mask;
- port_falling |=
- readb(dev->mmio +
- NI_65XX_FALL_EDGE_ENA_REG(port)) &
- ~port_mask;
- }
- writeb(port_rising & 0xff,
- dev->mmio + NI_65XX_RISE_EDGE_ENA_REG(port));
- writeb(port_falling & 0xff,
- dev->mmio + NI_65XX_FALL_EDGE_ENA_REG(port));
- }
- }
-}
-
-static void ni_65xx_disable_edge_detection(struct comedi_device *dev)
-{
- /* clear edge detection for channels 0 to 31 */
- ni_65xx_update_edge_detection(dev, 0, 0, 0);
- /* clear edge detection for channels 32 to 63 */
- ni_65xx_update_edge_detection(dev, 32, 0, 0);
- /* clear edge detection for channels 64 to 95 */
- ni_65xx_update_edge_detection(dev, 64, 0, 0);
-}
-
-static int ni_65xx_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long base_port = (unsigned long)s->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int chan_mask = NI_65XX_CHAN_TO_MASK(chan);
- unsigned int port = base_port + NI_65XX_CHAN_TO_PORT(chan);
- unsigned int interval;
- unsigned int val;
-
- switch (data[0]) {
- case INSN_CONFIG_FILTER:
- /*
- * The deglitch filter interval is specified in nanoseconds.
- * The hardware supports intervals in 200ns increments. Round
- * the user values up and return the actual interval.
- */
- interval = (data[1] + 100) / 200;
- if (interval > 0xfffff)
- interval = 0xfffff;
- data[1] = interval * 200;
-
- /*
- * Enable/disable the channel for deglitch filtering. Note
- * that the filter interval is never set to '0'. This is done
- * because other channels might still be enabled for filtering.
- */
- val = readb(dev->mmio + NI_65XX_FILTER_ENA(port));
- if (interval) {
- writel(interval, dev->mmio + NI_65XX_FILTER_REG);
- val |= chan_mask;
- } else {
- val &= ~chan_mask;
- }
- writeb(val, dev->mmio + NI_65XX_FILTER_ENA(port));
- break;
-
- case INSN_CONFIG_DIO_OUTPUT:
- if (s->type != COMEDI_SUBD_DIO)
- return -EINVAL;
- writeb(NI_65XX_IO_SEL_OUTPUT,
- dev->mmio + NI_65XX_IO_SEL_REG(port));
- break;
-
- case INSN_CONFIG_DIO_INPUT:
- if (s->type != COMEDI_SUBD_DIO)
- return -EINVAL;
- writeb(NI_65XX_IO_SEL_INPUT,
- dev->mmio + NI_65XX_IO_SEL_REG(port));
- break;
-
- case INSN_CONFIG_DIO_QUERY:
- if (s->type != COMEDI_SUBD_DIO)
- return -EINVAL;
- val = readb(dev->mmio + NI_65XX_IO_SEL_REG(port));
- data[1] = (val == NI_65XX_IO_SEL_INPUT) ? COMEDI_INPUT
- : COMEDI_OUTPUT;
- break;
-
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long base_port = (unsigned long)s->private;
- unsigned int base_chan = CR_CHAN(insn->chanspec);
- int last_port_offset = NI_65XX_CHAN_TO_PORT(s->n_chan - 1);
- unsigned int read_bits = 0;
- int port_offset;
-
- for (port_offset = NI_65XX_CHAN_TO_PORT(base_chan);
- port_offset <= last_port_offset; port_offset++) {
- unsigned int port = base_port + port_offset;
- int base_port_channel = NI_65XX_PORT_TO_CHAN(port_offset);
- unsigned int port_mask, port_data, bits;
- int bitshift = base_port_channel - base_chan;
-
- if (bitshift >= 32)
- break;
- port_mask = data[0];
- port_data = data[1];
- if (bitshift > 0) {
- port_mask >>= bitshift;
- port_data >>= bitshift;
- } else {
- port_mask <<= -bitshift;
- port_data <<= -bitshift;
- }
- port_mask &= 0xff;
- port_data &= 0xff;
-
- /* update the outputs */
- if (port_mask) {
- bits = readb(dev->mmio + NI_65XX_IO_DATA_REG(port));
- bits ^= s->io_bits; /* invert if necessary */
- bits &= ~port_mask;
- bits |= (port_data & port_mask);
- bits ^= s->io_bits; /* invert back */
- writeb(bits, dev->mmio + NI_65XX_IO_DATA_REG(port));
- }
-
- /* read back the actual state */
- bits = readb(dev->mmio + NI_65XX_IO_DATA_REG(port));
- bits ^= s->io_bits; /* invert if necessary */
- if (bitshift > 0)
- bits <<= bitshift;
- else
- bits >>= -bitshift;
-
- read_bits |= bits;
- }
- data[1] = read_bits;
- return insn->n;
-}
-
-static irqreturn_t ni_65xx_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int status;
- unsigned short val = 0;
-
- status = readb(dev->mmio + NI_65XX_STATUS_REG);
- if ((status & NI_65XX_STATUS_INT) == 0)
- return IRQ_NONE;
- if ((status & NI_65XX_STATUS_EDGE_INT) == 0)
- return IRQ_NONE;
-
- writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
- dev->mmio + NI_65XX_CLR_REG);
-
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_OTHER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int ni_65xx_intr_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
- dev->mmio + NI_65XX_CLR_REG);
- writeb(NI_65XX_CTRL_FALL_EDGE_ENA | NI_65XX_CTRL_RISE_EDGE_ENA |
- NI_65XX_CTRL_INT_ENA | NI_65XX_CTRL_EDGE_ENA,
- dev->mmio + NI_65XX_CTRL_REG);
-
- return 0;
-}
-
-static int ni_65xx_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
-
- return 0;
-}
-
-static int ni_65xx_intr_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = 0;
- return insn->n;
-}
-
-static int ni_65xx_intr_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- switch (data[0]) {
- case INSN_CONFIG_CHANGE_NOTIFY:
- /* add instruction to check_insn_config_length() */
- if (insn->n != 3)
- return -EINVAL;
-
- /* update edge detection for channels 0 to 31 */
- ni_65xx_update_edge_detection(dev, 0, data[1], data[2]);
- /* clear edge detection for channels 32 to 63 */
- ni_65xx_update_edge_detection(dev, 32, 0, 0);
- /* clear edge detection for channels 64 to 95 */
- ni_65xx_update_edge_detection(dev, 64, 0, 0);
- break;
- case INSN_CONFIG_DIGITAL_TRIG:
- /* check trigger number */
- if (data[1] != 0)
- return -EINVAL;
- /* check digital trigger operation */
- switch (data[2]) {
- case COMEDI_DIGITAL_TRIG_DISABLE:
- ni_65xx_disable_edge_detection(dev);
- break;
- case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
- /*
- * update edge detection for channels data[3]
- * to (data[3] + 31)
- */
- ni_65xx_update_edge_detection(dev, data[3],
- data[4], data[5]);
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-/* ripped from mite.h and mite_setup2() to avoid mite dependency */
-#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
-#define WENAB BIT(7) /* window enable */
-
-static int ni_65xx_mite_init(struct pci_dev *pcidev)
-{
- void __iomem *mite_base;
- u32 main_phys_addr;
-
- /* ioremap the MITE registers (BAR 0) temporarily */
- mite_base = pci_ioremap_bar(pcidev, 0);
- if (!mite_base)
- return -ENOMEM;
-
- /* set data window to main registers (BAR 1) */
- main_phys_addr = pci_resource_start(pcidev, 1);
- writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
-
- /* finished with MITE registers */
- iounmap(mite_base);
- return 0;
-}
-
-static int ni_65xx_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct ni_65xx_board *board = NULL;
- struct comedi_subdevice *s;
- unsigned int i;
- int ret;
-
- if (context < ARRAY_SIZE(ni_65xx_boards))
- board = &ni_65xx_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- ret = ni_65xx_mite_init(pcidev);
- if (ret)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 1);
- if (!dev->mmio)
- return -ENOMEM;
-
- writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
- dev->mmio + NI_65XX_CLR_REG);
- writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, ni_65xx_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name,
- readb(dev->mmio + NI_65XX_ID_REG));
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- if (board->num_di_ports) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_di_ports);
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni_65xx_dio_insn_bits;
- s->insn_config = ni_65xx_dio_insn_config;
-
- /* the input ports always start at port 0 */
- s->private = (void *)0;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[1];
- if (board->num_do_ports) {
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_do_ports);
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni_65xx_dio_insn_bits;
-
- /* the output ports always start after the input ports */
- s->private = (void *)(unsigned long)board->num_di_ports;
-
- /*
- * Use the io_bits to handle the inverted outputs. Inverted
- * outputs are only supported if the "legacy_invert_outputs"
- * module parameter is set to "true".
- */
- if (ni_65xx_legacy_invert_outputs && board->legacy_invert)
- s->io_bits = 0xff;
-
- /* reset all output ports to comedi '0' */
- for (i = 0; i < board->num_do_ports; ++i) {
- writeb(s->io_bits, /* inverted if necessary */
- dev->mmio +
- NI_65XX_IO_DATA_REG(board->num_di_ports + i));
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[2];
- if (board->num_dio_ports) {
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_dio_ports);
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni_65xx_dio_insn_bits;
- s->insn_config = ni_65xx_dio_insn_config;
-
- /* the input/output ports always start at port 0 */
- s->private = (void *)0;
-
- /* configure all ports for input */
- for (i = 0; i < board->num_dio_ports; ++i) {
- writeb(NI_65XX_IO_SEL_INPUT,
- dev->mmio + NI_65XX_IO_SEL_REG(i));
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni_65xx_intr_insn_bits;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 1;
- s->insn_config = ni_65xx_intr_insn_config;
- s->do_cmdtest = ni_65xx_intr_cmdtest;
- s->do_cmd = ni_65xx_intr_cmd;
- s->cancel = ni_65xx_intr_cancel;
- }
-
- ni_65xx_disable_input_filters(dev);
- ni_65xx_disable_edge_detection(dev);
-
- return 0;
-}
-
-static void ni_65xx_detach(struct comedi_device *dev)
-{
- if (dev->mmio)
- writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver ni_65xx_driver = {
- .driver_name = "ni_65xx",
- .module = THIS_MODULE,
- .auto_attach = ni_65xx_auto_attach,
- .detach = ni_65xx_detach,
-};
-
-static int ni_65xx_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &ni_65xx_driver, id->driver_data);
-}
-
-static const struct pci_device_id ni_65xx_pci_table[] = {
- { PCI_VDEVICE(NI, 0x1710), BOARD_PXI6509 },
- { PCI_VDEVICE(NI, 0x7085), BOARD_PCI6509 },
- { PCI_VDEVICE(NI, 0x7086), BOARD_PXI6528 },
- { PCI_VDEVICE(NI, 0x7087), BOARD_PCI6515 },
- { PCI_VDEVICE(NI, 0x7088), BOARD_PCI6514 },
- { PCI_VDEVICE(NI, 0x70a9), BOARD_PCI6528 },
- { PCI_VDEVICE(NI, 0x70c3), BOARD_PCI6511 },
- { PCI_VDEVICE(NI, 0x70c8), BOARD_PCI6513 },
- { PCI_VDEVICE(NI, 0x70c9), BOARD_PXI6515 },
- { PCI_VDEVICE(NI, 0x70cc), BOARD_PCI6512 },
- { PCI_VDEVICE(NI, 0x70cd), BOARD_PXI6514 },
- { PCI_VDEVICE(NI, 0x70d1), BOARD_PXI6513 },
- { PCI_VDEVICE(NI, 0x70d2), BOARD_PXI6512 },
- { PCI_VDEVICE(NI, 0x70d3), BOARD_PXI6511 },
- { PCI_VDEVICE(NI, 0x7124), BOARD_PCI6510 },
- { PCI_VDEVICE(NI, 0x7125), BOARD_PCI6516 },
- { PCI_VDEVICE(NI, 0x7126), BOARD_PCI6517 },
- { PCI_VDEVICE(NI, 0x7127), BOARD_PCI6518 },
- { PCI_VDEVICE(NI, 0x7128), BOARD_PCI6519 },
- { PCI_VDEVICE(NI, 0x718b), BOARD_PCI6521 },
- { PCI_VDEVICE(NI, 0x718c), BOARD_PXI6521 },
- { PCI_VDEVICE(NI, 0x71c5), BOARD_PCI6520 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table);
-
-static struct pci_driver ni_65xx_pci_driver = {
- .name = "ni_65xx",
- .id_table = ni_65xx_pci_table,
- .probe = ni_65xx_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for NI PCI-65xx static dio boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
deleted file mode 100644
index e60d0125bcb2..000000000000
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ /dev/null
@@ -1,1255 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Hardware driver for NI 660x devices
- */
-
-/*
- * Driver: ni_660x
- * Description: National Instruments 660x counter/timer boards
- * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
- * PCI-6608, PXI-6608, PCI-6624, PXI-6624
- * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
- * Herman.Bruyninckx@mech.kuleuven.ac.be,
- * Wim.Meeussen@mech.kuleuven.ac.be,
- * Klaas.Gadeyne@mech.kuleuven.ac.be,
- * Frank Mori Hess <fmhess@users.sourceforge.net>
- * Updated: Mon, 16 Jan 2017 14:00:43 +0000
- * Status: experimental
- *
- * Encoders work. PulseGeneration (both single pulse and pulse train)
- * works. Buffered commands work for input but not output.
- *
- * References:
- * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
- * DAQ 6601/6602 User Manual (NI 322137B-01)
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "mite.h"
-#include "ni_tio.h"
-#include "ni_routes.h"
-
-/* See Register-Level Programmer Manual page 3.1 */
-enum ni_660x_register {
- /* see enum ni_gpct_register */
- NI660X_STC_DIO_PARALLEL_INPUT = NITIO_NUM_REGS,
- NI660X_STC_DIO_OUTPUT,
- NI660X_STC_DIO_CONTROL,
- NI660X_STC_DIO_SERIAL_INPUT,
- NI660X_DIO32_INPUT,
- NI660X_DIO32_OUTPUT,
- NI660X_CLK_CFG,
- NI660X_GLOBAL_INT_STATUS,
- NI660X_DMA_CFG,
- NI660X_GLOBAL_INT_CFG,
- NI660X_IO_CFG_0_1,
- NI660X_IO_CFG_2_3,
- NI660X_IO_CFG_4_5,
- NI660X_IO_CFG_6_7,
- NI660X_IO_CFG_8_9,
- NI660X_IO_CFG_10_11,
- NI660X_IO_CFG_12_13,
- NI660X_IO_CFG_14_15,
- NI660X_IO_CFG_16_17,
- NI660X_IO_CFG_18_19,
- NI660X_IO_CFG_20_21,
- NI660X_IO_CFG_22_23,
- NI660X_IO_CFG_24_25,
- NI660X_IO_CFG_26_27,
- NI660X_IO_CFG_28_29,
- NI660X_IO_CFG_30_31,
- NI660X_IO_CFG_32_33,
- NI660X_IO_CFG_34_35,
- NI660X_IO_CFG_36_37,
- NI660X_IO_CFG_38_39,
- NI660X_NUM_REGS,
-};
-
-#define NI660X_CLK_CFG_COUNTER_SWAP BIT(21)
-
-#define NI660X_GLOBAL_INT_COUNTER0 BIT(8)
-#define NI660X_GLOBAL_INT_COUNTER1 BIT(9)
-#define NI660X_GLOBAL_INT_COUNTER2 BIT(10)
-#define NI660X_GLOBAL_INT_COUNTER3 BIT(11)
-#define NI660X_GLOBAL_INT_CASCADE BIT(29)
-#define NI660X_GLOBAL_INT_GLOBAL_POL BIT(30)
-#define NI660X_GLOBAL_INT_GLOBAL BIT(31)
-
-#define NI660X_DMA_CFG_SEL(_c, _s) (((_s) & 0x1f) << (8 * (_c)))
-#define NI660X_DMA_CFG_SEL_MASK(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
-#define NI660X_DMA_CFG_SEL_NONE(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
-#define NI660X_DMA_CFG_RESET(_c) NI660X_DMA_CFG_SEL((_c), 0x80)
-
-#define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2))
-#define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8))
-#define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3)
-#define NI660X_IO_CFG_IN_SEL(_c, _s) (((_s) & 0x7) << (((_c) % 2) ? 4 : 12))
-#define NI660X_IO_CFG_IN_SEL_MASK(_c) NI660X_IO_CFG_IN_SEL((_c), 0x7)
-
-struct ni_660x_register_data {
- int offset; /* Offset from base address from GPCT chip */
- char size; /* 2 or 4 bytes */
-};
-
-static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = {
- [NITIO_G0_INT_ACK] = { 0x004, 2 }, /* write */
- [NITIO_G0_STATUS] = { 0x004, 2 }, /* read */
- [NITIO_G1_INT_ACK] = { 0x006, 2 }, /* write */
- [NITIO_G1_STATUS] = { 0x006, 2 }, /* read */
- [NITIO_G01_STATUS] = { 0x008, 2 }, /* read */
- [NITIO_G0_CMD] = { 0x00c, 2 }, /* write */
- [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, 2 }, /* read */
- [NITIO_G1_CMD] = { 0x00e, 2 }, /* write */
- [NITIO_G0_HW_SAVE] = { 0x010, 4 }, /* read */
- [NITIO_G1_HW_SAVE] = { 0x014, 4 }, /* read */
- [NI660X_STC_DIO_OUTPUT] = { 0x014, 2 }, /* write */
- [NI660X_STC_DIO_CONTROL] = { 0x016, 2 }, /* write */
- [NITIO_G0_SW_SAVE] = { 0x018, 4 }, /* read */
- [NITIO_G1_SW_SAVE] = { 0x01c, 4 }, /* read */
- [NITIO_G0_MODE] = { 0x034, 2 }, /* write */
- [NITIO_G01_STATUS1] = { 0x036, 2 }, /* read */
- [NITIO_G1_MODE] = { 0x036, 2 }, /* write */
- [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, 2 }, /* read */
- [NITIO_G0_LOADA] = { 0x038, 4 }, /* write */
- [NITIO_G01_STATUS2] = { 0x03a, 2 }, /* read */
- [NITIO_G0_LOADB] = { 0x03c, 4 }, /* write */
- [NITIO_G1_LOADA] = { 0x040, 4 }, /* write */
- [NITIO_G1_LOADB] = { 0x044, 4 }, /* write */
- [NITIO_G0_INPUT_SEL] = { 0x048, 2 }, /* write */
- [NITIO_G1_INPUT_SEL] = { 0x04a, 2 }, /* write */
- [NITIO_G0_AUTO_INC] = { 0x088, 2 }, /* write */
- [NITIO_G1_AUTO_INC] = { 0x08a, 2 }, /* write */
- [NITIO_G01_RESET] = { 0x090, 2 }, /* write */
- [NITIO_G0_INT_ENA] = { 0x092, 2 }, /* write */
- [NITIO_G1_INT_ENA] = { 0x096, 2 }, /* write */
- [NITIO_G0_CNT_MODE] = { 0x0b0, 2 }, /* write */
- [NITIO_G1_CNT_MODE] = { 0x0b2, 2 }, /* write */
- [NITIO_G0_GATE2] = { 0x0b4, 2 }, /* write */
- [NITIO_G1_GATE2] = { 0x0b6, 2 }, /* write */
- [NITIO_G0_DMA_CFG] = { 0x0b8, 2 }, /* write */
- [NITIO_G0_DMA_STATUS] = { 0x0b8, 2 }, /* read */
- [NITIO_G1_DMA_CFG] = { 0x0ba, 2 }, /* write */
- [NITIO_G1_DMA_STATUS] = { 0x0ba, 2 }, /* read */
- [NITIO_G2_INT_ACK] = { 0x104, 2 }, /* write */
- [NITIO_G2_STATUS] = { 0x104, 2 }, /* read */
- [NITIO_G3_INT_ACK] = { 0x106, 2 }, /* write */
- [NITIO_G3_STATUS] = { 0x106, 2 }, /* read */
- [NITIO_G23_STATUS] = { 0x108, 2 }, /* read */
- [NITIO_G2_CMD] = { 0x10c, 2 }, /* write */
- [NITIO_G3_CMD] = { 0x10e, 2 }, /* write */
- [NITIO_G2_HW_SAVE] = { 0x110, 4 }, /* read */
- [NITIO_G3_HW_SAVE] = { 0x114, 4 }, /* read */
- [NITIO_G2_SW_SAVE] = { 0x118, 4 }, /* read */
- [NITIO_G3_SW_SAVE] = { 0x11c, 4 }, /* read */
- [NITIO_G2_MODE] = { 0x134, 2 }, /* write */
- [NITIO_G23_STATUS1] = { 0x136, 2 }, /* read */
- [NITIO_G3_MODE] = { 0x136, 2 }, /* write */
- [NITIO_G2_LOADA] = { 0x138, 4 }, /* write */
- [NITIO_G23_STATUS2] = { 0x13a, 2 }, /* read */
- [NITIO_G2_LOADB] = { 0x13c, 4 }, /* write */
- [NITIO_G3_LOADA] = { 0x140, 4 }, /* write */
- [NITIO_G3_LOADB] = { 0x144, 4 }, /* write */
- [NITIO_G2_INPUT_SEL] = { 0x148, 2 }, /* write */
- [NITIO_G3_INPUT_SEL] = { 0x14a, 2 }, /* write */
- [NITIO_G2_AUTO_INC] = { 0x188, 2 }, /* write */
- [NITIO_G3_AUTO_INC] = { 0x18a, 2 }, /* write */
- [NITIO_G23_RESET] = { 0x190, 2 }, /* write */
- [NITIO_G2_INT_ENA] = { 0x192, 2 }, /* write */
- [NITIO_G3_INT_ENA] = { 0x196, 2 }, /* write */
- [NITIO_G2_CNT_MODE] = { 0x1b0, 2 }, /* write */
- [NITIO_G3_CNT_MODE] = { 0x1b2, 2 }, /* write */
- [NITIO_G2_GATE2] = { 0x1b4, 2 }, /* write */
- [NITIO_G3_GATE2] = { 0x1b6, 2 }, /* write */
- [NITIO_G2_DMA_CFG] = { 0x1b8, 2 }, /* write */
- [NITIO_G2_DMA_STATUS] = { 0x1b8, 2 }, /* read */
- [NITIO_G3_DMA_CFG] = { 0x1ba, 2 }, /* write */
- [NITIO_G3_DMA_STATUS] = { 0x1ba, 2 }, /* read */
- [NI660X_DIO32_INPUT] = { 0x414, 4 }, /* read */
- [NI660X_DIO32_OUTPUT] = { 0x510, 4 }, /* write */
- [NI660X_CLK_CFG] = { 0x73c, 4 }, /* write */
- [NI660X_GLOBAL_INT_STATUS] = { 0x754, 4 }, /* read */
- [NI660X_DMA_CFG] = { 0x76c, 4 }, /* write */
- [NI660X_GLOBAL_INT_CFG] = { 0x770, 4 }, /* write */
- [NI660X_IO_CFG_0_1] = { 0x77c, 2 }, /* read/write */
- [NI660X_IO_CFG_2_3] = { 0x77e, 2 }, /* read/write */
- [NI660X_IO_CFG_4_5] = { 0x780, 2 }, /* read/write */
- [NI660X_IO_CFG_6_7] = { 0x782, 2 }, /* read/write */
- [NI660X_IO_CFG_8_9] = { 0x784, 2 }, /* read/write */
- [NI660X_IO_CFG_10_11] = { 0x786, 2 }, /* read/write */
- [NI660X_IO_CFG_12_13] = { 0x788, 2 }, /* read/write */
- [NI660X_IO_CFG_14_15] = { 0x78a, 2 }, /* read/write */
- [NI660X_IO_CFG_16_17] = { 0x78c, 2 }, /* read/write */
- [NI660X_IO_CFG_18_19] = { 0x78e, 2 }, /* read/write */
- [NI660X_IO_CFG_20_21] = { 0x790, 2 }, /* read/write */
- [NI660X_IO_CFG_22_23] = { 0x792, 2 }, /* read/write */
- [NI660X_IO_CFG_24_25] = { 0x794, 2 }, /* read/write */
- [NI660X_IO_CFG_26_27] = { 0x796, 2 }, /* read/write */
- [NI660X_IO_CFG_28_29] = { 0x798, 2 }, /* read/write */
- [NI660X_IO_CFG_30_31] = { 0x79a, 2 }, /* read/write */
- [NI660X_IO_CFG_32_33] = { 0x79c, 2 }, /* read/write */
- [NI660X_IO_CFG_34_35] = { 0x79e, 2 }, /* read/write */
- [NI660X_IO_CFG_36_37] = { 0x7a0, 2 }, /* read/write */
- [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */
-};
-
-#define NI660X_CHIP_OFFSET 0x800
-
-enum ni_660x_boardid {
- BOARD_PCI6601,
- BOARD_PCI6602,
- BOARD_PXI6602,
- BOARD_PCI6608,
- BOARD_PXI6608,
- BOARD_PCI6624,
- BOARD_PXI6624
-};
-
-struct ni_660x_board {
- const char *name;
- unsigned int n_chips; /* total number of TIO chips */
-};
-
-static const struct ni_660x_board ni_660x_boards[] = {
- [BOARD_PCI6601] = {
- .name = "PCI-6601",
- .n_chips = 1,
- },
- [BOARD_PCI6602] = {
- .name = "PCI-6602",
- .n_chips = 2,
- },
- [BOARD_PXI6602] = {
- .name = "PXI-6602",
- .n_chips = 2,
- },
- [BOARD_PCI6608] = {
- .name = "PCI-6608",
- .n_chips = 2,
- },
- [BOARD_PXI6608] = {
- .name = "PXI-6608",
- .n_chips = 2,
- },
- [BOARD_PCI6624] = {
- .name = "PCI-6624",
- .n_chips = 2,
- },
- [BOARD_PXI6624] = {
- .name = "PXI-6624",
- .n_chips = 2,
- },
-};
-
-#define NI660X_NUM_PFI_CHANNELS 40
-
-/* there are only up to 3 dma channels, but the register layout allows for 4 */
-#define NI660X_MAX_DMA_CHANNEL 4
-
-#define NI660X_COUNTERS_PER_CHIP 4
-#define NI660X_MAX_CHIPS 2
-#define NI660X_MAX_COUNTERS (NI660X_MAX_CHIPS * \
- NI660X_COUNTERS_PER_CHIP)
-
-struct ni_660x_private {
- struct mite *mite;
- struct ni_gpct_device *counter_dev;
- struct mite_ring *ring[NI660X_MAX_CHIPS][NI660X_COUNTERS_PER_CHIP];
- /* protects mite channel request/release */
- spinlock_t mite_channel_lock;
- /* prevents races between interrupt and comedi_poll */
- spinlock_t interrupt_lock;
- unsigned int dma_cfg[NI660X_MAX_CHIPS];
- unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS];
- u64 io_dir;
- struct ni_route_tables routing_tables;
-};
-
-static void ni_660x_write(struct comedi_device *dev, unsigned int chip,
- unsigned int bits, unsigned int reg)
-{
- unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
- ni_660x_reg_data[reg].offset;
-
- if (ni_660x_reg_data[reg].size == 2)
- writew(bits, dev->mmio + addr);
- else
- writel(bits, dev->mmio + addr);
-}
-
-static unsigned int ni_660x_read(struct comedi_device *dev,
- unsigned int chip, unsigned int reg)
-{
- unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
- ni_660x_reg_data[reg].offset;
-
- if (ni_660x_reg_data[reg].size == 2)
- return readw(dev->mmio + addr);
- return readl(dev->mmio + addr);
-}
-
-static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits,
- enum ni_gpct_register reg)
-{
- struct comedi_device *dev = counter->counter_dev->dev;
-
- ni_660x_write(dev, counter->chip_index, bits, reg);
-}
-
-static unsigned int ni_660x_gpct_read(struct ni_gpct *counter,
- enum ni_gpct_register reg)
-{
- struct comedi_device *dev = counter->counter_dev->dev;
-
- return ni_660x_read(dev, counter->chip_index, reg);
-}
-
-static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
- unsigned int mite_channel,
- struct ni_gpct *counter)
-{
- struct ni_660x_private *devpriv = dev->private;
- unsigned int chip = counter->chip_index;
-
- devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
- devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel,
- counter->counter_index);
- ni_660x_write(dev, chip, devpriv->dma_cfg[chip] |
- NI660X_DMA_CFG_RESET(mite_channel),
- NI660X_DMA_CFG);
-}
-
-static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
- unsigned int mite_channel,
- struct ni_gpct *counter)
-{
- struct ni_660x_private *devpriv = dev->private;
- unsigned int chip = counter->chip_index;
-
- devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
- devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel);
- ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG);
-}
-
-static int ni_660x_request_mite_channel(struct comedi_device *dev,
- struct ni_gpct *counter,
- enum comedi_io_direction direction)
-{
- struct ni_660x_private *devpriv = dev->private;
- struct mite_ring *ring;
- struct mite_channel *mite_chan;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- ring = devpriv->ring[counter->chip_index][counter->counter_index];
- mite_chan = mite_request_channel(devpriv->mite, ring);
- if (!mite_chan) {
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- dev_err(dev->class_dev,
- "failed to reserve mite dma channel for counter\n");
- return -EBUSY;
- }
- mite_chan->dir = direction;
- ni_tio_set_mite_channel(counter, mite_chan);
- ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- return 0;
-}
-
-static void ni_660x_release_mite_channel(struct comedi_device *dev,
- struct ni_gpct *counter)
-{
- struct ni_660x_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (counter->mite_chan) {
- struct mite_channel *mite_chan = counter->mite_chan;
-
- ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
- ni_tio_set_mite_channel(counter, NULL);
- mite_release_channel(mite_chan);
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-}
-
-static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
- int retval;
-
- retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
- if (retval) {
- dev_err(dev->class_dev,
- "no dma channel available for use by counter\n");
- return retval;
- }
- ni_tio_acknowledge(counter);
-
- return ni_tio_cmd(dev, s);
-}
-
-static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
- int retval;
-
- retval = ni_tio_cancel(counter);
- ni_660x_release_mite_channel(dev, counter);
- return retval;
-}
-
-static void set_tio_counterswap(struct comedi_device *dev, int chip)
-{
- unsigned int bits = 0;
-
- /*
- * See P. 3.5 of the Register-Level Programming manual.
- * The CounterSwap bit has to be set on the second chip,
- * otherwise it will try to use the same pins as the
- * first chip.
- */
- if (chip)
- bits = NI660X_CLK_CFG_COUNTER_SWAP;
-
- ni_660x_write(dev, chip, bits, NI660X_CLK_CFG);
-}
-
-static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
-
- ni_tio_handle_interrupt(counter, s);
- comedi_handle_events(dev, s);
-}
-
-static irqreturn_t ni_660x_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct ni_660x_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- unsigned int i;
- unsigned long flags;
-
- if (!dev->attached)
- return IRQ_NONE;
- /* make sure dev->attached is checked before doing anything else */
- smp_mb();
-
- /* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&devpriv->interrupt_lock, flags);
- for (i = 0; i < dev->n_subdevices; ++i) {
- s = &dev->subdevices[i];
- if (s->type == COMEDI_SUBD_COUNTER)
- ni_660x_handle_gpct_interrupt(dev, s);
- }
- spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
- return IRQ_HANDLED;
-}
-
-static int ni_660x_input_poll(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_660x_private *devpriv = dev->private;
- struct ni_gpct *counter = s->private;
- unsigned long flags;
-
- /* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&devpriv->interrupt_lock, flags);
- mite_sync_dma(counter->mite_chan, s);
- spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
- return comedi_buf_read_n_available(s);
-}
-
-static int ni_660x_buf_change(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_660x_private *devpriv = dev->private;
- struct ni_gpct *counter = s->private;
- struct mite_ring *ring;
- int ret;
-
- ring = devpriv->ring[counter->chip_index][counter->counter_index];
- ret = mite_buf_change(ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int ni_660x_allocate_private(struct comedi_device *dev)
-{
- struct ni_660x_private *devpriv;
- unsigned int i;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- spin_lock_init(&devpriv->mite_channel_lock);
- spin_lock_init(&devpriv->interrupt_lock);
- for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i)
- devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER;
-
- return 0;
-}
-
-static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
-{
- const struct ni_660x_board *board = dev->board_ptr;
- struct ni_660x_private *devpriv = dev->private;
- unsigned int i;
- unsigned int j;
-
- for (i = 0; i < board->n_chips; ++i) {
- for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j) {
- devpriv->ring[i][j] = mite_alloc_ring(devpriv->mite);
- if (!devpriv->ring[i][j])
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-static void ni_660x_free_mite_rings(struct comedi_device *dev)
-{
- const struct ni_660x_board *board = dev->board_ptr;
- struct ni_660x_private *devpriv = dev->private;
- unsigned int i;
- unsigned int j;
-
- for (i = 0; i < board->n_chips; ++i) {
- for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j)
- mite_free_ring(devpriv->ring[i][j]);
- }
-}
-
-static int ni_660x_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int shift = CR_CHAN(insn->chanspec);
- unsigned int mask = data[0] << shift;
- unsigned int bits = data[1] << shift;
-
- /*
- * There are 40 channels in this subdevice but only 32 are usable
- * as DIO. The shift adjusts the mask/bits to account for the base
- * channel in insn->chanspec. The state update can then be handled
- * normally for the 32 usable channels.
- */
- if (mask) {
- s->state &= ~mask;
- s->state |= (bits & mask);
- ni_660x_write(dev, 0, s->state, NI660X_DIO32_OUTPUT);
- }
-
- /*
- * Return the input channels, shifted back to account for the base
- * channel.
- */
- data[1] = ni_660x_read(dev, 0, NI660X_DIO32_INPUT) >> shift;
-
- return insn->n;
-}
-
-static void ni_660x_select_pfi_output(struct comedi_device *dev,
- unsigned int chan, unsigned int out_sel)
-{
- const struct ni_660x_board *board = dev->board_ptr;
- unsigned int active_chip = 0;
- unsigned int idle_chip = 0;
- unsigned int bits;
-
- if (chan >= NI_PFI(0))
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
-
- if (board->n_chips > 1) {
- if (out_sel == NI_660X_PFI_OUTPUT_COUNTER &&
- chan >= 8 && chan <= 23) {
- /* counters 4-7 pfi channels */
- active_chip = 1;
- idle_chip = 0;
- } else {
- /* counters 0-3 pfi channels */
- active_chip = 0;
- idle_chip = 1;
- }
- }
-
- if (idle_chip != active_chip) {
- /* set the pfi channel to high-z on the inactive chip */
- bits = ni_660x_read(dev, idle_chip, NI660X_IO_CFG(chan));
- bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
- bits |= NI660X_IO_CFG_OUT_SEL(chan, 0); /* high-z */
- ni_660x_write(dev, idle_chip, bits, NI660X_IO_CFG(chan));
- }
-
- /* set the pfi channel output on the active chip */
- bits = ni_660x_read(dev, active_chip, NI660X_IO_CFG(chan));
- bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
- bits |= NI660X_IO_CFG_OUT_SEL(chan, out_sel);
- ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan));
-}
-
-static void ni_660x_set_pfi_direction(struct comedi_device *dev,
- unsigned int chan,
- unsigned int direction)
-{
- struct ni_660x_private *devpriv = dev->private;
- u64 bit;
-
- if (chan >= NI_PFI(0))
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
-
- bit = 1ULL << chan;
-
- if (direction == COMEDI_OUTPUT) {
- devpriv->io_dir |= bit;
- /* reset the output to currently assigned output value */
- ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
- } else {
- devpriv->io_dir &= ~bit;
- /* set pin to high-z; do not change currently assigned route */
- ni_660x_select_pfi_output(dev, chan, 0);
- }
-}
-
-static unsigned int ni_660x_get_pfi_direction(struct comedi_device *dev,
- unsigned int chan)
-{
- struct ni_660x_private *devpriv = dev->private;
- u64 bit;
-
- if (chan >= NI_PFI(0))
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
-
- bit = 1ULL << chan;
-
- return (devpriv->io_dir & bit) ? COMEDI_OUTPUT : COMEDI_INPUT;
-}
-
-static int ni_660x_set_pfi_routing(struct comedi_device *dev,
- unsigned int chan, unsigned int source)
-{
- struct ni_660x_private *devpriv = dev->private;
-
- if (chan >= NI_PFI(0))
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
-
- switch (source) {
- case NI_660X_PFI_OUTPUT_COUNTER:
- if (chan < 8)
- return -EINVAL;
- break;
- case NI_660X_PFI_OUTPUT_DIO:
- if (chan > 31)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- devpriv->io_cfg[chan] = source;
- if (ni_660x_get_pfi_direction(dev, chan) == COMEDI_OUTPUT)
- ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
- return 0;
-}
-
-static int ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned int chan)
-{
- struct ni_660x_private *devpriv = dev->private;
-
- if (chan >= NI_PFI(0))
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
-
- return devpriv->io_cfg[chan];
-}
-
-static void ni_660x_set_pfi_filter(struct comedi_device *dev,
- unsigned int chan, unsigned int value)
-{
- unsigned int val;
-
- if (chan >= NI_PFI(0))
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
-
- val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan));
- val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
- val |= NI660X_IO_CFG_IN_SEL(chan, value);
- ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan));
-}
-
-static int ni_660x_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret;
-
- switch (data[0]) {
- case INSN_CONFIG_DIO_OUTPUT:
- ni_660x_set_pfi_direction(dev, chan, COMEDI_OUTPUT);
- break;
-
- case INSN_CONFIG_DIO_INPUT:
- ni_660x_set_pfi_direction(dev, chan, COMEDI_INPUT);
- break;
-
- case INSN_CONFIG_DIO_QUERY:
- data[1] = ni_660x_get_pfi_direction(dev, chan);
- break;
-
- case INSN_CONFIG_SET_ROUTING:
- ret = ni_660x_set_pfi_routing(dev, chan, data[1]);
- if (ret)
- return ret;
- break;
-
- case INSN_CONFIG_GET_ROUTING:
- data[1] = ni_660x_get_pfi_routing(dev, chan);
- break;
-
- case INSN_CONFIG_FILTER:
- ni_660x_set_pfi_filter(dev, chan, data[1]);
- break;
-
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static unsigned int _ni_get_valid_routes(struct comedi_device *dev,
- unsigned int n_pairs,
- unsigned int *pair_data)
-{
- struct ni_660x_private *devpriv = dev->private;
-
- return ni_get_valid_routes(&devpriv->routing_tables, n_pairs,
- pair_data);
-}
-
-/*
- * Retrieves the current source of the output selector for the given
- * destination. If the terminal for the destination is not already configured
- * as an output, this function returns -EINVAL as error.
- *
- * Return: The register value of the destination output selector;
- * -EINVAL if terminal is not configured for output.
- */
-static inline int get_output_select_source(int dest, struct comedi_device *dev)
-{
- struct ni_660x_private *devpriv = dev->private;
- int reg = -1;
-
- if (channel_is_pfi(dest)) {
- if (ni_660x_get_pfi_direction(dev, dest) == COMEDI_OUTPUT)
- reg = ni_660x_get_pfi_routing(dev, dest);
- } else if (channel_is_rtsi(dest)) {
- dev_dbg(dev->class_dev,
- "%s: unhandled rtsi destination (%d) queried\n",
- __func__, dest);
- /*
- * The following can be enabled when RTSI routing info is
- * determined (not currently documented):
- * if (ni_get_rtsi_direction(dev, dest) == COMEDI_OUTPUT) {
- * reg = ni_get_rtsi_routing(dev, dest);
-
- * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
- * dest = NI_RGOUT0; ** prepare for lookup below **
- * reg = get_rgout0_reg(dev);
- * } else if (reg >= NI_RTSI_OUTPUT_RTSI_BRD(0) &&
- * reg <= NI_RTSI_OUTPUT_RTSI_BRD(3)) {
- * const int i = reg - NI_RTSI_OUTPUT_RTSI_BRD(0);
-
- * dest = NI_RTSI_BRD(i); ** prepare for lookup **
- * reg = get_ith_rtsi_brd_reg(i, dev);
- * }
- * }
- */
- } else if (channel_is_ctr(dest)) {
- reg = ni_tio_get_routing(devpriv->counter_dev, dest);
- } else {
- dev_dbg(dev->class_dev,
- "%s: unhandled destination (%d) queried\n",
- __func__, dest);
- }
-
- if (reg >= 0)
- return ni_find_route_source(CR_CHAN(reg), dest,
- &devpriv->routing_tables);
- return -EINVAL;
-}
-
-/*
- * Test a route:
- *
- * Return: -1 if not connectible;
- * 0 if connectible and not connected;
- * 1 if connectible and connected.
- */
-static inline int test_route(unsigned int src, unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_660x_private *devpriv = dev->private;
- s8 reg = ni_route_to_register(CR_CHAN(src), dest,
- &devpriv->routing_tables);
-
- if (reg < 0)
- return -1;
- if (get_output_select_source(dest, dev) != CR_CHAN(src))
- return 0;
- return 1;
-}
-
-/* Connect the actual route. */
-static inline int connect_route(unsigned int src, unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_660x_private *devpriv = dev->private;
- s8 reg = ni_route_to_register(CR_CHAN(src), dest,
- &devpriv->routing_tables);
- s8 current_src;
-
- if (reg < 0)
- /* route is not valid */
- return -EINVAL;
-
- current_src = get_output_select_source(dest, dev);
- if (current_src == CR_CHAN(src))
- return -EALREADY;
- if (current_src >= 0)
- /* destination mux is already busy. complain, don't overwrite */
- return -EBUSY;
-
- /* The route is valid and available. Now connect... */
- if (channel_is_pfi(CR_CHAN(dest))) {
- /*
- * set routing and then direction so that the output does not
- * first get generated with the wrong pin
- */
- ni_660x_set_pfi_routing(dev, dest, reg);
- ni_660x_set_pfi_direction(dev, dest, COMEDI_OUTPUT);
- } else if (channel_is_rtsi(CR_CHAN(dest))) {
- dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
- __func__, dest);
- return -EINVAL;
- /*
- * The following can be enabled when RTSI routing info is
- * determined (not currently documented):
- * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
- * int ret = incr_rgout0_src_use(src, dev);
-
- * if (ret < 0)
- * return ret;
- * } else if (ni_rtsi_route_requires_mux(reg)) {
- * ** Attempt to allocate and route (src->brd) **
- * int brd = incr_rtsi_brd_src_use(src, dev);
-
- * if (brd < 0)
- * return brd;
-
- * ** Now lookup the register value for (brd->dest) **
- * reg = ni_lookup_route_register(brd, CR_CHAN(dest),
- * &devpriv->routing_tables);
- * }
-
- * ni_set_rtsi_direction(dev, dest, COMEDI_OUTPUT);
- * ni_set_rtsi_routing(dev, dest, reg);
- */
- } else if (channel_is_ctr(CR_CHAN(dest))) {
- /*
- * we are adding back the channel modifier info to set
- * invert/edge info passed by the user
- */
- ni_tio_set_routing(devpriv->counter_dev, dest,
- reg | (src & ~CR_CHAN(-1)));
- } else {
- return -EINVAL;
- }
- return 0;
-}
-
-static inline int disconnect_route(unsigned int src, unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_660x_private *devpriv = dev->private;
- s8 reg = ni_route_to_register(CR_CHAN(src), CR_CHAN(dest),
- &devpriv->routing_tables);
-
- if (reg < 0)
- /* route is not valid */
- return -EINVAL;
- if (get_output_select_source(dest, dev) != CR_CHAN(src))
- /* cannot disconnect something not connected */
- return -EINVAL;
-
- /* The route is valid and is connected. Now disconnect... */
- if (channel_is_pfi(CR_CHAN(dest))) {
- unsigned int source = ((CR_CHAN(dest) - NI_PFI(0)) < 8)
- ? NI_660X_PFI_OUTPUT_DIO
- : NI_660X_PFI_OUTPUT_COUNTER;
-
- /* set the pfi to high impedance, and disconnect */
- ni_660x_set_pfi_direction(dev, dest, COMEDI_INPUT);
- ni_660x_set_pfi_routing(dev, dest, source);
- } else if (channel_is_rtsi(CR_CHAN(dest))) {
- dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
- __func__, dest);
- return -EINVAL;
- /*
- * The following can be enabled when RTSI routing info is
- * determined (not currently documented):
- * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
- * int ret = decr_rgout0_src_use(src, dev);
-
- * if (ret < 0)
- * return ret;
- * } else if (ni_rtsi_route_requires_mux(reg)) {
- * ** find which RTSI_BRD line is source for rtsi pin **
- * int brd = ni_find_route_source(
- * ni_get_rtsi_routing(dev, dest), CR_CHAN(dest),
- * &devpriv->routing_tables);
-
- * if (brd < 0)
- * return brd;
-
- * ** decrement/disconnect RTSI_BRD line from source **
- * decr_rtsi_brd_src_use(src, brd, dev);
- * }
-
- * ** set rtsi output selector to default state **
- * reg = default_rtsi_routing[CR_CHAN(dest) - TRIGGER_LINE(0)];
- * ni_set_rtsi_direction(dev, dest, COMEDI_INPUT);
- * ni_set_rtsi_routing(dev, dest, reg);
- */
- } else if (channel_is_ctr(CR_CHAN(dest))) {
- ni_tio_unset_routing(devpriv->counter_dev, dest);
- } else {
- return -EINVAL;
- }
- return 0;
-}
-
-static int ni_global_insn_config(struct comedi_device *dev,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- switch (data[0]) {
- case INSN_DEVICE_CONFIG_TEST_ROUTE:
- data[0] = test_route(data[1], data[2], dev);
- return 2;
- case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
- return connect_route(data[1], data[2], dev);
- case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
- return disconnect_route(data[1], data[2], dev);
- /*
- * This case is already handled one level up.
- * case INSN_DEVICE_CONFIG_GET_ROUTES:
- */
- default:
- return -EINVAL;
- }
- return 1;
-}
-
-static void ni_660x_init_tio_chips(struct comedi_device *dev,
- unsigned int n_chips)
-{
- struct ni_660x_private *devpriv = dev->private;
- unsigned int chip;
- unsigned int chan;
-
- /*
- * We use the ioconfig registers to control dio direction, so zero
- * output enables in stc dio control reg.
- */
- ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL);
-
- for (chip = 0; chip < n_chips; ++chip) {
- /* init dma configuration register */
- devpriv->dma_cfg[chip] = 0;
- for (chan = 0; chan < NI660X_MAX_DMA_CHANNEL; ++chan)
- devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(chan);
- ni_660x_write(dev, chip, devpriv->dma_cfg[chip],
- NI660X_DMA_CFG);
-
- /* init ioconfig registers */
- for (chan = 0; chan < NI660X_NUM_PFI_CHANNELS; ++chan)
- ni_660x_write(dev, chip, 0, NI660X_IO_CFG(chan));
- }
-}
-
-static int ni_660x_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct ni_660x_board *board = NULL;
- struct ni_660x_private *devpriv;
- struct comedi_subdevice *s;
- struct ni_gpct_device *gpct_dev;
- unsigned int n_counters;
- int subdev;
- int ret;
- unsigned int i;
- unsigned int global_interrupt_config_bits;
-
- if (context < ARRAY_SIZE(ni_660x_boards))
- board = &ni_660x_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- ret = ni_660x_allocate_private(dev);
- if (ret < 0)
- return ret;
- devpriv = dev->private;
-
- devpriv->mite = mite_attach(dev, true); /* use win1 */
- if (!devpriv->mite)
- return -ENOMEM;
-
- ret = ni_660x_alloc_mite_rings(dev);
- if (ret < 0)
- return ret;
-
- ni_660x_init_tio_chips(dev, board->n_chips);
-
- /* prepare the device for globally-named routes. */
- if (ni_assign_device_routes("ni_660x", board->name, NULL,
- &devpriv->routing_tables) < 0) {
- dev_warn(dev->class_dev, "%s: %s device has no signal routing table.\n",
- __func__, board->name);
- dev_warn(dev->class_dev, "%s: High level NI signal names will not be available for this %s board.\n",
- __func__, board->name);
- } else {
- /*
- * only(?) assign insn_device_config if we have global names for
- * this device.
- */
- dev->insn_device_config = ni_global_insn_config;
- dev->get_valid_routes = _ni_get_valid_routes;
- }
-
- n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP;
- gpct_dev = ni_gpct_device_construct(dev,
- ni_660x_gpct_write,
- ni_660x_gpct_read,
- ni_gpct_variant_660x,
- n_counters,
- NI660X_COUNTERS_PER_CHIP,
- &devpriv->routing_tables);
- if (!gpct_dev)
- return -ENOMEM;
- devpriv->counter_dev = gpct_dev;
-
- ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS);
- if (ret)
- return ret;
-
- subdev = 0;
-
- s = &dev->subdevices[subdev++];
- /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
- s->type = COMEDI_SUBD_UNUSED;
-
- /*
- * Digital I/O subdevice
- *
- * There are 40 channels but only the first 32 can be digital I/Os.
- * The last 8 are dedicated to counters 0 and 1.
- *
- * Counter 0-3 signals are from the first TIO chip.
- * Counter 4-7 signals are from the second TIO chip.
- *
- * Comedi External
- * PFI Chan DIO Chan Counter Signal
- * ------- -------- --------------
- * 0 0
- * 1 1
- * 2 2
- * 3 3
- * 4 4
- * 5 5
- * 6 6
- * 7 7
- * 8 8 CTR 7 OUT
- * 9 9 CTR 7 AUX
- * 10 10 CTR 7 GATE
- * 11 11 CTR 7 SOURCE
- * 12 12 CTR 6 OUT
- * 13 13 CTR 6 AUX
- * 14 14 CTR 6 GATE
- * 15 15 CTR 6 SOURCE
- * 16 16 CTR 5 OUT
- * 17 17 CTR 5 AUX
- * 18 18 CTR 5 GATE
- * 19 19 CTR 5 SOURCE
- * 20 20 CTR 4 OUT
- * 21 21 CTR 4 AUX
- * 22 22 CTR 4 GATE
- * 23 23 CTR 4 SOURCE
- * 24 24 CTR 3 OUT
- * 25 25 CTR 3 AUX
- * 26 26 CTR 3 GATE
- * 27 27 CTR 3 SOURCE
- * 28 28 CTR 2 OUT
- * 29 29 CTR 2 AUX
- * 30 30 CTR 2 GATE
- * 31 31 CTR 2 SOURCE
- * 32 CTR 1 OUT
- * 33 CTR 1 AUX
- * 34 CTR 1 GATE
- * 35 CTR 1 SOURCE
- * 36 CTR 0 OUT
- * 37 CTR 0 AUX
- * 38 CTR 0 GATE
- * 39 CTR 0 SOURCE
- */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = NI660X_NUM_PFI_CHANNELS;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni_660x_dio_insn_bits;
- s->insn_config = ni_660x_dio_insn_config;
-
- /*
- * Default the DIO channels as:
- * chan 0-7: DIO inputs
- * chan 8-39: counter signal inputs
- */
- for (i = 0; i < s->n_chan; ++i) {
- unsigned int source = (i < 8) ? NI_660X_PFI_OUTPUT_DIO
- : NI_660X_PFI_OUTPUT_COUNTER;
-
- ni_660x_set_pfi_routing(dev, i, source);
- ni_660x_set_pfi_direction(dev, i, COMEDI_INPUT);/* high-z */
- }
-
- /* Counter subdevices (4 NI TIO General Purpose Counters per chip) */
- for (i = 0; i < NI660X_MAX_COUNTERS; ++i) {
- s = &dev->subdevices[subdev++];
- if (i < n_counters) {
- struct ni_gpct *counter = &gpct_dev->counters[i];
-
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
- SDF_LSAMPL | SDF_CMD_READ;
- s->n_chan = 3;
- s->maxdata = 0xffffffff;
- s->insn_read = ni_tio_insn_read;
- s->insn_write = ni_tio_insn_write;
- s->insn_config = ni_tio_insn_config;
- s->len_chanlist = 1;
- s->do_cmd = ni_660x_cmd;
- s->do_cmdtest = ni_tio_cmdtest;
- s->cancel = ni_660x_cancel;
- s->poll = ni_660x_input_poll;
- s->buf_change = ni_660x_buf_change;
- s->async_dma_dir = DMA_BIDIRECTIONAL;
- s->private = counter;
-
- ni_tio_init_counter(counter);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- }
-
- /*
- * To be safe, set counterswap bits on tio chips after all the counter
- * outputs have been set to high impedance mode.
- */
- for (i = 0; i < board->n_chips; ++i)
- set_tio_counterswap(dev, i);
-
- ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret < 0) {
- dev_warn(dev->class_dev, " irq not available\n");
- return ret;
- }
- dev->irq = pcidev->irq;
- global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL;
- if (board->n_chips > 1)
- global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE;
- ni_660x_write(dev, 0, global_interrupt_config_bits,
- NI660X_GLOBAL_INT_CFG);
-
- return 0;
-}
-
-static void ni_660x_detach(struct comedi_device *dev)
-{
- struct ni_660x_private *devpriv = dev->private;
-
- if (dev->irq) {
- ni_660x_write(dev, 0, 0, NI660X_GLOBAL_INT_CFG);
- free_irq(dev->irq, dev);
- }
- if (devpriv) {
- ni_gpct_device_destroy(devpriv->counter_dev);
- ni_660x_free_mite_rings(dev);
- mite_detach(devpriv->mite);
- }
- if (dev->mmio)
- iounmap(dev->mmio);
- comedi_pci_disable(dev);
-}
-
-static struct comedi_driver ni_660x_driver = {
- .driver_name = "ni_660x",
- .module = THIS_MODULE,
- .auto_attach = ni_660x_auto_attach,
- .detach = ni_660x_detach,
-};
-
-static int ni_660x_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data);
-}
-
-static const struct pci_device_id ni_660x_pci_table[] = {
- { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
- { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
- { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
- { PCI_VDEVICE(NI, 0x2db0), BOARD_PCI6608 },
- { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
- { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 },
- { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
-
-static struct pci_driver ni_660x_pci_driver = {
- .name = "ni_660x",
- .id_table = ni_660x_pci_table,
- .probe = ni_660x_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for NI 660x counter/timer boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
deleted file mode 100644
index c197e47486be..000000000000
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ /dev/null
@@ -1,282 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for NI 670x devices
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_670x
- * Description: National Instruments 670x
- * Author: Bart Joris <bjoris@advalvas.be>
- * Updated: Wed, 11 Dec 2002 18:25:35 -0800
- * Devices: [National Instruments] PCI-6703 (ni_670x), PCI-6704
- * Status: unknown
- *
- * Commands are not supported.
- *
- * Manuals:
- * 322110a.pdf PCI/PXI-6704 User Manual
- * 322110b.pdf PCI/PXI-6703/6704 User Manual
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include "../comedi_pci.h"
-
-#define AO_VALUE_OFFSET 0x00
-#define AO_CHAN_OFFSET 0x0c
-#define AO_STATUS_OFFSET 0x10
-#define AO_CONTROL_OFFSET 0x10
-#define DIO_PORT0_DIR_OFFSET 0x20
-#define DIO_PORT0_DATA_OFFSET 0x24
-#define DIO_PORT1_DIR_OFFSET 0x28
-#define DIO_PORT1_DATA_OFFSET 0x2c
-#define MISC_STATUS_OFFSET 0x14
-#define MISC_CONTROL_OFFSET 0x14
-
-enum ni_670x_boardid {
- BOARD_PCI6703,
- BOARD_PXI6704,
- BOARD_PCI6704,
-};
-
-struct ni_670x_board {
- const char *name;
- unsigned short ao_chans;
-};
-
-static const struct ni_670x_board ni_670x_boards[] = {
- [BOARD_PCI6703] = {
- .name = "PCI-6703",
- .ao_chans = 16,
- },
- [BOARD_PXI6704] = {
- .name = "PXI-6704",
- .ao_chans = 32,
- },
- [BOARD_PCI6704] = {
- .name = "PCI-6704",
- .ao_chans = 32,
- },
-};
-
-struct ni_670x_private {
- int boardtype;
- int dio;
-};
-
-static int ni_670x_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- /*
- * Channel number mapping:
- *
- * NI 6703/ NI 6704 | NI 6704 Only
- * -------------------------------
- * vch(0) : 0 | ich(16) : 1
- * vch(1) : 2 | ich(17) : 3
- * ... | ...
- * vch(15) : 30 | ich(31) : 31
- */
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- /* First write in channel register which channel to use */
- writel(((chan & 15) << 1) | ((chan & 16) >> 4),
- dev->mmio + AO_CHAN_OFFSET);
- /* write channel value */
- writel(val, dev->mmio + AO_VALUE_OFFSET);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int ni_670x_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- writel(s->state, dev->mmio + DIO_PORT0_DATA_OFFSET);
-
- data[1] = readl(dev->mmio + DIO_PORT0_DATA_OFFSET);
-
- return insn->n;
-}
-
-static int ni_670x_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- writel(s->io_bits, dev->mmio + DIO_PORT0_DIR_OFFSET);
-
- return insn->n;
-}
-
-/* ripped from mite.h and mite_setup2() to avoid mite dependency */
-#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
-#define WENAB BIT(7) /* window enable */
-
-static int ni_670x_mite_init(struct pci_dev *pcidev)
-{
- void __iomem *mite_base;
- u32 main_phys_addr;
-
- /* ioremap the MITE registers (BAR 0) temporarily */
- mite_base = pci_ioremap_bar(pcidev, 0);
- if (!mite_base)
- return -ENOMEM;
-
- /* set data window to main registers (BAR 1) */
- main_phys_addr = pci_resource_start(pcidev, 1);
- writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
-
- /* finished with MITE registers */
- iounmap(mite_base);
- return 0;
-}
-
-static int ni_670x_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct ni_670x_board *board = NULL;
- struct ni_670x_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
- int i;
-
- if (context < ARRAY_SIZE(ni_670x_boards))
- board = &ni_670x_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = ni_670x_mite_init(pcidev);
- if (ret)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 1);
- if (!dev->mmio)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->ao_chans;
- s->maxdata = 0xffff;
- if (s->n_chan == 32) {
- const struct comedi_lrange **range_table_list;
-
- range_table_list = kmalloc_array(32,
- sizeof(struct comedi_lrange *),
- GFP_KERNEL);
- if (!range_table_list)
- return -ENOMEM;
- s->range_table_list = range_table_list;
- for (i = 0; i < 16; i++) {
- range_table_list[i] = &range_bipolar10;
- range_table_list[16 + i] = &range_0_20mA;
- }
- } else {
- s->range_table = &range_bipolar10;
- }
- s->insn_write = ni_670x_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s = &dev->subdevices[1];
- /* digital i/o subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni_670x_dio_insn_bits;
- s->insn_config = ni_670x_dio_insn_config;
-
- /* Config of misc registers */
- writel(0x10, dev->mmio + MISC_CONTROL_OFFSET);
- /* Config of ao registers */
- writel(0x00, dev->mmio + AO_CONTROL_OFFSET);
-
- return 0;
-}
-
-static void ni_670x_detach(struct comedi_device *dev)
-{
- struct comedi_subdevice *s;
-
- comedi_pci_detach(dev);
- if (dev->n_subdevices) {
- s = &dev->subdevices[0];
- if (s)
- kfree(s->range_table_list);
- }
-}
-
-static struct comedi_driver ni_670x_driver = {
- .driver_name = "ni_670x",
- .module = THIS_MODULE,
- .auto_attach = ni_670x_auto_attach,
- .detach = ni_670x_detach,
-};
-
-static int ni_670x_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &ni_670x_driver, id->driver_data);
-}
-
-static const struct pci_device_id ni_670x_pci_table[] = {
- { PCI_VDEVICE(NI, 0x1290), BOARD_PCI6704 },
- { PCI_VDEVICE(NI, 0x1920), BOARD_PXI6704 },
- { PCI_VDEVICE(NI, 0x2c90), BOARD_PCI6703 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ni_670x_pci_table);
-
-static struct pci_driver ni_670x_pci_driver = {
- .name = "ni_670x",
- .id_table = ni_670x_pci_table,
- .probe = ni_670x_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(ni_670x_driver, ni_670x_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
deleted file mode 100644
index 10ad7b88713e..000000000000
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ /dev/null
@@ -1,782 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for National Instruments AT-A2150 boards
- * Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_at_a2150
- * Description: National Instruments AT-A2150
- * Author: Frank Mori Hess
- * Status: works
- * Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (optional, required for timed conversions)
- * [2] - DMA (optional, required for timed conversions)
- *
- * Yet another driver for obsolete hardware brought to you by Frank Hess.
- * Testing and debugging help provided by Dave Andruczyk.
- *
- * If you want to ac couple the board's inputs, use AREF_OTHER.
- *
- * The only difference in the boards is their master clock frequencies.
- *
- * References (from ftp://ftp.natinst.com/support/manuals):
- * 320360.pdf AT-A2150 User Manual
- *
- * TODO:
- * - analog level triggering
- * - TRIG_WAKE_EOS
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-#include "comedi_8254.h"
-
-#define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
-
-/* Registers and bits */
-#define CONFIG_REG 0x0
-#define CHANNEL_BITS(x) ((x) & 0x7)
-#define CHANNEL_MASK 0x7
-#define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
-#define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
-#define CLOCK_MASK (0xf << 3)
-/* enable (don't internally ground) channels 0 and 1 */
-#define ENABLE0_BIT 0x80
-/* enable (don't internally ground) channels 2 and 3 */
-#define ENABLE1_BIT 0x100
-#define AC0_BIT 0x200 /* ac couple channels 0,1 */
-#define AC1_BIT 0x400 /* ac couple channels 2,3 */
-#define APD_BIT 0x800 /* analog power down */
-#define DPD_BIT 0x1000 /* digital power down */
-#define TRIGGER_REG 0x2 /* trigger config register */
-#define POST_TRIGGER_BITS 0x2
-#define DELAY_TRIGGER_BITS 0x3
-#define HW_TRIG_EN 0x10 /* enable hardware trigger */
-#define FIFO_START_REG 0x6 /* software start aquistion trigger */
-#define FIFO_RESET_REG 0x8 /* clears fifo + fifo flags */
-#define FIFO_DATA_REG 0xa /* read data */
-#define DMA_TC_CLEAR_REG 0xe /* clear dma terminal count interrupt */
-#define STATUS_REG 0x12 /* read only */
-#define FNE_BIT 0x1 /* fifo not empty */
-#define OVFL_BIT 0x8 /* fifo overflow */
-#define EDAQ_BIT 0x10 /* end of acquisition interrupt */
-#define DCAL_BIT 0x20 /* offset calibration in progress */
-#define INTR_BIT 0x40 /* interrupt has occurred */
-/* dma terminal count interrupt has occurred */
-#define DMA_TC_BIT 0x80
-#define ID_BITS(x) (((x) >> 8) & 0x3)
-#define IRQ_DMA_CNTRL_REG 0x12 /* write only */
-#define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */
-#define DMA_EN_BIT 0x8 /* enables dma */
-#define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */
-#define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */
-#define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */
-/* enable interrupt on dma terminal count */
-#define DMA_INTR_EN_BIT 0x800
-#define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */
-#define I8253_BASE_REG 0x14
-
-struct a2150_board {
- const char *name;
- int clock[4]; /* master clock periods, in nanoseconds */
- int num_clocks; /* number of available master clock speeds */
- int ai_speed; /* maximum conversion rate in nanoseconds */
-};
-
-/* analog input range */
-static const struct comedi_lrange range_a2150 = {
- 1, {
- BIP_RANGE(2.828)
- }
-};
-
-/* enum must match board indices */
-enum { a2150_c, a2150_s };
-static const struct a2150_board a2150_boards[] = {
- {
- .name = "at-a2150c",
- .clock = {31250, 22676, 20833, 19531},
- .num_clocks = 4,
- .ai_speed = 19531,
- },
- {
- .name = "at-a2150s",
- .clock = {62500, 50000, 41667, 0},
- .num_clocks = 3,
- .ai_speed = 41667,
- },
-};
-
-struct a2150_private {
- struct comedi_isadma *dma;
- unsigned int count; /* number of data points left to be taken */
- int irq_dma_bits; /* irq/dma register bits */
- int config_bits; /* config register bits */
-};
-
-/* interrupt service routine */
-static irqreturn_t a2150_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct a2150_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[0];
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned short *buf = desc->virt_addr;
- unsigned int max_points, num_points, residue, leftover;
- unsigned short dpnt;
- int status;
- int i;
-
- if (!dev->attached)
- return IRQ_HANDLED;
-
- status = inw(dev->iobase + STATUS_REG);
- if ((status & INTR_BIT) == 0)
- return IRQ_NONE;
-
- if (status & OVFL_BIT) {
- async->events |= COMEDI_CB_ERROR;
- comedi_handle_events(dev, s);
- }
-
- if ((status & DMA_TC_BIT) == 0) {
- async->events |= COMEDI_CB_ERROR;
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
- }
-
- /*
- * residue is the number of bytes left to be done on the dma
- * transfer. It should always be zero at this point unless
- * the stop_src is set to external triggering.
- */
- residue = comedi_isadma_disable(desc->chan);
-
- /* figure out how many points to read */
- max_points = comedi_bytes_to_samples(s, desc->size);
- num_points = max_points - comedi_bytes_to_samples(s, residue);
- if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
- num_points = devpriv->count;
-
- /* figure out how many points will be stored next time */
- leftover = 0;
- if (cmd->stop_src == TRIG_NONE) {
- leftover = comedi_bytes_to_samples(s, desc->size);
- } else if (devpriv->count > max_points) {
- leftover = devpriv->count - max_points;
- if (leftover > max_points)
- leftover = max_points;
- }
- /*
- * There should only be a residue if collection was stopped by having
- * the stop_src set to an external trigger, in which case there
- * will be no more data
- */
- if (residue)
- leftover = 0;
-
- for (i = 0; i < num_points; i++) {
- /* write data point to comedi buffer */
- dpnt = buf[i];
- /* convert from 2's complement to unsigned coding */
- dpnt ^= 0x8000;
- comedi_buf_write_samples(s, &dpnt, 1);
- if (cmd->stop_src == TRIG_COUNT) {
- if (--devpriv->count == 0) { /* end of acquisition */
- async->events |= COMEDI_CB_EOA;
- break;
- }
- }
- }
- /* re-enable dma */
- if (leftover) {
- desc->size = comedi_samples_to_bytes(s, leftover);
- comedi_isadma_program(desc);
- }
-
- comedi_handle_events(dev, s);
-
- /* clear interrupt */
- outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
-
- return IRQ_HANDLED;
-}
-
-static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct a2150_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[0];
-
- /* disable dma on card */
- devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
- outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
-
- /* disable computer's dma */
- comedi_isadma_disable(desc->chan);
-
- /* clear fifo and reset triggering circuitry */
- outw(0, dev->iobase + FIFO_RESET_REG);
-
- return 0;
-}
-
-/*
- * sets bits in devpriv->clock_bits to nearest approximation of requested
- * period, adjusts requested period to actual timing.
- */
-static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
- unsigned int flags)
-{
- const struct a2150_board *board = dev->board_ptr;
- struct a2150_private *devpriv = dev->private;
- int lub, glb, temp;
- int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
- int i, j;
-
- /* initialize greatest lower and least upper bounds */
- lub_divisor_shift = 3;
- lub_index = 0;
- lub = board->clock[lub_index] * (1 << lub_divisor_shift);
- glb_divisor_shift = 0;
- glb_index = board->num_clocks - 1;
- glb = board->clock[glb_index] * (1 << glb_divisor_shift);
-
- /* make sure period is in available range */
- if (*period < glb)
- *period = glb;
- if (*period > lub)
- *period = lub;
-
- /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
- for (i = 0; i < 4; i++) {
- /* there are a maximum of 4 master clocks */
- for (j = 0; j < board->num_clocks; j++) {
- /* temp is the period in nanosec we are evaluating */
- temp = board->clock[j] * (1 << i);
- /* if it is the best match yet */
- if (temp < lub && temp >= *period) {
- lub_divisor_shift = i;
- lub_index = j;
- lub = temp;
- }
- if (temp > glb && temp <= *period) {
- glb_divisor_shift = i;
- glb_index = j;
- glb = temp;
- }
- }
- }
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- /* if least upper bound is better approximation */
- if (lub - *period < *period - glb)
- *period = lub;
- else
- *period = glb;
- break;
- case CMDF_ROUND_UP:
- *period = lub;
- break;
- case CMDF_ROUND_DOWN:
- *period = glb;
- break;
- }
-
- /* set clock bits for config register appropriately */
- devpriv->config_bits &= ~CLOCK_MASK;
- if (*period == lub) {
- devpriv->config_bits |=
- CLOCK_SELECT_BITS(lub_index) |
- CLOCK_DIVISOR_BITS(lub_divisor_shift);
- } else {
- devpriv->config_bits |=
- CLOCK_SELECT_BITS(glb_index) |
- CLOCK_DIVISOR_BITS(glb_divisor_shift);
- }
-
- return 0;
-}
-
-static int a2150_set_chanlist(struct comedi_device *dev,
- unsigned int start_channel,
- unsigned int num_channels)
-{
- struct a2150_private *devpriv = dev->private;
-
- if (start_channel + num_channels > 4)
- return -1;
-
- devpriv->config_bits &= ~CHANNEL_MASK;
-
- switch (num_channels) {
- case 1:
- devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
- break;
- case 2:
- if (start_channel == 0)
- devpriv->config_bits |= CHANNEL_BITS(0x2);
- else if (start_channel == 2)
- devpriv->config_bits |= CHANNEL_BITS(0x3);
- else
- return -1;
- break;
- case 4:
- devpriv->config_bits |= CHANNEL_BITS(0x1);
- break;
- default:
- return -1;
- }
-
- return 0;
-}
-
-static int a2150_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
- int i;
-
- if (cmd->chanlist_len == 2 && (chan0 == 1 || chan0 == 3)) {
- dev_dbg(dev->class_dev,
- "length 2 chanlist must be channels 0,1 or channels 2,3\n");
- return -EINVAL;
- }
-
- if (cmd->chanlist_len == 3) {
- dev_dbg(dev->class_dev,
- "chanlist must have 1,2 or 4 channels\n");
- return -EINVAL;
- }
-
- for (i = 1; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- if (chan != (chan0 + i)) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
- return -EINVAL;
- }
-
- if (chan == 2)
- aref0 = aref;
- if (aref != aref0) {
- dev_dbg(dev->class_dev,
- "channels 0/1 and 2/3 must have the same analog reference\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int a2150_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- const struct a2150_board *board = dev->board_ptr;
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- a2150_get_timing(dev, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= a2150_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct a2150_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[0];
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int old_config_bits = devpriv->config_bits;
- unsigned int trigger_bits;
-
- if (cmd->flags & CMDF_PRIORITY) {
- dev_err(dev->class_dev,
- "dma incompatible with hard real-time interrupt (CMDF_PRIORITY), aborting\n");
- return -1;
- }
- /* clear fifo and reset triggering circuitry */
- outw(0, dev->iobase + FIFO_RESET_REG);
-
- /* setup chanlist */
- if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
- cmd->chanlist_len) < 0)
- return -1;
-
- /* setup ac/dc coupling */
- if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
- devpriv->config_bits |= AC0_BIT;
- else
- devpriv->config_bits &= ~AC0_BIT;
- if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
- devpriv->config_bits |= AC1_BIT;
- else
- devpriv->config_bits &= ~AC1_BIT;
-
- /* setup timing */
- a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
-
- /* send timing, channel, config bits */
- outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
-
- /* initialize number of samples remaining */
- devpriv->count = cmd->stop_arg * cmd->chanlist_len;
-
- comedi_isadma_disable(desc->chan);
-
- /* set size of transfer to fill in 1/3 second */
-#define ONE_THIRD_SECOND 333333333
- desc->size = comedi_bytes_per_sample(s) * cmd->chanlist_len *
- ONE_THIRD_SECOND / cmd->scan_begin_arg;
- if (desc->size > desc->maxsize)
- desc->size = desc->maxsize;
- if (desc->size < comedi_bytes_per_sample(s))
- desc->size = comedi_bytes_per_sample(s);
- desc->size -= desc->size % comedi_bytes_per_sample(s);
-
- comedi_isadma_program(desc);
-
- /*
- * Clear dma interrupt before enabling it, to try and get rid of
- * that one spurious interrupt that has been happening.
- */
- outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
-
- /* enable dma on card */
- devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
- outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
-
- /* may need to wait 72 sampling periods if timing was changed */
- comedi_8254_load(dev->pacer, 2, 72, I8254_MODE0 | I8254_BINARY);
-
- /* setup start triggering */
- trigger_bits = 0;
- /* decide if we need to wait 72 periods for valid data */
- if (cmd->start_src == TRIG_NOW &&
- (old_config_bits & CLOCK_MASK) !=
- (devpriv->config_bits & CLOCK_MASK)) {
- /* set trigger source to delay trigger */
- trigger_bits |= DELAY_TRIGGER_BITS;
- } else {
- /* otherwise no delay */
- trigger_bits |= POST_TRIGGER_BITS;
- }
- /* enable external hardware trigger */
- if (cmd->start_src == TRIG_EXT) {
- trigger_bits |= HW_TRIG_EN;
- } else if (cmd->start_src == TRIG_OTHER) {
- /*
- * XXX add support for level/slope start trigger
- * using TRIG_OTHER
- */
- dev_err(dev->class_dev, "you shouldn't see this?\n");
- }
- /* send trigger config bits */
- outw(trigger_bits, dev->iobase + TRIGGER_REG);
-
- /* start acquisition for soft trigger */
- if (cmd->start_src == TRIG_NOW)
- outw(0, dev->iobase + FIFO_START_REG);
-
- return 0;
-}
-
-static int a2150_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + STATUS_REG);
- if (status & FNE_BIT)
- return 0;
- return -EBUSY;
-}
-
-static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct a2150_private *devpriv = dev->private;
- unsigned int n;
- int ret;
-
- /* clear fifo and reset triggering circuitry */
- outw(0, dev->iobase + FIFO_RESET_REG);
-
- /* setup chanlist */
- if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
- return -1;
-
- /* set dc coupling */
- devpriv->config_bits &= ~AC0_BIT;
- devpriv->config_bits &= ~AC1_BIT;
-
- /* send timing, channel, config bits */
- outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
-
- /* disable dma on card */
- devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
- outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
-
- /* setup start triggering */
- outw(0, dev->iobase + TRIGGER_REG);
-
- /* start acquisition for soft trigger */
- outw(0, dev->iobase + FIFO_START_REG);
-
- /*
- * there is a 35.6 sample delay for data to get through the
- * antialias filter
- */
- for (n = 0; n < 36; n++) {
- ret = comedi_timeout(dev, s, insn, a2150_ai_eoc, 0);
- if (ret)
- return ret;
-
- inw(dev->iobase + FIFO_DATA_REG);
- }
-
- /* read data */
- for (n = 0; n < insn->n; n++) {
- ret = comedi_timeout(dev, s, insn, a2150_ai_eoc, 0);
- if (ret)
- return ret;
-
- data[n] = inw(dev->iobase + FIFO_DATA_REG);
- data[n] ^= 0x8000;
- }
-
- /* clear fifo and reset triggering circuitry */
- outw(0, dev->iobase + FIFO_RESET_REG);
-
- return n;
-}
-
-static void a2150_alloc_irq_and_dma(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct a2150_private *devpriv = dev->private;
- unsigned int irq_num = it->options[1];
- unsigned int dma_chan = it->options[2];
-
- /*
- * Only IRQs 15, 14, 12-9, and 7-3 are valid.
- * Only DMA channels 7-5 and 3-0 are valid.
- */
- if (irq_num > 15 || dma_chan > 7 ||
- !((1 << irq_num) & 0xdef8) || !((1 << dma_chan) & 0xef))
- return;
-
- if (request_irq(irq_num, a2150_interrupt, 0, dev->board_name, dev))
- return;
-
- /* DMA uses 1 buffer */
- devpriv->dma = comedi_isadma_alloc(dev, 1, dma_chan, dma_chan,
- A2150_DMA_BUFFER_SIZE,
- COMEDI_ISADMA_READ);
- if (!devpriv->dma) {
- free_irq(irq_num, dev);
- } else {
- dev->irq = irq_num;
- devpriv->irq_dma_bits = IRQ_LVL_BITS(irq_num) |
- DMA_CHAN_BITS(dma_chan);
- }
-}
-
-static void a2150_free_dma(struct comedi_device *dev)
-{
- struct a2150_private *devpriv = dev->private;
-
- if (devpriv)
- comedi_isadma_free(devpriv->dma);
-}
-
-static const struct a2150_board *a2150_probe(struct comedi_device *dev)
-{
- int id = ID_BITS(inw(dev->iobase + STATUS_REG));
-
- if (id >= ARRAY_SIZE(a2150_boards))
- return NULL;
-
- return &a2150_boards[id];
-}
-
-static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct a2150_board *board;
- struct a2150_private *devpriv;
- struct comedi_subdevice *s;
- static const int timeout = 2000;
- int i;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x1c);
- if (ret)
- return ret;
-
- board = a2150_probe(dev);
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- /* an IRQ and DMA are required to support async commands */
- a2150_alloc_irq_and_dma(dev, it);
-
- dev->pacer = comedi_8254_init(dev->iobase + I8253_BASE_REG,
- 0, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* analog input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->range_table = &range_a2150;
- s->insn_read = a2150_ai_rinsn;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmd = a2150_ai_cmd;
- s->do_cmdtest = a2150_ai_cmdtest;
- s->cancel = a2150_cancel;
- }
-
- /* set card's irq and dma levels */
- outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
-
- /* reset and sync adc clock circuitry */
- outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
- outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
- /* initialize configuration register */
- devpriv->config_bits = 0;
- outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
- /* wait until offset calibration is done, then enable analog inputs */
- for (i = 0; i < timeout; i++) {
- if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
- break;
- usleep_range(1000, 3000);
- }
- if (i == timeout) {
- dev_err(dev->class_dev,
- "timed out waiting for offset calibration to complete\n");
- return -ETIME;
- }
- devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
- outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
-
- return 0;
-};
-
-static void a2150_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
- a2150_free_dma(dev);
- comedi_legacy_detach(dev);
-};
-
-static struct comedi_driver ni_at_a2150_driver = {
- .driver_name = "ni_at_a2150",
- .module = THIS_MODULE,
- .attach = a2150_attach,
- .detach = a2150_detach,
-};
-module_comedi_driver(ni_at_a2150_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
deleted file mode 100644
index 2a0fb4d460db..000000000000
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ /dev/null
@@ -1,374 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * ni_at_ao.c
- * Driver for NI AT-AO-6/10 boards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_at_ao
- * Description: National Instruments AT-AO-6/10
- * Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
- * Status: should work
- * Author: David A. Schleef <ds@schleef.org>
- * Updated: Sun Dec 26 12:26:28 EST 2004
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (unused)
- * [2] - DMA (unused)
- * [3] - analog output range, set by jumpers on hardware
- * 0 for -10 to 10V bipolar
- * 1 for 0V to 10V unipolar
- */
-
-#include <linux/module.h>
-
-#include "../comedidev.h"
-
-#include "comedi_8254.h"
-
-/*
- * Register map
- *
- * Register-level programming information can be found in NI
- * document 320379.pdf.
- */
-#define ATAO_DIO_REG 0x00
-#define ATAO_CFG2_REG 0x02
-#define ATAO_CFG2_CALLD_NOP (0 << 14)
-#define ATAO_CFG2_CALLD(x) ((((x) >> 3) + 1) << 14)
-#define ATAO_CFG2_FFRTEN BIT(13)
-#define ATAO_CFG2_DACS(x) (1 << (((x) / 2) + 8))
-#define ATAO_CFG2_LDAC(x) (1 << (((x) / 2) + 3))
-#define ATAO_CFG2_PROMEN BIT(2)
-#define ATAO_CFG2_SCLK BIT(1)
-#define ATAO_CFG2_SDATA BIT(0)
-#define ATAO_CFG3_REG 0x04
-#define ATAO_CFG3_DMAMODE BIT(6)
-#define ATAO_CFG3_CLKOUT BIT(5)
-#define ATAO_CFG3_RCLKEN BIT(4)
-#define ATAO_CFG3_DOUTEN2 BIT(3)
-#define ATAO_CFG3_DOUTEN1 BIT(2)
-#define ATAO_CFG3_EN2_5V BIT(1)
-#define ATAO_CFG3_SCANEN BIT(0)
-#define ATAO_82C53_BASE 0x06
-#define ATAO_CFG1_REG 0x0a
-#define ATAO_CFG1_EXTINT2EN BIT(15)
-#define ATAO_CFG1_EXTINT1EN BIT(14)
-#define ATAO_CFG1_CNTINT2EN BIT(13)
-#define ATAO_CFG1_CNTINT1EN BIT(12)
-#define ATAO_CFG1_TCINTEN BIT(11)
-#define ATAO_CFG1_CNT1SRC BIT(10)
-#define ATAO_CFG1_CNT2SRC BIT(9)
-#define ATAO_CFG1_FIFOEN BIT(8)
-#define ATAO_CFG1_GRP2WR BIT(7)
-#define ATAO_CFG1_EXTUPDEN BIT(6)
-#define ATAO_CFG1_DMARQ BIT(5)
-#define ATAO_CFG1_DMAEN BIT(4)
-#define ATAO_CFG1_CH(x) (((x) & 0xf) << 0)
-#define ATAO_STATUS_REG 0x0a
-#define ATAO_STATUS_FH BIT(6)
-#define ATAO_STATUS_FE BIT(5)
-#define ATAO_STATUS_FF BIT(4)
-#define ATAO_STATUS_INT2 BIT(3)
-#define ATAO_STATUS_INT1 BIT(2)
-#define ATAO_STATUS_TCINT BIT(1)
-#define ATAO_STATUS_PROMOUT BIT(0)
-#define ATAO_FIFO_WRITE_REG 0x0c
-#define ATAO_FIFO_CLEAR_REG 0x0c
-#define ATAO_AO_REG(x) (0x0c + ((x) * 2))
-
-/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
-#define ATAO_2_DMATCCLR_REG 0x00
-#define ATAO_2_INT1CLR_REG 0x02
-#define ATAO_2_INT2CLR_REG 0x04
-#define ATAO_2_RTSISHFT_REG 0x06
-#define ATAO_2_RTSISHFT_RSI BIT(0)
-#define ATAO_2_RTSISTRB_REG 0x07
-
-struct atao_board {
- const char *name;
- int n_ao_chans;
-};
-
-static const struct atao_board atao_boards[] = {
- {
- .name = "at-ao-6",
- .n_ao_chans = 6,
- }, {
- .name = "at-ao-10",
- .n_ao_chans = 10,
- },
-};
-
-struct atao_private {
- unsigned short cfg1;
- unsigned short cfg3;
-
- /* Used for caldac readback */
- unsigned char caldac[21];
-};
-
-static void atao_select_reg_group(struct comedi_device *dev, int group)
-{
- struct atao_private *devpriv = dev->private;
-
- if (group)
- devpriv->cfg1 |= ATAO_CFG1_GRP2WR;
- else
- devpriv->cfg1 &= ~ATAO_CFG1_GRP2WR;
- outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
-}
-
-static int atao_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- if (chan == 0)
- atao_select_reg_group(dev, 1);
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
-
- /* the hardware expects two's complement values */
- outw(comedi_offset_munge(s, val),
- dev->iobase + ATAO_AO_REG(chan));
- }
- s->readback[chan] = val;
-
- if (chan == 0)
- atao_select_reg_group(dev, 0);
-
- return insn->n;
-}
-
-static int atao_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + ATAO_DIO_REG);
-
- data[1] = inw(dev->iobase + ATAO_DIO_REG);
-
- return insn->n;
-}
-
-static int atao_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct atao_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 4)
- mask = 0x0f;
- else
- mask = 0xf0;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- if (s->io_bits & 0x0f)
- devpriv->cfg3 |= ATAO_CFG3_DOUTEN1;
- else
- devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN1;
- if (s->io_bits & 0xf0)
- devpriv->cfg3 |= ATAO_CFG3_DOUTEN2;
- else
- devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN2;
-
- outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
-
- return insn->n;
-}
-
-/*
- * There are three DAC8800 TrimDACs on the board. These are 8-channel,
- * 8-bit DACs that are used to calibrate the Analog Output channels.
- * The factory default calibration values are stored in the EEPROM.
- * The TrimDACs, and EEPROM addresses, are mapped as:
- *
- * Channel EEPROM Description
- * ----------------- ------ -----------------------------------
- * 0 - DAC0 Chan 0 0x30 AO Channel 0 Offset
- * 1 - DAC0 Chan 1 0x31 AO Channel 0 Gain
- * 2 - DAC0 Chan 2 0x32 AO Channel 1 Offset
- * 3 - DAC0 Chan 3 0x33 AO Channel 1 Gain
- * 4 - DAC0 Chan 4 0x34 AO Channel 2 Offset
- * 5 - DAC0 Chan 5 0x35 AO Channel 2 Gain
- * 6 - DAC0 Chan 6 0x36 AO Channel 3 Offset
- * 7 - DAC0 Chan 7 0x37 AO Channel 3 Gain
- * 8 - DAC1 Chan 0 0x38 AO Channel 4 Offset
- * 9 - DAC1 Chan 1 0x39 AO Channel 4 Gain
- * 10 - DAC1 Chan 2 0x3a AO Channel 5 Offset
- * 11 - DAC1 Chan 3 0x3b AO Channel 5 Gain
- * 12 - DAC1 Chan 4 0x3c 2.5V Offset
- * 13 - DAC1 Chan 5 0x3d AO Channel 6 Offset (at-ao-10 only)
- * 14 - DAC1 Chan 6 0x3e AO Channel 6 Gain (at-ao-10 only)
- * 15 - DAC1 Chan 7 0x3f AO Channel 7 Offset (at-ao-10 only)
- * 16 - DAC2 Chan 0 0x40 AO Channel 7 Gain (at-ao-10 only)
- * 17 - DAC2 Chan 1 0x41 AO Channel 8 Offset (at-ao-10 only)
- * 18 - DAC2 Chan 2 0x42 AO Channel 8 Gain (at-ao-10 only)
- * 19 - DAC2 Chan 3 0x43 AO Channel 9 Offset (at-ao-10 only)
- * 20 - DAC2 Chan 4 0x44 AO Channel 9 Gain (at-ao-10 only)
- * DAC2 Chan 5 0x45 Reserved
- * DAC2 Chan 6 0x46 Reserved
- * DAC2 Chan 7 0x47 Reserved
- */
-static int atao_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
- unsigned int bitstring = ((chan & 0x7) << 8) | val;
- unsigned int bits;
- int bit;
-
- /* write the channel and last data value to the caldac */
- /* clock the bitstring to the caldac; MSB -> LSB */
- for (bit = BIT(10); bit; bit >>= 1) {
- bits = (bit & bitstring) ? ATAO_CFG2_SDATA : 0;
-
- outw(bits, dev->iobase + ATAO_CFG2_REG);
- outw(bits | ATAO_CFG2_SCLK,
- dev->iobase + ATAO_CFG2_REG);
- }
-
- /* strobe the caldac to load the value */
- outw(ATAO_CFG2_CALLD(chan), dev->iobase + ATAO_CFG2_REG);
- outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static void atao_reset(struct comedi_device *dev)
-{
- struct atao_private *devpriv = dev->private;
-
- /* This is the reset sequence described in the manual */
-
- devpriv->cfg1 = 0;
- outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
-
- /* Put outputs of counter 1 and counter 2 in a high state */
- comedi_8254_set_mode(dev->pacer, 0, I8254_MODE4 | I8254_BINARY);
- comedi_8254_set_mode(dev->pacer, 1, I8254_MODE4 | I8254_BINARY);
- comedi_8254_write(dev->pacer, 0, 0x0003);
-
- outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
-
- devpriv->cfg3 = 0;
- outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
-
- inw(dev->iobase + ATAO_FIFO_CLEAR_REG);
-
- atao_select_reg_group(dev, 1);
- outw(0, dev->iobase + ATAO_2_INT1CLR_REG);
- outw(0, dev->iobase + ATAO_2_INT2CLR_REG);
- outw(0, dev->iobase + ATAO_2_DMATCCLR_REG);
- atao_select_reg_group(dev, 0);
-}
-
-static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct atao_board *board = dev->board_ptr;
- struct atao_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x20);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- dev->pacer = comedi_8254_init(dev->iobase + ATAO_82C53_BASE,
- 0, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->n_ao_chans;
- s->maxdata = 0x0fff;
- s->range_table = it->options[3] ? &range_unipolar10 : &range_bipolar10;
- s->insn_write = atao_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = atao_dio_insn_bits;
- s->insn_config = atao_dio_insn_config;
-
- /* caldac subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = (board->n_ao_chans * 2) + 1;
- s->maxdata = 0xff;
- s->insn_write = atao_calib_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* EEPROM subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_UNUSED;
-
- atao_reset(dev);
-
- return 0;
-}
-
-static struct comedi_driver ni_at_ao_driver = {
- .driver_name = "ni_at_ao",
- .module = THIS_MODULE,
- .attach = atao_attach,
- .detach = comedi_legacy_detach,
- .board_name = &atao_boards[0].name,
- .offset = sizeof(struct atao_board),
- .num_names = ARRAY_SIZE(atao_boards),
-};
-module_comedi_driver(ni_at_ao_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for NI AT-AO-6/10 boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
deleted file mode 100644
index 56c78da475e7..000000000000
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ /dev/null
@@ -1,360 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for NI AT-MIO E series cards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_atmio
- * Description: National Instruments AT-MIO-E series
- * Author: ds
- * Devices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
- * AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
- * AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
- * Status: works
- * Updated: Thu May 1 20:03:02 CDT 2003
- *
- * The driver has 2.6 kernel isapnp support, and will automatically probe for
- * a supported board if the I/O base is left unspecified with comedi_config.
- * However, many of the isapnp id numbers are unknown. If your board is not
- * recognized, please send the output of 'cat /proc/isapnp' (you may need to
- * modprobe the isa-pnp module for /proc/isapnp to exist) so the id numbers
- * for your board can be added to the driver.
- *
- * Otherwise, you can use the isapnptools package to configure your board.
- * Use isapnp to configure the I/O base and IRQ for the board, and then pass
- * the same values as parameters in comedi_config. A sample isapnp.conf file
- * is included in the etc/ directory of Comedilib.
- *
- * Comedilib includes a utility to autocalibrate these boards. The boards
- * seem to boot into a state where the all calibration DACs are at one
- * extreme of their range, thus the default calibration is terrible.
- * Calibration at boot is strongly encouraged.
- *
- * To use the extended digital I/O on some of the boards, enable the
- * 8255 driver when configuring the Comedi source tree.
- *
- * External triggering is supported for some events. The channel index
- * (scan_begin_arg, etc.) maps to PFI0 - PFI9.
- *
- * Some of the more esoteric triggering possibilities of these boards are
- * not supported.
- */
-
-/*
- * The real guts of the driver is in ni_mio_common.c, which is included
- * both here and in ni_pcimio.c
- *
- * Interrupt support added by Truxton Fulton <trux@truxton.com>
- *
- * References for specifications:
- * 340747b.pdf Register Level Programmer Manual (obsolete)
- * 340747c.pdf Register Level Programmer Manual (new)
- * DAQ-STC reference manual
- *
- * Other possibly relevant info:
- * 320517c.pdf User manual (obsolete)
- * 320517f.pdf User manual (new)
- * 320889a.pdf delete
- * 320906c.pdf maximum signal ratings
- * 321066a.pdf about 16x
- * 321791a.pdf discontinuation of at-mio-16e-10 rev. c
- * 321808a.pdf about at-mio-16e-10 rev P
- * 321837a.pdf discontinuation of at-mio-16de-10 rev d
- * 321838a.pdf about at-mio-16de-10 rev N
- *
- * ISSUES:
- * - need to deal with external reference for DAC, and other DAC
- * properties in board properties
- * - deal with at-mio-16de-10 revision D to N changes, etc.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include "../comedidev.h"
-
-#include <linux/isapnp.h>
-
-#include "ni_stc.h"
-#include "8255.h"
-
-/* AT specific setup */
-static const struct ni_board_struct ni_boards[] = {
- {
- .name = "at-mio-16e-1",
- .device_id = 44,
- .isapnp_id = 0x0000, /* XXX unknown */
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 8192,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { mb88341 },
- }, {
- .name = "at-mio-16e-2",
- .device_id = 25,
- .isapnp_id = 0x1900,
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 2048,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { mb88341 },
- }, {
- .name = "at-mio-16e-10",
- .device_id = 36,
- .isapnp_id = 0x2400,
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_16,
- .ai_speed = 10000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 10000,
- .caldac = { ad8804_debug },
- }, {
- .name = "at-mio-16de-10",
- .device_id = 37,
- .isapnp_id = 0x2500,
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_16,
- .ai_speed = 10000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 10000,
- .caldac = { ad8804_debug },
- .has_8255 = 1,
- }, {
- .name = "at-mio-64e-3",
- .device_id = 38,
- .isapnp_id = 0x2600,
- .n_adchan = 64,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 2048,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { ad8804_debug },
- }, {
- .name = "at-mio-16xe-50",
- .device_id = 39,
- .isapnp_id = 0x2700,
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_8,
- .ai_speed = 50000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 50000,
- .caldac = { dac8800, dac8043 },
- }, {
- .name = "at-mio-16xe-10",
- .device_id = 50,
- .isapnp_id = 0x0000, /* XXX unknown */
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { dac8800, dac8043, ad8522 },
- }, {
- .name = "at-ai-16xe-10",
- .device_id = 51,
- .isapnp_id = 0x0000, /* XXX unknown */
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1, /* unknown */
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .caldac = { dac8800, dac8043, ad8522 },
- },
-};
-
-static const int ni_irqpin[] = {
- -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7
-};
-
-#include "ni_mio_common.c"
-
-static const struct pnp_device_id device_ids[] = {
- {.id = "NIC1900", .driver_data = 0},
- {.id = "NIC2400", .driver_data = 0},
- {.id = "NIC2500", .driver_data = 0},
- {.id = "NIC2600", .driver_data = 0},
- {.id = "NIC2700", .driver_data = 0},
- {.id = ""}
-};
-
-MODULE_DEVICE_TABLE(pnp, device_ids);
-
-static int ni_isapnp_find_board(struct pnp_dev **dev)
-{
- struct pnp_dev *isapnp_dev = NULL;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
- isapnp_dev =
- pnp_find_dev(NULL,
- ISAPNP_VENDOR('N', 'I', 'C'),
- ISAPNP_FUNCTION(ni_boards[i].isapnp_id),
- NULL);
-
- if (!isapnp_dev || !isapnp_dev->card)
- continue;
-
- if (pnp_device_attach(isapnp_dev) < 0)
- continue;
-
- if (pnp_activate_dev(isapnp_dev) < 0) {
- pnp_device_detach(isapnp_dev);
- return -EAGAIN;
- }
-
- if (!pnp_port_valid(isapnp_dev, 0) ||
- !pnp_irq_valid(isapnp_dev, 0)) {
- pnp_device_detach(isapnp_dev);
- return -ENOMEM;
- }
- break;
- }
- if (i == ARRAY_SIZE(ni_boards))
- return -ENODEV;
- *dev = isapnp_dev;
- return 0;
-}
-
-static const struct ni_board_struct *ni_atmio_probe(struct comedi_device *dev)
-{
- int device_id = ni_read_eeprom(dev, 511);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
- const struct ni_board_struct *board = &ni_boards[i];
-
- if (board->device_id == device_id)
- return board;
- }
- if (device_id == 255)
- dev_err(dev->class_dev, "can't find board\n");
- else if (device_id == 0)
- dev_err(dev->class_dev,
- "EEPROM read error (?) or device not found\n");
- else
- dev_err(dev->class_dev,
- "unknown device ID %d -- contact author\n", device_id);
-
- return NULL;
-}
-
-static int ni_atmio_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct ni_board_struct *board;
- struct pnp_dev *isapnp_dev;
- int ret;
- unsigned long iobase;
- unsigned int irq;
-
- ret = ni_alloc_private(dev);
- if (ret)
- return ret;
-
- iobase = it->options[0];
- irq = it->options[1];
- isapnp_dev = NULL;
- if (iobase == 0) {
- ret = ni_isapnp_find_board(&isapnp_dev);
- if (ret < 0)
- return ret;
-
- iobase = pnp_port_start(isapnp_dev, 0);
- irq = pnp_irq(isapnp_dev, 0);
- comedi_set_hw_dev(dev, &isapnp_dev->dev);
- }
-
- ret = comedi_request_region(dev, iobase, 0x20);
- if (ret)
- return ret;
-
- board = ni_atmio_probe(dev);
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- /* irq stuff */
-
- if (irq != 0) {
- if (irq > 15 || ni_irqpin[irq] == -1)
- return -EINVAL;
- ret = request_irq(irq, ni_E_interrupt, 0,
- dev->board_name, dev);
- if (ret < 0)
- return -EINVAL;
- dev->irq = irq;
- }
-
- /* generic E series stuff in ni_mio_common.c */
-
- ret = ni_E_init(dev, ni_irqpin[dev->irq], 0);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static void ni_atmio_detach(struct comedi_device *dev)
-{
- struct pnp_dev *isapnp_dev;
-
- mio_common_detach(dev);
- comedi_legacy_detach(dev);
-
- isapnp_dev = dev->hw_dev ? to_pnp_dev(dev->hw_dev) : NULL;
- if (isapnp_dev)
- pnp_device_detach(isapnp_dev);
-}
-
-static struct comedi_driver ni_atmio_driver = {
- .driver_name = "ni_atmio",
- .module = THIS_MODULE,
- .attach = ni_atmio_attach,
- .detach = ni_atmio_detach,
-};
-module_comedi_driver(ni_atmio_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
deleted file mode 100644
index dffce1aa3e69..000000000000
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ /dev/null
@@ -1,729 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for National Instruments AT-MIO16D board
- * Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
- */
-
-/*
- * Driver: ni_atmio16d
- * Description: National Instruments AT-MIO-16D
- * Author: Chris R. Baugher <baugher@enteract.com>
- * Status: unknown
- * Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
- *
- * Configuration options:
- * [0] - I/O port
- * [1] - MIO irq (0 == no irq; or 3,4,5,6,7,9,10,11,12,14,15)
- * [2] - DIO irq (0 == no irq; or 3,4,5,6,7,9)
- * [3] - DMA1 channel (0 == no DMA; or 5,6,7)
- * [4] - DMA2 channel (0 == no DMA; or 5,6,7)
- * [5] - a/d mux (0=differential; 1=single)
- * [6] - a/d range (0=bipolar10; 1=bipolar5; 2=unipolar10)
- * [7] - dac0 range (0=bipolar; 1=unipolar)
- * [8] - dac0 reference (0=internal; 1=external)
- * [9] - dac0 coding (0=2's comp; 1=straight binary)
- * [10] - dac1 range (same as dac0 options)
- * [11] - dac1 reference (same as dac0 options)
- * [12] - dac1 coding (same as dac0 options)
- */
-
-/*
- * I must give credit here to Michal Dobes <dobes@tesnet.cz> who
- * wrote the driver for Advantec's pcl812 boards. I used the interrupt
- * handling code from his driver as an example for this one.
- *
- * Chris Baugher
- * 5/1/2000
- *
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include "../comedidev.h"
-
-#include "8255.h"
-
-/* Configuration and Status Registers */
-#define COM_REG_1 0x00 /* wo 16 */
-#define STAT_REG 0x00 /* ro 16 */
-#define COM_REG_2 0x02 /* wo 16 */
-/* Event Strobe Registers */
-#define START_CONVERT_REG 0x08 /* wo 16 */
-#define START_DAQ_REG 0x0A /* wo 16 */
-#define AD_CLEAR_REG 0x0C /* wo 16 */
-#define EXT_STROBE_REG 0x0E /* wo 16 */
-/* Analog Output Registers */
-#define DAC0_REG 0x10 /* wo 16 */
-#define DAC1_REG 0x12 /* wo 16 */
-#define INT2CLR_REG 0x14 /* wo 16 */
-/* Analog Input Registers */
-#define MUX_CNTR_REG 0x04 /* wo 16 */
-#define MUX_GAIN_REG 0x06 /* wo 16 */
-#define AD_FIFO_REG 0x16 /* ro 16 */
-#define DMA_TC_INT_CLR_REG 0x16 /* wo 16 */
-/* AM9513A Counter/Timer Registers */
-#define AM9513A_DATA_REG 0x18 /* rw 16 */
-#define AM9513A_COM_REG 0x1A /* wo 16 */
-#define AM9513A_STAT_REG 0x1A /* ro 16 */
-/* MIO-16 Digital I/O Registers */
-#define MIO_16_DIG_IN_REG 0x1C /* ro 16 */
-#define MIO_16_DIG_OUT_REG 0x1C /* wo 16 */
-/* RTSI Switch Registers */
-#define RTSI_SW_SHIFT_REG 0x1E /* wo 8 */
-#define RTSI_SW_STROBE_REG 0x1F /* wo 8 */
-/* DIO-24 Registers */
-#define DIO_24_PORTA_REG 0x00 /* rw 8 */
-#define DIO_24_PORTB_REG 0x01 /* rw 8 */
-#define DIO_24_PORTC_REG 0x02 /* rw 8 */
-#define DIO_24_CNFG_REG 0x03 /* wo 8 */
-
-/* Command Register bits */
-#define COMREG1_2SCADC 0x0001
-#define COMREG1_1632CNT 0x0002
-#define COMREG1_SCANEN 0x0008
-#define COMREG1_DAQEN 0x0010
-#define COMREG1_DMAEN 0x0020
-#define COMREG1_CONVINTEN 0x0080
-#define COMREG2_SCN2 0x0010
-#define COMREG2_INTEN 0x0080
-#define COMREG2_DOUTEN0 0x0100
-#define COMREG2_DOUTEN1 0x0200
-/* Status Register bits */
-#define STAT_AD_OVERRUN 0x0100
-#define STAT_AD_OVERFLOW 0x0200
-#define STAT_AD_DAQPROG 0x0800
-#define STAT_AD_CONVAVAIL 0x2000
-#define STAT_AD_DAQSTOPINT 0x4000
-/* AM9513A Counter/Timer defines */
-#define CLOCK_1_MHZ 0x8B25
-#define CLOCK_100_KHZ 0x8C25
-#define CLOCK_10_KHZ 0x8D25
-#define CLOCK_1_KHZ 0x8E25
-#define CLOCK_100_HZ 0x8F25
-
-struct atmio16_board_t {
- const char *name;
- int has_8255;
-};
-
-/* range structs */
-static const struct comedi_lrange range_atmio16d_ai_10_bipolar = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.02)
- }
-};
-
-static const struct comedi_lrange range_atmio16d_ai_5_bipolar = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_atmio16d_ai_unipolar = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.02)
- }
-};
-
-/* private data struct */
-struct atmio16d_private {
- enum { adc_diff, adc_singleended } adc_mux;
- enum { adc_bipolar10, adc_bipolar5, adc_unipolar10 } adc_range;
- enum { adc_2comp, adc_straight } adc_coding;
- enum { dac_bipolar, dac_unipolar } dac0_range, dac1_range;
- enum { dac_internal, dac_external } dac0_reference, dac1_reference;
- enum { dac_2comp, dac_straight } dac0_coding, dac1_coding;
- const struct comedi_lrange *ao_range_type_list[2];
- unsigned int com_reg_1_state; /* current state of command register 1 */
- unsigned int com_reg_2_state; /* current state of command register 2 */
-};
-
-static void reset_counters(struct comedi_device *dev)
-{
- /* Counter 2 */
- outw(0xFFC2, dev->iobase + AM9513A_COM_REG);
- outw(0xFF02, dev->iobase + AM9513A_COM_REG);
- outw(0x4, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
- outw(0x3, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF42, dev->iobase + AM9513A_COM_REG);
- outw(0xFF42, dev->iobase + AM9513A_COM_REG);
- /* Counter 3 */
- outw(0xFFC4, dev->iobase + AM9513A_COM_REG);
- outw(0xFF03, dev->iobase + AM9513A_COM_REG);
- outw(0x4, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
- outw(0x3, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF44, dev->iobase + AM9513A_COM_REG);
- outw(0xFF44, dev->iobase + AM9513A_COM_REG);
- /* Counter 4 */
- outw(0xFFC8, dev->iobase + AM9513A_COM_REG);
- outw(0xFF04, dev->iobase + AM9513A_COM_REG);
- outw(0x4, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
- outw(0x3, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF48, dev->iobase + AM9513A_COM_REG);
- outw(0xFF48, dev->iobase + AM9513A_COM_REG);
- /* Counter 5 */
- outw(0xFFD0, dev->iobase + AM9513A_COM_REG);
- outw(0xFF05, dev->iobase + AM9513A_COM_REG);
- outw(0x4, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
- outw(0x3, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF50, dev->iobase + AM9513A_COM_REG);
- outw(0xFF50, dev->iobase + AM9513A_COM_REG);
-
- outw(0, dev->iobase + AD_CLEAR_REG);
-}
-
-static void reset_atmio16d(struct comedi_device *dev)
-{
- struct atmio16d_private *devpriv = dev->private;
- int i;
-
- /* now we need to initialize the board */
- outw(0, dev->iobase + COM_REG_1);
- outw(0, dev->iobase + COM_REG_2);
- outw(0, dev->iobase + MUX_GAIN_REG);
- /* init AM9513A timer */
- outw(0xFFFF, dev->iobase + AM9513A_COM_REG);
- outw(0xFFEF, dev->iobase + AM9513A_COM_REG);
- outw(0xFF17, dev->iobase + AM9513A_COM_REG);
- outw(0xF000, dev->iobase + AM9513A_DATA_REG);
- for (i = 1; i <= 5; ++i) {
- outw(0xFF00 + i, dev->iobase + AM9513A_COM_REG);
- outw(0x0004, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF08 + i, dev->iobase + AM9513A_COM_REG);
- outw(0x3, dev->iobase + AM9513A_DATA_REG);
- }
- outw(0xFF5F, dev->iobase + AM9513A_COM_REG);
- /* timer init done */
- outw(0, dev->iobase + AD_CLEAR_REG);
- outw(0, dev->iobase + INT2CLR_REG);
- /* select straight binary mode for Analog Input */
- devpriv->com_reg_1_state |= 1;
- outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
- devpriv->adc_coding = adc_straight;
- /* zero the analog outputs */
- outw(2048, dev->iobase + DAC0_REG);
- outw(2048, dev->iobase + DAC1_REG);
-}
-
-static irqreturn_t atmio16d_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned short val;
-
- val = inw(dev->iobase + AD_FIFO_REG);
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int atmio16d_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_FOLLOW | TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- return 0;
-}
-
-static int atmio16d_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct atmio16d_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int timer, base_clock;
- unsigned int sample_count, tmp, chan, gain;
- int i;
-
- /*
- * This is slowly becoming a working command interface.
- * It is still uber-experimental
- */
-
- reset_counters(dev);
-
- /* check if scanning multiple channels */
- if (cmd->chanlist_len < 2) {
- devpriv->com_reg_1_state &= ~COMREG1_SCANEN;
- outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
- } else {
- devpriv->com_reg_1_state |= COMREG1_SCANEN;
- devpriv->com_reg_2_state |= COMREG2_SCN2;
- outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
- outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
- }
-
- /* Setup the Mux-Gain Counter */
- for (i = 0; i < cmd->chanlist_len; ++i) {
- chan = CR_CHAN(cmd->chanlist[i]);
- gain = CR_RANGE(cmd->chanlist[i]);
- outw(i, dev->iobase + MUX_CNTR_REG);
- tmp = chan | (gain << 6);
- if (i == cmd->scan_end_arg - 1)
- tmp |= 0x0010; /* set LASTONE bit */
- outw(tmp, dev->iobase + MUX_GAIN_REG);
- }
-
- /*
- * Now program the sample interval timer.
- * Figure out which clock to use then get an appropriate timer value.
- */
- if (cmd->convert_arg < 65536000) {
- base_clock = CLOCK_1_MHZ;
- timer = cmd->convert_arg / 1000;
- } else if (cmd->convert_arg < 655360000) {
- base_clock = CLOCK_100_KHZ;
- timer = cmd->convert_arg / 10000;
- } else /* cmd->convert_arg < 6553600000 */ {
- base_clock = CLOCK_10_KHZ;
- timer = cmd->convert_arg / 100000;
- }
- outw(0xFF03, dev->iobase + AM9513A_COM_REG);
- outw(base_clock, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
- outw(0x2, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF44, dev->iobase + AM9513A_COM_REG);
- outw(0xFFF3, dev->iobase + AM9513A_COM_REG);
- outw(timer, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF24, dev->iobase + AM9513A_COM_REG);
-
- /* Now figure out how many samples to get */
- /* and program the sample counter */
- sample_count = cmd->stop_arg * cmd->scan_end_arg;
- outw(0xFF04, dev->iobase + AM9513A_COM_REG);
- outw(0x1025, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
- if (sample_count < 65536) {
- /* use only Counter 4 */
- outw(sample_count, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF48, dev->iobase + AM9513A_COM_REG);
- outw(0xFFF4, dev->iobase + AM9513A_COM_REG);
- outw(0xFF28, dev->iobase + AM9513A_COM_REG);
- devpriv->com_reg_1_state &= ~COMREG1_1632CNT;
- outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
- } else {
- /* Counter 4 and 5 are needed */
-
- tmp = sample_count & 0xFFFF;
- if (tmp)
- outw(tmp - 1, dev->iobase + AM9513A_DATA_REG);
- else
- outw(0xFFFF, dev->iobase + AM9513A_DATA_REG);
-
- outw(0xFF48, dev->iobase + AM9513A_COM_REG);
- outw(0, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF28, dev->iobase + AM9513A_COM_REG);
- outw(0xFF05, dev->iobase + AM9513A_COM_REG);
- outw(0x25, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
- tmp = sample_count & 0xFFFF;
- if ((tmp == 0) || (tmp == 1)) {
- outw((sample_count >> 16) & 0xFFFF,
- dev->iobase + AM9513A_DATA_REG);
- } else {
- outw(((sample_count >> 16) & 0xFFFF) + 1,
- dev->iobase + AM9513A_DATA_REG);
- }
- outw(0xFF70, dev->iobase + AM9513A_COM_REG);
- devpriv->com_reg_1_state |= COMREG1_1632CNT;
- outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
- }
-
- /*
- * Program the scan interval timer ONLY IF SCANNING IS ENABLED.
- * Figure out which clock to use then get an appropriate timer value.
- */
- if (cmd->chanlist_len > 1) {
- if (cmd->scan_begin_arg < 65536000) {
- base_clock = CLOCK_1_MHZ;
- timer = cmd->scan_begin_arg / 1000;
- } else if (cmd->scan_begin_arg < 655360000) {
- base_clock = CLOCK_100_KHZ;
- timer = cmd->scan_begin_arg / 10000;
- } else /* cmd->scan_begin_arg < 6553600000 */ {
- base_clock = CLOCK_10_KHZ;
- timer = cmd->scan_begin_arg / 100000;
- }
- outw(0xFF02, dev->iobase + AM9513A_COM_REG);
- outw(base_clock, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
- outw(0x2, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF42, dev->iobase + AM9513A_COM_REG);
- outw(0xFFF2, dev->iobase + AM9513A_COM_REG);
- outw(timer, dev->iobase + AM9513A_DATA_REG);
- outw(0xFF22, dev->iobase + AM9513A_COM_REG);
- }
-
- /* Clear the A/D FIFO and reset the MUX counter */
- outw(0, dev->iobase + AD_CLEAR_REG);
- outw(0, dev->iobase + MUX_CNTR_REG);
- outw(0, dev->iobase + INT2CLR_REG);
- /* enable this acquisition operation */
- devpriv->com_reg_1_state |= COMREG1_DAQEN;
- outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
- /* enable interrupts for conversion completion */
- devpriv->com_reg_1_state |= COMREG1_CONVINTEN;
- devpriv->com_reg_2_state |= COMREG2_INTEN;
- outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
- outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
- /* apply a trigger. this starts the counters! */
- outw(0, dev->iobase + START_DAQ_REG);
-
- return 0;
-}
-
-/* This will cancel a running acquisition operation */
-static int atmio16d_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- reset_atmio16d(dev);
-
- return 0;
-}
-
-static int atmio16d_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + STAT_REG);
- if (status & STAT_AD_CONVAVAIL)
- return 0;
- if (status & STAT_AD_OVERFLOW) {
- outw(0, dev->iobase + AD_CLEAR_REG);
- return -EOVERFLOW;
- }
- return -EBUSY;
-}
-
-static int atmio16d_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct atmio16d_private *devpriv = dev->private;
- int i;
- int chan;
- int gain;
- int ret;
-
- chan = CR_CHAN(insn->chanspec);
- gain = CR_RANGE(insn->chanspec);
-
- /* reset the Analog input circuitry */
- /* outw( 0, dev->iobase+AD_CLEAR_REG ); */
- /* reset the Analog Input MUX Counter to 0 */
- /* outw( 0, dev->iobase+MUX_CNTR_REG ); */
-
- /* set the Input MUX gain */
- outw(chan | (gain << 6), dev->iobase + MUX_GAIN_REG);
-
- for (i = 0; i < insn->n; i++) {
- /* start the conversion */
- outw(0, dev->iobase + START_CONVERT_REG);
-
- /* wait for it to finish */
- ret = comedi_timeout(dev, s, insn, atmio16d_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* read the data now */
- data[i] = inw(dev->iobase + AD_FIFO_REG);
- /* change to two's complement if need be */
- if (devpriv->adc_coding == adc_2comp)
- data[i] ^= 0x800;
- }
-
- return i;
-}
-
-static int atmio16d_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct atmio16d_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int reg = (chan) ? DAC1_REG : DAC0_REG;
- bool munge = false;
- int i;
-
- if (chan == 0 && devpriv->dac0_coding == dac_2comp)
- munge = true;
- if (chan == 1 && devpriv->dac1_coding == dac_2comp)
- munge = true;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- if (munge)
- val ^= 0x800;
-
- outw(val, dev->iobase + reg);
- }
-
- return insn->n;
-}
-
-static int atmio16d_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + MIO_16_DIG_OUT_REG);
-
- data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG);
-
- return insn->n;
-}
-
-static int atmio16d_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct atmio16d_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 4)
- mask = 0x0f;
- else
- mask = 0xf0;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- devpriv->com_reg_2_state &= ~(COMREG2_DOUTEN0 | COMREG2_DOUTEN1);
- if (s->io_bits & 0x0f)
- devpriv->com_reg_2_state |= COMREG2_DOUTEN0;
- if (s->io_bits & 0xf0)
- devpriv->com_reg_2_state |= COMREG2_DOUTEN1;
- outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
-
- return insn->n;
-}
-
-static int atmio16d_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct atmio16_board_t *board = dev->board_ptr;
- struct atmio16d_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x20);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- /* reset the atmio16d hardware */
- reset_atmio16d(dev);
-
- if (it->options[1]) {
- ret = request_irq(it->options[1], atmio16d_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- /* set device options */
- devpriv->adc_mux = it->options[5];
- devpriv->adc_range = it->options[6];
-
- devpriv->dac0_range = it->options[7];
- devpriv->dac0_reference = it->options[8];
- devpriv->dac0_coding = it->options[9];
- devpriv->dac1_range = it->options[10];
- devpriv->dac1_reference = it->options[11];
- devpriv->dac1_coding = it->options[12];
-
- /* setup sub-devices */
- s = &dev->subdevices[0];
- /* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = (devpriv->adc_mux ? 16 : 8);
- s->insn_read = atmio16d_ai_insn_read;
- s->maxdata = 0xfff; /* 4095 decimal */
- switch (devpriv->adc_range) {
- case adc_bipolar10:
- s->range_table = &range_atmio16d_ai_10_bipolar;
- break;
- case adc_bipolar5:
- s->range_table = &range_atmio16d_ai_5_bipolar;
- break;
- case adc_unipolar10:
- s->range_table = &range_atmio16d_ai_unipolar;
- break;
- }
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 16;
- s->do_cmdtest = atmio16d_ai_cmdtest;
- s->do_cmd = atmio16d_ai_cmd;
- s->cancel = atmio16d_ai_cancel;
- }
-
- /* ao subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0xfff; /* 4095 decimal */
- s->range_table_list = devpriv->ao_range_type_list;
- switch (devpriv->dac0_range) {
- case dac_bipolar:
- devpriv->ao_range_type_list[0] = &range_bipolar10;
- break;
- case dac_unipolar:
- devpriv->ao_range_type_list[0] = &range_unipolar10;
- break;
- }
- switch (devpriv->dac1_range) {
- case dac_bipolar:
- devpriv->ao_range_type_list[1] = &range_bipolar10;
- break;
- case dac_unipolar:
- devpriv->ao_range_type_list[1] = &range_unipolar10;
- break;
- }
- s->insn_write = atmio16d_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital I/O */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 8;
- s->insn_bits = atmio16d_dio_insn_bits;
- s->insn_config = atmio16d_dio_insn_config;
- s->maxdata = 1;
- s->range_table = &range_digital;
-
- /* 8255 subdevice */
- s = &dev->subdevices[3];
- if (board->has_8255) {
- ret = subdev_8255_init(dev, s, NULL, 0x00);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
-/* don't yet know how to deal with counter/timers */
-#if 0
- s = &dev->subdevices[4];
- /* do */
- s->type = COMEDI_SUBD_TIMER;
- s->n_chan = 0;
- s->maxdata = 0
-#endif
-
- return 0;
-}
-
-static void atmio16d_detach(struct comedi_device *dev)
-{
- reset_atmio16d(dev);
- comedi_legacy_detach(dev);
-}
-
-static const struct atmio16_board_t atmio16_boards[] = {
- {
- .name = "atmio16",
- .has_8255 = 0,
- }, {
- .name = "atmio16d",
- .has_8255 = 1,
- },
-};
-
-static struct comedi_driver atmio16d_driver = {
- .driver_name = "atmio16",
- .module = THIS_MODULE,
- .attach = atmio16d_attach,
- .detach = atmio16d_detach,
- .board_name = &atmio16_boards[0].name,
- .num_names = ARRAY_SIZE(atmio16_boards),
- .offset = sizeof(struct atmio16_board_t),
-};
-module_comedi_driver(atmio16d_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
deleted file mode 100644
index d40fc89f9cef..000000000000
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ /dev/null
@@ -1,280 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/ni_daq_700.c
- * Driver for DAQCard-700 DIO/AI
- * copied from 8255
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_daq_700
- * Description: National Instruments PCMCIA DAQCard-700
- * Author: Fred Brooks <nsaspook@nsaspook.com>,
- * based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
- * Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
- * Status: works
- * Updated: Wed, 21 May 2014 12:07:20 +0000
- *
- * The daqcard-700 appears in Comedi as a digital I/O subdevice (0) with
- * 16 channels and a analog input subdevice (1) with 16 single-ended channels
- * or 8 differential channels, and three input ranges.
- *
- * Digital: The channel 0 corresponds to the daqcard-700's output
- * port, bit 0; channel 8 corresponds to the input port, bit 0.
- *
- * Digital direction configuration: channels 0-7 output, 8-15 input.
- *
- * Analog: The input range is 0 to 4095 with a default of -10 to +10 volts.
- * Valid ranges:
- * 0 for -10 to 10V bipolar
- * 1 for -5 to 5V bipolar
- * 2 for -2.5 to 2.5V bipolar
- *
- * IRQ is assigned but not used.
- *
- * Manuals: Register level: https://www.ni.com/pdf/manuals/340698.pdf
- * User Manual: https://www.ni.com/pdf/manuals/320676d.pdf
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pcmcia.h"
-
-/* daqcard700 registers */
-#define DIO_W 0x04 /* WO 8bit */
-#define DIO_R 0x05 /* RO 8bit */
-#define CMD_R1 0x00 /* WO 8bit */
-#define CMD_R2 0x07 /* RW 8bit */
-#define CMD_R3 0x05 /* W0 8bit */
-#define STA_R1 0x00 /* RO 8bit */
-#define STA_R2 0x01 /* RO 8bit */
-#define ADFIFO_R 0x02 /* RO 16bit */
-#define ADCLEAR_R 0x01 /* WO 8bit */
-#define CDA_R0 0x08 /* RW 8bit */
-#define CDA_R1 0x09 /* RW 8bit */
-#define CDA_R2 0x0A /* RW 8bit */
-#define CMO_R 0x0B /* RO 8bit */
-#define TIC_R 0x06 /* WO 8bit */
-/* daqcard700 modes */
-#define CMD_R3_DIFF 0x04 /* diff mode */
-
-static const struct comedi_lrange range_daq700_ai = {
- 3,
- {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5)
- }
-};
-
-static int daq700_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0xff)
- outb(s->state & 0xff, dev->iobase + DIO_W);
- }
-
- val = s->state & 0xff;
- val |= inb(dev->iobase + DIO_R) << 8;
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int daq700_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- /* The DIO channels are not configurable, fix the io_bits */
- s->io_bits = 0x00ff;
-
- return insn->n;
-}
-
-static int daq700_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + STA_R2);
- if ((status & 0x03))
- return -EOVERFLOW;
- status = inb(dev->iobase + STA_R1);
- if ((status & 0x02))
- return -ENODATA;
- if ((status & 0x11) == 0x01)
- return 0;
- return -EBUSY;
-}
-
-static int daq700_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int n;
- int d;
- int ret;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int r3_bits = 0;
-
- /* set channel input modes */
- if (aref == AREF_DIFF)
- r3_bits |= CMD_R3_DIFF;
- /* write channel mode/range */
- if (range >= 1)
- range++; /* convert range to hardware value */
- outb(r3_bits | (range & 0x03), dev->iobase + CMD_R3);
-
- /* write channel to multiplexer */
- /* set mask scan bit high to disable scanning */
- outb(chan | 0x80, dev->iobase + CMD_R1);
- /* mux needs 2us to really settle [Fred Brooks]. */
- udelay(2);
-
- /* convert n samples */
- for (n = 0; n < insn->n; n++) {
- /* trigger conversion with out0 L to H */
- outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */
- outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */
- outb(0x00, dev->iobase + ADCLEAR_R); /* clear the ADC FIFO */
- /* read 16bit junk from FIFO to clear */
- inw(dev->iobase + ADFIFO_R);
- /* mode 1 out0 H, L to H, start conversion */
- outb(0x32, dev->iobase + CMO_R);
-
- /* wait for conversion to end */
- ret = comedi_timeout(dev, s, insn, daq700_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* read data */
- d = inw(dev->iobase + ADFIFO_R);
- /* mangle the data as necessary */
- /* Bipolar Offset Binary: 0 to 4095 for -10 to +10 */
- d &= 0x0fff;
- d ^= 0x0800;
- data[n] = d;
- }
- return n;
-}
-
-/*
- * Data acquisition is enabled.
- * The counter 0 output is high.
- * The I/O connector pin CLK1 drives counter 1 source.
- * Multiple-channel scanning is disabled.
- * All interrupts are disabled.
- * The analog input range is set to +-10 V
- * The analog input mode is single-ended.
- * The analog input circuitry is initialized to channel 0.
- * The A/D FIFO is cleared.
- */
-static void daq700_ai_config(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned long iobase = dev->iobase;
-
- outb(0x80, iobase + CMD_R1); /* disable scanning, ADC to chan 0 */
- outb(0x00, iobase + CMD_R2); /* clear all bits */
- outb(0x00, iobase + CMD_R3); /* set +-10 range */
- outb(0x32, iobase + CMO_R); /* config counter mode1, out0 to H */
- outb(0x00, iobase + TIC_R); /* clear counter interrupt */
- outb(0x00, iobase + ADCLEAR_R); /* clear the ADC FIFO */
- inw(iobase + ADFIFO_R); /* read 16bit junk from FIFO to clear */
-}
-
-static int daq700_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- link->config_flags |= CONF_AUTO_SET_IO;
- ret = comedi_pcmcia_enable(dev, NULL);
- if (ret)
- return ret;
- dev->iobase = link->resource[0]->start;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- /* DAQCard-700 dio */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 16;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = daq700_dio_insn_bits;
- s->insn_config = daq700_dio_insn_config;
- s->io_bits = 0x00ff;
-
- /* DAQCard-700 ai */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = BIT(12) - 1;
- s->range_table = &range_daq700_ai;
- s->insn_read = daq700_ai_rinsn;
- daq700_ai_config(dev, s);
-
- return 0;
-}
-
-static struct comedi_driver daq700_driver = {
- .driver_name = "ni_daq_700",
- .module = THIS_MODULE,
- .auto_attach = daq700_auto_attach,
- .detach = comedi_pcmcia_disable,
-};
-
-static int daq700_cs_attach(struct pcmcia_device *link)
-{
- return comedi_pcmcia_auto_config(link, &daq700_driver);
-}
-
-static const struct pcmcia_device_id daq700_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, daq700_cs_ids);
-
-static struct pcmcia_driver daq700_cs_driver = {
- .name = "ni_daq_700",
- .owner = THIS_MODULE,
- .id_table = daq700_cs_ids,
- .probe = daq700_cs_attach,
- .remove = comedi_pcmcia_auto_unconfig,
-};
-module_comedi_pcmcia_driver(daq700_driver, daq700_cs_driver);
-
-MODULE_AUTHOR("Fred Brooks <nsaspook@nsaspook.com>");
-MODULE_DESCRIPTION(
- "Comedi driver for National Instruments PCMCIA DAQCard-700 DIO/AI");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
deleted file mode 100644
index 44fb65afc218..000000000000
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for National Instruments PCMCIA DAQ-Card DIO-24
- * Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
- *
- * PCMCIA crap at end of file is adapted from dummy_cs.c 1.31
- * 2001/08/24 12:13:13 from the pcmcia package.
- * The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
- */
-
-/*
- * Driver: ni_daq_dio24
- * Description: National Instruments PCMCIA DAQ-Card DIO-24
- * Author: Daniel Vecino Castel <dvecino@able.es>
- * Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
- * Status: ?
- * Updated: Thu, 07 Nov 2002 21:53:06 -0800
- *
- * This is just a wrapper around the 8255.o driver to properly handle
- * the PCMCIA interface.
- */
-
-#include <linux/module.h>
-#include "../comedi_pcmcia.h"
-
-#include "8255.h"
-
-static int dio24_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- struct comedi_subdevice *s;
- int ret;
-
- link->config_flags |= CONF_AUTO_SET_IO;
- ret = comedi_pcmcia_enable(dev, NULL);
- if (ret)
- return ret;
- dev->iobase = link->resource[0]->start;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* 8255 dio */
- s = &dev->subdevices[0];
- return subdev_8255_init(dev, s, NULL, 0x00);
-}
-
-static struct comedi_driver driver_dio24 = {
- .driver_name = "ni_daq_dio24",
- .module = THIS_MODULE,
- .auto_attach = dio24_auto_attach,
- .detach = comedi_pcmcia_disable,
-};
-
-static int dio24_cs_attach(struct pcmcia_device *link)
-{
- return comedi_pcmcia_auto_config(link, &driver_dio24);
-}
-
-static const struct pcmcia_device_id dio24_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c), /* daqcard-dio24 */
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
-
-static struct pcmcia_driver dio24_cs_driver = {
- .name = "ni_daq_dio24",
- .owner = THIS_MODULE,
- .id_table = dio24_cs_ids,
- .probe = dio24_cs_attach,
- .remove = comedi_pcmcia_auto_unconfig,
-};
-module_comedi_pcmcia_driver(driver_dio24, dio24_cs_driver);
-
-MODULE_AUTHOR("Daniel Vecino Castel <dvecino@able.es>");
-MODULE_DESCRIPTION(
- "Comedi driver for National Instruments PCMCIA DAQ-Card DIO-24");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
deleted file mode 100644
index 1f4a07bd1d26..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ /dev/null
@@ -1,116 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/ni_labpc.c
- * Driver for National Instruments Lab-PC series boards and compatibles
- * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-/*
- * Driver: ni_labpc
- * Description: National Instruments Lab-PC (& compatibles)
- * Devices: [National Instruments] Lab-PC-1200 (lab-pc-1200),
- * Lab-PC-1200AI (lab-pc-1200ai), Lab-PC+ (lab-pc+)
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Status: works
- *
- * Configuration options - ISA boards:
- * [0] - I/O port base address
- * [1] - IRQ (optional, required for timed or externally triggered
- * conversions)
- * [2] - DMA channel (optional)
- *
- * Tested with lab-pc-1200. For the older Lab-PC+, not all input
- * ranges and analog references will work, the available ranges/arefs
- * will depend on how you have configured the jumpers on your board
- * (see your owner's manual).
- *
- * Kernel-level ISA plug-and-play support for the lab-pc-1200 boards
- * has not yet been added to the driver, mainly due to the fact that
- * I don't know the device id numbers. If you have one of these boards,
- * please file a bug report at https://comedi.org/ so I can get the
- * necessary information from you.
- *
- * The 1200 series boards have onboard calibration dacs for correcting
- * analog input/output offsets and gains. The proper settings for these
- * caldacs are stored on the board's eeprom. To read the caldac values
- * from the eeprom and store them into a file that can be then be used
- * by comedilib, use the comedi_calibrate program.
- *
- * The Lab-pc+ has quirky chanlist requirements when scanning multiple
- * channels. Multiple channel scan sequence must start at highest channel,
- * then decrement down to channel 0. The rest of the cards can scan down
- * like lab-pc+ or scan up from channel zero. Chanlists consisting of all
- * one channel are also legal, and allow you to pace conversions in bursts.
- *
- * NI manuals:
- * 341309a (labpc-1200 register manual)
- * 320502b (lab-pc+)
- */
-
-#include <linux/module.h>
-
-#include "../comedidev.h"
-
-#include "ni_labpc.h"
-#include "ni_labpc_isadma.h"
-
-static const struct labpc_boardinfo labpc_boards[] = {
- {
- .name = "lab-pc-1200",
- .ai_speed = 10000,
- .ai_scan_up = 1,
- .has_ao = 1,
- .is_labpc1200 = 1,
- }, {
- .name = "lab-pc-1200ai",
- .ai_speed = 10000,
- .ai_scan_up = 1,
- .is_labpc1200 = 1,
- }, {
- .name = "lab-pc+",
- .ai_speed = 12000,
- .has_ao = 1,
- },
-};
-
-static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- unsigned int irq = it->options[1];
- unsigned int dma_chan = it->options[2];
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x20);
- if (ret)
- return ret;
-
- ret = labpc_common_attach(dev, irq, 0);
- if (ret)
- return ret;
-
- if (dev->irq)
- labpc_init_dma_chan(dev, dma_chan);
-
- return 0;
-}
-
-static void labpc_detach(struct comedi_device *dev)
-{
- labpc_free_dma_chan(dev);
- labpc_common_detach(dev);
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver labpc_driver = {
- .driver_name = "ni_labpc",
- .module = THIS_MODULE,
- .attach = labpc_attach,
- .detach = labpc_detach,
- .num_names = ARRAY_SIZE(labpc_boards),
- .board_name = &labpc_boards[0].name,
- .offset = sizeof(struct labpc_boardinfo),
-};
-module_comedi_driver(labpc_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for NI Lab-PC ISA boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
deleted file mode 100644
index 728e901f53cd..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Header for ni_labpc ISA/PCMCIA/PCI drivers
- *
- * Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-#ifndef _NI_LABPC_H
-#define _NI_LABPC_H
-
-enum transfer_type { fifo_not_empty_transfer, fifo_half_full_transfer,
- isa_dma_transfer
-};
-
-struct labpc_boardinfo {
- const char *name;
- int ai_speed; /* maximum input speed in ns */
- unsigned ai_scan_up:1; /* can auto scan up in ai channels */
- unsigned has_ao:1; /* has analog outputs */
- unsigned is_labpc1200:1; /* has extra regs compared to pc+ */
-};
-
-struct labpc_private {
- struct comedi_isadma *dma;
- struct comedi_8254 *counter;
-
- /* number of data points left to be taken */
- unsigned long long count;
- /* software copys of bits written to command registers */
- unsigned int cmd1;
- unsigned int cmd2;
- unsigned int cmd3;
- unsigned int cmd4;
- unsigned int cmd5;
- unsigned int cmd6;
- /* store last read of board status registers */
- unsigned int stat1;
- unsigned int stat2;
-
- /* we are using dma/fifo-half-full/etc. */
- enum transfer_type current_transfer;
- /*
- * function pointers so we can use inb/outb or readb/writeb as
- * appropriate
- */
- unsigned int (*read_byte)(struct comedi_device *dev, unsigned long reg);
- void (*write_byte)(struct comedi_device *dev,
- unsigned int byte, unsigned long reg);
-};
-
-int labpc_common_attach(struct comedi_device *dev,
- unsigned int irq, unsigned long isr_flags);
-void labpc_common_detach(struct comedi_device *dev);
-
-#endif /* _NI_LABPC_H */
diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c
deleted file mode 100644
index dd97946eacaf..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc_common.c
+++ /dev/null
@@ -1,1363 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/ni_labpc_common.c
- *
- * Common support code for "ni_labpc", "ni_labpc_pci" and "ni_labpc_cs".
- *
- * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include "../comedidev.h"
-
-#include "comedi_8254.h"
-#include "8255.h"
-#include "ni_labpc.h"
-#include "ni_labpc_regs.h"
-#include "ni_labpc_isadma.h"
-
-enum scan_mode {
- MODE_SINGLE_CHAN,
- MODE_SINGLE_CHAN_INTERVAL,
- MODE_MULT_CHAN_UP,
- MODE_MULT_CHAN_DOWN,
-};
-
-static const struct comedi_lrange range_labpc_plus_ai = {
- 16, {
- BIP_RANGE(5),
- BIP_RANGE(4),
- BIP_RANGE(2.5),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.25),
- BIP_RANGE(0.1),
- BIP_RANGE(0.05),
- UNI_RANGE(10),
- UNI_RANGE(8),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5),
- UNI_RANGE(0.2),
- UNI_RANGE(0.1)
- }
-};
-
-static const struct comedi_lrange range_labpc_1200_ai = {
- 14, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.25),
- BIP_RANGE(0.1),
- BIP_RANGE(0.05),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5),
- UNI_RANGE(0.2),
- UNI_RANGE(0.1)
- }
-};
-
-static const struct comedi_lrange range_labpc_ao = {
- 2, {
- BIP_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-/*
- * functions that do inb/outb and readb/writeb so we can use
- * function pointers to decide which to use
- */
-static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg)
-{
- return inb(dev->iobase + reg);
-}
-
-static void labpc_outb(struct comedi_device *dev,
- unsigned int byte, unsigned long reg)
-{
- outb(byte, dev->iobase + reg);
-}
-
-static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg)
-{
- return readb(dev->mmio + reg);
-}
-
-static void labpc_writeb(struct comedi_device *dev,
- unsigned int byte, unsigned long reg)
-{
- writeb(byte, dev->mmio + reg);
-}
-
-static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
- devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- devpriv->cmd3 = 0;
- devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
-
- return 0;
-}
-
-static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
- enum scan_mode mode,
- unsigned int chan,
- unsigned int range,
- unsigned int aref)
-{
- const struct labpc_boardinfo *board = dev->board_ptr;
- struct labpc_private *devpriv = dev->private;
-
- if (board->is_labpc1200) {
- /*
- * The LabPC-1200 boards do not have a gain
- * of '0x10'. Skip the range values that would
- * result in this gain.
- */
- range += (range > 0) + (range > 7);
- }
-
- /* munge channel bits for differential/scan disabled mode */
- if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
- aref == AREF_DIFF)
- chan *= 2;
- devpriv->cmd1 = CMD1_MA(chan);
- devpriv->cmd1 |= CMD1_GAIN(range);
-
- devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
-}
-
-static void labpc_setup_cmd6_reg(struct comedi_device *dev,
- struct comedi_subdevice *s,
- enum scan_mode mode,
- enum transfer_type xfer,
- unsigned int range,
- unsigned int aref,
- bool ena_intr)
-{
- const struct labpc_boardinfo *board = dev->board_ptr;
- struct labpc_private *devpriv = dev->private;
-
- if (!board->is_labpc1200)
- return;
-
- /* reference inputs to ground or common? */
- if (aref != AREF_GROUND)
- devpriv->cmd6 |= CMD6_NRSE;
- else
- devpriv->cmd6 &= ~CMD6_NRSE;
-
- /* bipolar or unipolar range? */
- if (comedi_range_is_unipolar(s, range))
- devpriv->cmd6 |= CMD6_ADCUNI;
- else
- devpriv->cmd6 &= ~CMD6_ADCUNI;
-
- /* interrupt on fifo half full? */
- if (xfer == fifo_half_full_transfer)
- devpriv->cmd6 |= CMD6_HFINTEN;
- else
- devpriv->cmd6 &= ~CMD6_HFINTEN;
-
- /* enable interrupt on counter a1 terminal count? */
- if (ena_intr)
- devpriv->cmd6 |= CMD6_DQINTEN;
- else
- devpriv->cmd6 &= ~CMD6_DQINTEN;
-
- /* are we scanning up or down through channels? */
- if (mode == MODE_MULT_CHAN_UP)
- devpriv->cmd6 |= CMD6_SCANUP;
- else
- devpriv->cmd6 &= ~CMD6_SCANUP;
-
- devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
-}
-
-static unsigned int labpc_read_adc_fifo(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned int lsb = devpriv->read_byte(dev, ADC_FIFO_REG);
- unsigned int msb = devpriv->read_byte(dev, ADC_FIFO_REG);
-
- return (msb << 8) | lsb;
-}
-
-static void labpc_clear_adc_fifo(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
-
- devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
- labpc_read_adc_fifo(dev);
-}
-
-static int labpc_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- struct labpc_private *devpriv = dev->private;
-
- devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
- if (devpriv->stat1 & STAT1_DAVAIL)
- return 0;
- return -EBUSY;
-}
-
-static int labpc_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- int ret;
- int i;
-
- /* disable timed conversions, interrupt generation and dma */
- labpc_cancel(dev, s);
-
- labpc_ai_set_chan_and_gain(dev, MODE_SINGLE_CHAN, chan, range, aref);
-
- labpc_setup_cmd6_reg(dev, s, MODE_SINGLE_CHAN, fifo_not_empty_transfer,
- range, aref, false);
-
- /* setup cmd4 register */
- devpriv->cmd4 = 0;
- devpriv->cmd4 |= CMD4_ECLKRCV;
- /* single-ended/differential */
- if (aref == AREF_DIFF)
- devpriv->cmd4 |= CMD4_SEDIFF;
- devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
-
- /* initialize pacer counter to prevent any problems */
- comedi_8254_set_mode(devpriv->counter, 0, I8254_MODE2 | I8254_BINARY);
-
- labpc_clear_adc_fifo(dev);
-
- for (i = 0; i < insn->n; i++) {
- /* trigger conversion */
- devpriv->write_byte(dev, 0x1, ADC_START_CONVERT_REG);
-
- ret = comedi_timeout(dev, s, insn, labpc_ai_eoc, 0);
- if (ret)
- return ret;
-
- data[i] = labpc_read_adc_fifo(dev);
- }
-
- return insn->n;
-}
-
-static bool labpc_use_continuous_mode(const struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- if (mode == MODE_SINGLE_CHAN || cmd->scan_begin_src == TRIG_FOLLOW)
- return true;
-
- return false;
-}
-
-static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- if (cmd->convert_src != TRIG_TIMER)
- return 0;
-
- if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
- return cmd->scan_begin_arg;
-
- return cmd->convert_arg;
-}
-
-static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
- enum scan_mode mode, unsigned int ns)
-{
- if (cmd->convert_src != TRIG_TIMER)
- return;
-
- if (mode == MODE_SINGLE_CHAN &&
- cmd->scan_begin_src == TRIG_TIMER) {
- cmd->scan_begin_arg = ns;
- if (cmd->convert_arg > cmd->scan_begin_arg)
- cmd->convert_arg = cmd->scan_begin_arg;
- } else {
- cmd->convert_arg = ns;
- }
-}
-
-static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- if (cmd->scan_begin_src != TRIG_TIMER)
- return 0;
-
- if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
- return 0;
-
- return cmd->scan_begin_arg;
-}
-
-static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
- enum scan_mode mode, unsigned int ns)
-{
- if (cmd->scan_begin_src != TRIG_TIMER)
- return;
-
- if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
- return;
-
- cmd->scan_begin_arg = ns;
-}
-
-/* figures out what counter values to use based on command */
-static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- struct comedi_8254 *pacer = dev->pacer;
- unsigned int convert_period = labpc_ai_convert_period(cmd, mode);
- unsigned int scan_period = labpc_ai_scan_period(cmd, mode);
- unsigned int base_period;
-
- /*
- * If both convert and scan triggers are TRIG_TIMER, then they
- * both rely on counter b0. If only one TRIG_TIMER is used, we
- * can use the generic cascaded timing functions.
- */
- if (convert_period && scan_period) {
- /*
- * pick the lowest divisor value we can (for maximum input
- * clock speed on convert and scan counters)
- */
- pacer->next_div1 = (scan_period - 1) /
- (pacer->osc_base * I8254_MAX_COUNT) + 1;
-
- comedi_check_trigger_arg_min(&pacer->next_div1, 2);
- comedi_check_trigger_arg_max(&pacer->next_div1,
- I8254_MAX_COUNT);
-
- base_period = pacer->osc_base * pacer->next_div1;
-
- /* set a0 for conversion frequency and b1 for scan frequency */
- switch (cmd->flags & CMDF_ROUND_MASK) {
- default:
- case CMDF_ROUND_NEAREST:
- pacer->next_div = DIV_ROUND_CLOSEST(convert_period,
- base_period);
- pacer->next_div2 = DIV_ROUND_CLOSEST(scan_period,
- base_period);
- break;
- case CMDF_ROUND_UP:
- pacer->next_div = DIV_ROUND_UP(convert_period,
- base_period);
- pacer->next_div2 = DIV_ROUND_UP(scan_period,
- base_period);
- break;
- case CMDF_ROUND_DOWN:
- pacer->next_div = convert_period / base_period;
- pacer->next_div2 = scan_period / base_period;
- break;
- }
- /* make sure a0 and b1 values are acceptable */
- comedi_check_trigger_arg_min(&pacer->next_div, 2);
- comedi_check_trigger_arg_max(&pacer->next_div, I8254_MAX_COUNT);
- comedi_check_trigger_arg_min(&pacer->next_div2, 2);
- comedi_check_trigger_arg_max(&pacer->next_div2,
- I8254_MAX_COUNT);
-
- /* write corrected timings to command */
- labpc_set_ai_convert_period(cmd, mode,
- base_period * pacer->next_div);
- labpc_set_ai_scan_period(cmd, mode,
- base_period * pacer->next_div2);
- } else if (scan_period) {
- /*
- * calculate cascaded counter values
- * that give desired scan timing
- * (pacer->next_div2 / pacer->next_div1)
- */
- comedi_8254_cascade_ns_to_timer(pacer, &scan_period,
- cmd->flags);
- labpc_set_ai_scan_period(cmd, mode, scan_period);
- } else if (convert_period) {
- /*
- * calculate cascaded counter values
- * that give desired conversion timing
- * (pacer->next_div / pacer->next_div1)
- */
- comedi_8254_cascade_ns_to_timer(pacer, &convert_period,
- cmd->flags);
- /* transfer div2 value so correct timer gets updated */
- pacer->next_div = pacer->next_div2;
- labpc_set_ai_convert_period(cmd, mode, convert_period);
- }
-}
-
-static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
-{
- unsigned int chan0;
- unsigned int chan1;
-
- if (cmd->chanlist_len == 1)
- return MODE_SINGLE_CHAN;
-
- /* chanlist may be NULL during cmdtest */
- if (!cmd->chanlist)
- return MODE_MULT_CHAN_UP;
-
- chan0 = CR_CHAN(cmd->chanlist[0]);
- chan1 = CR_CHAN(cmd->chanlist[1]);
-
- if (chan0 < chan1)
- return MODE_MULT_CHAN_UP;
-
- if (chan0 > chan1)
- return MODE_MULT_CHAN_DOWN;
-
- return MODE_SINGLE_CHAN_INTERVAL;
-}
-
-static int labpc_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- enum scan_mode mode = labpc_ai_scan_mode(cmd);
- unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
- unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
- unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
- int i;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
- unsigned int aref = CR_AREF(cmd->chanlist[i]);
-
- switch (mode) {
- case MODE_SINGLE_CHAN:
- break;
- case MODE_SINGLE_CHAN_INTERVAL:
- if (chan != chan0) {
- dev_dbg(dev->class_dev,
- "channel scanning order specified in chanlist is not supported by hardware\n");
- return -EINVAL;
- }
- break;
- case MODE_MULT_CHAN_UP:
- if (chan != i) {
- dev_dbg(dev->class_dev,
- "channel scanning order specified in chanlist is not supported by hardware\n");
- return -EINVAL;
- }
- break;
- case MODE_MULT_CHAN_DOWN:
- if (chan != (cmd->chanlist_len - i - 1)) {
- dev_dbg(dev->class_dev,
- "channel scanning order specified in chanlist is not supported by hardware\n");
- return -EINVAL;
- }
- break;
- }
-
- if (range != range0) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must all have the same range\n");
- return -EINVAL;
- }
-
- if (aref != aref0) {
- dev_dbg(dev->class_dev,
- "entries in chanlist must all have the same reference\n");
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static int labpc_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- const struct labpc_boardinfo *board = dev->board_ptr;
- int err = 0;
- int tmp, tmp2;
- unsigned int stop_mask;
- enum scan_mode mode;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
-
- stop_mask = TRIG_COUNT | TRIG_NONE;
- if (board->is_labpc1200)
- stop_mask |= TRIG_EXT;
- err |= comedi_check_trigger_src(&cmd->stop_src, stop_mask);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- /* can't have external stop and start triggers at once */
- if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
- err++;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- /* start_arg value is ignored */
- break;
- }
-
- if (!cmd->chanlist_len)
- err |= -EINVAL;
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- }
-
- /* make sure scan timing is not too fast */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(
- &cmd->scan_begin_arg,
- cmd->convert_arg * cmd->chanlist_len);
- }
- err |= comedi_check_trigger_arg_min(
- &cmd->scan_begin_arg,
- board->ai_speed * cmd->chanlist_len);
- }
-
- switch (cmd->stop_src) {
- case TRIG_COUNT:
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- break;
- case TRIG_NONE:
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
- break;
- /*
- * TRIG_EXT doesn't care since it doesn't
- * trigger off a numbered channel
- */
- default:
- break;
- }
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- tmp = cmd->convert_arg;
- tmp2 = cmd->scan_begin_arg;
- mode = labpc_ai_scan_mode(cmd);
- labpc_adc_timing(dev, cmd, mode);
- if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
- err++;
-
- if (err)
- return 4;
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= labpc_ai_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- const struct labpc_boardinfo *board = dev->board_ptr;
- struct labpc_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- enum scan_mode mode = labpc_ai_scan_mode(cmd);
- unsigned int chanspec = (mode == MODE_MULT_CHAN_UP) ?
- cmd->chanlist[cmd->chanlist_len - 1] :
- cmd->chanlist[0];
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
- enum transfer_type xfer;
- unsigned long flags;
-
- /* make sure board is disabled before setting up acquisition */
- labpc_cancel(dev, s);
-
- /* initialize software conversion count */
- if (cmd->stop_src == TRIG_COUNT)
- devpriv->count = cmd->stop_arg * cmd->chanlist_len;
-
- /* setup hardware conversion counter */
- if (cmd->stop_src == TRIG_EXT) {
- /*
- * load counter a1 with count of 3
- * (pc+ manual says this is minimum allowed) using mode 0
- */
- comedi_8254_load(devpriv->counter, 1,
- 3, I8254_MODE0 | I8254_BINARY);
- } else {
- /* just put counter a1 in mode 0 to set its output low */
- comedi_8254_set_mode(devpriv->counter, 1,
- I8254_MODE0 | I8254_BINARY);
- }
-
- /* figure out what method we will use to transfer data */
- if (devpriv->dma &&
- (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) {
- /*
- * dma unsafe at RT priority,
- * and too much setup time for CMDF_WAKE_EOS
- */
- xfer = isa_dma_transfer;
- } else if (board->is_labpc1200 &&
- (cmd->flags & CMDF_WAKE_EOS) == 0 &&
- (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
- /*
- * pc-plus has no fifo-half full interrupt
- * wake-end-of-scan should interrupt on fifo not empty
- * make sure we are taking more than just a few points
- */
- xfer = fifo_half_full_transfer;
- } else {
- xfer = fifo_not_empty_transfer;
- }
- devpriv->current_transfer = xfer;
-
- labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref);
-
- labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref,
- (cmd->stop_src == TRIG_EXT));
-
- /* manual says to set scan enable bit on second pass */
- if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
- devpriv->cmd1 |= CMD1_SCANEN;
- /*
- * Need a brief delay before enabling scan, or scan
- * list will get screwed when you switch between
- * scan up to scan down mode - dunno why.
- */
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
- }
-
- devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG);
- /* load count */
- devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG);
-
- if (cmd->convert_src == TRIG_TIMER ||
- cmd->scan_begin_src == TRIG_TIMER) {
- struct comedi_8254 *pacer = dev->pacer;
- struct comedi_8254 *counter = devpriv->counter;
-
- comedi_8254_update_divisors(pacer);
-
- /* set up pacing */
- comedi_8254_load(pacer, 0, pacer->divisor1,
- I8254_MODE3 | I8254_BINARY);
-
- /* set up conversion pacing */
- comedi_8254_set_mode(counter, 0, I8254_MODE2 | I8254_BINARY);
- if (labpc_ai_convert_period(cmd, mode))
- comedi_8254_write(counter, 0, pacer->divisor);
-
- /* set up scan pacing */
- if (labpc_ai_scan_period(cmd, mode))
- comedi_8254_load(pacer, 1, pacer->divisor2,
- I8254_MODE2 | I8254_BINARY);
- }
-
- labpc_clear_adc_fifo(dev);
-
- if (xfer == isa_dma_transfer)
- labpc_setup_dma(dev, s);
-
- /* enable error interrupts */
- devpriv->cmd3 |= CMD3_ERRINTEN;
- /* enable fifo not empty interrupt? */
- if (xfer == fifo_not_empty_transfer)
- devpriv->cmd3 |= CMD3_FIFOINTEN;
- devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
-
- /* setup any external triggering/pacing (cmd4 register) */
- devpriv->cmd4 = 0;
- if (cmd->convert_src != TRIG_EXT)
- devpriv->cmd4 |= CMD4_ECLKRCV;
- /*
- * XXX should discard first scan when using interval scanning
- * since manual says it is not synced with scan clock.
- */
- if (!labpc_use_continuous_mode(cmd, mode)) {
- devpriv->cmd4 |= CMD4_INTSCAN;
- if (cmd->scan_begin_src == TRIG_EXT)
- devpriv->cmd4 |= CMD4_EOIRCV;
- }
- /* single-ended/differential */
- if (aref == AREF_DIFF)
- devpriv->cmd4 |= CMD4_SEDIFF;
- devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
-
- /* startup acquisition */
-
- spin_lock_irqsave(&dev->spinlock, flags);
-
- /* use 2 cascaded counters for pacing */
- devpriv->cmd2 |= CMD2_TBSEL;
-
- devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
- if (cmd->start_src == TRIG_EXT)
- devpriv->cmd2 |= CMD2_HWTRIG;
- else
- devpriv->cmd2 |= CMD2_SWTRIG;
- if (cmd->stop_src == TRIG_EXT)
- devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
-
- devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return 0;
-}
-
-/* read all available samples from ai fifo */
-static int labpc_drain_fifo(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- struct comedi_async *async = dev->read_subdev->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned short data;
- const int timeout = 10000;
- unsigned int i;
-
- devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
-
- for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
- i++) {
- /* quit if we have all the data we want */
- if (cmd->stop_src == TRIG_COUNT) {
- if (devpriv->count == 0)
- break;
- devpriv->count--;
- }
- data = labpc_read_adc_fifo(dev);
- comedi_buf_write_samples(dev->read_subdev, &data, 1);
- devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
- }
- if (i == timeout) {
- dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
- async->events |= COMEDI_CB_ERROR;
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Makes sure all data acquired by board is transferred to comedi (used
- * when acquisition is terminated by stop_src == TRIG_EXT).
- */
-static void labpc_drain_dregs(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
-
- if (devpriv->current_transfer == isa_dma_transfer)
- labpc_drain_dma(dev);
-
- labpc_drain_fifo(dev);
-}
-
-/* interrupt service routine */
-static irqreturn_t labpc_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- const struct labpc_boardinfo *board = dev->board_ptr;
- struct labpc_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async;
- struct comedi_cmd *cmd;
-
- if (!dev->attached) {
- dev_err(dev->class_dev, "premature interrupt\n");
- return IRQ_HANDLED;
- }
-
- async = s->async;
- cmd = &async->cmd;
-
- /* read board status */
- devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
- if (board->is_labpc1200)
- devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
-
- if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
- STAT1_OVERRUN | STAT1_DAVAIL)) == 0 &&
- (devpriv->stat2 & STAT2_OUTA1) == 0 &&
- (devpriv->stat2 & STAT2_FIFONHF)) {
- return IRQ_NONE;
- }
-
- if (devpriv->stat1 & STAT1_OVERRUN) {
- /* clear error interrupt */
- devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
- async->events |= COMEDI_CB_ERROR;
- comedi_handle_events(dev, s);
- dev_err(dev->class_dev, "overrun\n");
- return IRQ_HANDLED;
- }
-
- if (devpriv->current_transfer == isa_dma_transfer)
- labpc_handle_dma_status(dev);
- else
- labpc_drain_fifo(dev);
-
- if (devpriv->stat1 & STAT1_CNTINT) {
- dev_err(dev->class_dev, "handled timer interrupt?\n");
- /* clear it */
- devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG);
- }
-
- if (devpriv->stat1 & STAT1_OVERFLOW) {
- /* clear error interrupt */
- devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
- async->events |= COMEDI_CB_ERROR;
- comedi_handle_events(dev, s);
- dev_err(dev->class_dev, "overflow\n");
- return IRQ_HANDLED;
- }
- /* handle external stop trigger */
- if (cmd->stop_src == TRIG_EXT) {
- if (devpriv->stat2 & STAT2_OUTA1) {
- labpc_drain_dregs(dev);
- async->events |= COMEDI_CB_EOA;
- }
- }
-
- /* TRIG_COUNT end of acquisition */
- if (cmd->stop_src == TRIG_COUNT) {
- if (devpriv->count == 0)
- async->events |= COMEDI_CB_EOA;
- }
-
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static void labpc_ao_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chan, unsigned int val)
-{
- struct labpc_private *devpriv = dev->private;
-
- devpriv->write_byte(dev, val & 0xff, DAC_LSB_REG(chan));
- devpriv->write_byte(dev, (val >> 8) & 0xff, DAC_MSB_REG(chan));
-
- s->readback[chan] = val;
-}
-
-static int labpc_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct labpc_boardinfo *board = dev->board_ptr;
- struct labpc_private *devpriv = dev->private;
- unsigned int channel;
- unsigned int range;
- unsigned int i;
- unsigned long flags;
-
- channel = CR_CHAN(insn->chanspec);
-
- /*
- * Turn off pacing of analog output channel.
- * NOTE: hardware bug in daqcard-1200 means pacing cannot
- * be independently enabled/disabled for its the two channels.
- */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->cmd2 &= ~CMD2_LDAC(channel);
- devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- /* set range */
- if (board->is_labpc1200) {
- range = CR_RANGE(insn->chanspec);
- if (comedi_range_is_unipolar(s, range))
- devpriv->cmd6 |= CMD6_DACUNI(channel);
- else
- devpriv->cmd6 &= ~CMD6_DACUNI(channel);
- /* write to register */
- devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
- }
- /* send data */
- for (i = 0; i < insn->n; i++)
- labpc_ao_write(dev, s, channel, data[i]);
-
- return insn->n;
-}
-
-/* lowlevel write to eeprom/dac */
-static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
- unsigned int value_width)
-{
- struct labpc_private *devpriv = dev->private;
- int i;
-
- for (i = 1; i <= value_width; i++) {
- /* clear serial clock */
- devpriv->cmd5 &= ~CMD5_SCLK;
- /* send bits most significant bit first */
- if (value & (1 << (value_width - i)))
- devpriv->cmd5 |= CMD5_SDATA;
- else
- devpriv->cmd5 &= ~CMD5_SDATA;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- /* set clock to load bit */
- devpriv->cmd5 |= CMD5_SCLK;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- }
-}
-
-/* lowlevel read from eeprom */
-static unsigned int labpc_serial_in(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned int value = 0;
- int i;
- const int value_width = 8; /* number of bits wide values are */
-
- for (i = 1; i <= value_width; i++) {
- /* set serial clock */
- devpriv->cmd5 |= CMD5_SCLK;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- /* clear clock bit */
- devpriv->cmd5 &= ~CMD5_SCLK;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- /* read bits most significant bit first */
- udelay(1);
- devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
- if (devpriv->stat2 & STAT2_PROMOUT)
- value |= 1 << (value_width - i);
- }
-
- return value;
-}
-
-static unsigned int labpc_eeprom_read(struct comedi_device *dev,
- unsigned int address)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned int value;
- /* bits to tell eeprom to expect a read */
- const int read_instruction = 0x3;
- /* 8 bit write lengths to eeprom */
- const int write_length = 8;
-
- /* enable read/write to eeprom */
- devpriv->cmd5 &= ~CMD5_EEPROMCS;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- /* send read instruction */
- labpc_serial_out(dev, read_instruction, write_length);
- /* send 8 bit address to read from */
- labpc_serial_out(dev, address, write_length);
- /* read result */
- value = labpc_serial_in(dev);
-
- /* disable read/write to eeprom */
- devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- return value;
-}
-
-static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned int value;
- const int read_status_instruction = 0x5;
- const int write_length = 8; /* 8 bit write lengths to eeprom */
-
- /* enable read/write to eeprom */
- devpriv->cmd5 &= ~CMD5_EEPROMCS;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- /* send read status instruction */
- labpc_serial_out(dev, read_status_instruction, write_length);
- /* read result */
- value = labpc_serial_in(dev);
-
- /* disable read/write to eeprom */
- devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- return value;
-}
-
-static void labpc_eeprom_write(struct comedi_device *dev,
- unsigned int address, unsigned int value)
-{
- struct labpc_private *devpriv = dev->private;
- const int write_enable_instruction = 0x6;
- const int write_instruction = 0x2;
- const int write_length = 8; /* 8 bit write lengths to eeprom */
-
- /* enable read/write to eeprom */
- devpriv->cmd5 &= ~CMD5_EEPROMCS;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- /* send write_enable instruction */
- labpc_serial_out(dev, write_enable_instruction, write_length);
- devpriv->cmd5 &= ~CMD5_EEPROMCS;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- /* send write instruction */
- devpriv->cmd5 |= CMD5_EEPROMCS;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- labpc_serial_out(dev, write_instruction, write_length);
- /* send 8 bit address to write to */
- labpc_serial_out(dev, address, write_length);
- /* write value */
- labpc_serial_out(dev, value, write_length);
- devpriv->cmd5 &= ~CMD5_EEPROMCS;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- /* disable read/write to eeprom */
- devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-}
-
-/* writes to 8 bit calibration dacs */
-static void write_caldac(struct comedi_device *dev, unsigned int channel,
- unsigned int value)
-{
- struct labpc_private *devpriv = dev->private;
-
- /* clear caldac load bit and make sure we don't write to eeprom */
- devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-
- /* write 4 bit channel */
- labpc_serial_out(dev, channel, 4);
- /* write 8 bit caldac value */
- labpc_serial_out(dev, value, 8);
-
- /* set and clear caldac bit to load caldac value */
- devpriv->cmd5 |= CMD5_CALDACLD;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- devpriv->cmd5 &= ~CMD5_CALDACLD;
- udelay(1);
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
-}
-
-static int labpc_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /*
- * Only write the last data value to the caldac. Preceding
- * data would be overwritten anyway.
- */
- if (insn->n > 0) {
- unsigned int val = data[insn->n - 1];
-
- if (s->readback[chan] != val) {
- write_caldac(dev, chan, val);
- s->readback[chan] = val;
- }
- }
-
- return insn->n;
-}
-
-static int labpc_eeprom_ready(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- /* make sure there isn't already a write in progress */
- status = labpc_eeprom_read_status(dev);
- if ((status & 0x1) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int labpc_eeprom_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret;
-
- /* only allow writes to user area of eeprom */
- if (chan < 16 || chan > 127)
- return -EINVAL;
-
- /*
- * Only write the last data value to the eeprom. Preceding
- * data would be overwritten anyway.
- */
- if (insn->n > 0) {
- unsigned int val = data[insn->n - 1];
-
- ret = comedi_timeout(dev, s, insn, labpc_eeprom_ready, 0);
- if (ret)
- return ret;
-
- labpc_eeprom_write(dev, chan, val);
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-int labpc_common_attach(struct comedi_device *dev,
- unsigned int irq, unsigned long isr_flags)
-{
- const struct labpc_boardinfo *board = dev->board_ptr;
- struct labpc_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
- int i;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- if (dev->mmio) {
- devpriv->read_byte = labpc_readb;
- devpriv->write_byte = labpc_writeb;
- } else {
- devpriv->read_byte = labpc_inb;
- devpriv->write_byte = labpc_outb;
- }
-
- /* initialize board's command registers */
- devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
- devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
- devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
- devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
- if (board->is_labpc1200) {
- devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
- devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
- }
-
- if (irq) {
- ret = request_irq(irq, labpc_interrupt, isr_flags,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = irq;
- }
-
- if (dev->mmio) {
- dev->pacer = comedi_8254_mm_init(dev->mmio + COUNTER_B_BASE_REG,
- I8254_OSC_BASE_2MHZ,
- I8254_IO8, 0);
- devpriv->counter = comedi_8254_mm_init(dev->mmio +
- COUNTER_A_BASE_REG,
- I8254_OSC_BASE_2MHZ,
- I8254_IO8, 0);
- } else {
- dev->pacer = comedi_8254_init(dev->iobase + COUNTER_B_BASE_REG,
- I8254_OSC_BASE_2MHZ,
- I8254_IO8, 0);
- devpriv->counter = comedi_8254_init(dev->iobase +
- COUNTER_A_BASE_REG,
- I8254_OSC_BASE_2MHZ,
- I8254_IO8, 0);
- }
- if (!dev->pacer || !devpriv->counter)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 5);
- if (ret)
- return ret;
-
- /* analog input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
- s->n_chan = 8;
- s->len_chanlist = 8;
- s->maxdata = 0x0fff;
- s->range_table = board->is_labpc1200 ?
- &range_labpc_1200_ai : &range_labpc_plus_ai;
- s->insn_read = labpc_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->do_cmd = labpc_ai_cmd;
- s->do_cmdtest = labpc_ai_cmdtest;
- s->cancel = labpc_cancel;
- }
-
- /* analog output */
- s = &dev->subdevices[1];
- if (board->has_ao) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &range_labpc_ao;
- s->insn_write = labpc_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* initialize analog outputs to a known value */
- for (i = 0; i < s->n_chan; i++)
- labpc_ao_write(dev, s, i, s->maxdata / 2);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* 8255 dio */
- s = &dev->subdevices[2];
- if (dev->mmio)
- ret = subdev_8255_mm_init(dev, s, NULL, DIO_BASE_REG);
- else
- ret = subdev_8255_init(dev, s, NULL, DIO_BASE_REG);
- if (ret)
- return ret;
-
- /* calibration subdevices for boards that have one */
- s = &dev->subdevices[3];
- if (board->is_labpc1200) {
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 16;
- s->maxdata = 0xff;
- s->insn_write = labpc_calib_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++) {
- write_caldac(dev, i, s->maxdata / 2);
- s->readback[i] = s->maxdata / 2;
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* EEPROM (256 bytes) */
- s = &dev->subdevices[4];
- if (board->is_labpc1200) {
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 256;
- s->maxdata = 0xff;
- s->insn_write = labpc_eeprom_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- for (i = 0; i < s->n_chan; i++)
- s->readback[i] = labpc_eeprom_read(dev, i);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(labpc_common_attach);
-
-void labpc_common_detach(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
-
- if (devpriv)
- kfree(devpriv->counter);
-}
-EXPORT_SYMBOL_GPL(labpc_common_detach);
-
-static int __init labpc_common_init(void)
-{
- return 0;
-}
-module_init(labpc_common_init);
-
-static void __exit labpc_common_exit(void)
-{
-}
-module_exit(labpc_common_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi helper for ni_labpc, ni_labpc_pci, ni_labpc_cs");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
deleted file mode 100644
index 4f7e2fe21254..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Driver for National Instruments daqcard-1200 boards
- * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- * PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
- * from the pcmcia package.
- * The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
- * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- * are Copyright (C) 1999 David A. Hinds.
- */
-
-/*
- * Driver: ni_labpc_cs
- * Description: National Instruments Lab-PC (& compatibles)
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Devices: [National Instruments] DAQCard-1200 (daqcard-1200)
- * Status: works
- *
- * Thanks go to Fredrik Lingvall for much testing and perseverance in
- * helping to debug daqcard-1200 support.
- *
- * The 1200 series boards have onboard calibration dacs for correcting
- * analog input/output offsets and gains. The proper settings for these
- * caldacs are stored on the board's eeprom. To read the caldac values
- * from the eeprom and store them into a file that can be then be used by
- * comedilib, use the comedi_calibrate program.
- *
- * Configuration options: none
- *
- * The daqcard-1200 has quirky chanlist requirements when scanning multiple
- * channels. Multiple channel scan sequence must start at highest channel,
- * then decrement down to channel 0. Chanlists consisting of all one channel
- * are also legal, and allow you to pace conversions in bursts.
- *
- * NI manuals:
- * 340988a (daqcard-1200)
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pcmcia.h"
-
-#include "ni_labpc.h"
-
-static const struct labpc_boardinfo labpc_cs_boards[] = {
- {
- .name = "daqcard-1200",
- .ai_speed = 10000,
- .has_ao = 1,
- .is_labpc1200 = 1,
- },
-};
-
-static int labpc_cs_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- int ret;
-
- /* The ni_labpc driver needs the board_ptr */
- dev->board_ptr = &labpc_cs_boards[0];
-
- link->config_flags |= CONF_AUTO_SET_IO |
- CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
- ret = comedi_pcmcia_enable(dev, NULL);
- if (ret)
- return ret;
- dev->iobase = link->resource[0]->start;
-
- if (!link->irq)
- return -EINVAL;
-
- return labpc_common_attach(dev, link->irq, IRQF_SHARED);
-}
-
-static void labpc_cs_detach(struct comedi_device *dev)
-{
- labpc_common_detach(dev);
- comedi_pcmcia_disable(dev);
-}
-
-static struct comedi_driver driver_labpc_cs = {
- .driver_name = "ni_labpc_cs",
- .module = THIS_MODULE,
- .auto_attach = labpc_cs_auto_attach,
- .detach = labpc_cs_detach,
-};
-
-static int labpc_cs_attach(struct pcmcia_device *link)
-{
- return comedi_pcmcia_auto_config(link, &driver_labpc_cs);
-}
-
-static const struct pcmcia_device_id labpc_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103), /* daqcard-1200 */
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids);
-
-static struct pcmcia_driver labpc_cs_driver = {
- .name = "daqcard-1200",
- .owner = THIS_MODULE,
- .id_table = labpc_cs_ids,
- .probe = labpc_cs_attach,
- .remove = comedi_pcmcia_auto_unconfig,
-};
-module_comedi_pcmcia_driver(driver_labpc_cs, labpc_cs_driver);
-
-MODULE_DESCRIPTION("Comedi driver for National Instruments Lab-PC");
-MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
deleted file mode 100644
index a551aca6e615..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c
+++ /dev/null
@@ -1,181 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/ni_labpc_isadma.c
- * ISA DMA support for National Instruments Lab-PC series boards and
- * compatibles.
- *
- * Extracted from ni_labpc.c:
- * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-#include "ni_labpc.h"
-#include "ni_labpc_regs.h"
-#include "ni_labpc_isadma.h"
-
-/* size in bytes of dma buffer */
-#define LABPC_ISADMA_BUFFER_SIZE 0xff00
-
-/* utility function that suggests a dma transfer size in bytes */
-static unsigned int labpc_suggest_transfer_size(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int maxbytes)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int sample_size = comedi_bytes_per_sample(s);
- unsigned int size;
- unsigned int freq;
-
- if (cmd->convert_src == TRIG_TIMER)
- freq = 1000000000 / cmd->convert_arg;
- else
- /* return some default value */
- freq = 0xffffffff;
-
- /* make buffer fill in no more than 1/3 second */
- size = (freq / 3) * sample_size;
-
- /* set a minimum and maximum size allowed */
- if (size > maxbytes)
- size = maxbytes;
- else if (size < sample_size)
- size = sample_size;
-
- return size;
-}
-
-void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct labpc_private *devpriv = dev->private;
- struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int sample_size = comedi_bytes_per_sample(s);
-
- /* set appropriate size of transfer */
- desc->size = labpc_suggest_transfer_size(dev, s, desc->maxsize);
- if (cmd->stop_src == TRIG_COUNT &&
- devpriv->count * sample_size < desc->size)
- desc->size = devpriv->count * sample_size;
-
- comedi_isadma_program(desc);
-
- /* set CMD3 bits for caller to enable DMA and interrupt */
- devpriv->cmd3 |= (CMD3_DMAEN | CMD3_DMATCINTEN);
-}
-EXPORT_SYMBOL_GPL(labpc_setup_dma);
-
-void labpc_drain_dma(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int max_samples = comedi_bytes_to_samples(s, desc->size);
- unsigned int residue;
- unsigned int nsamples;
- unsigned int leftover;
-
- /*
- * residue is the number of bytes left to be done on the dma
- * transfer. It should always be zero at this point unless
- * the stop_src is set to external triggering.
- */
- residue = comedi_isadma_disable(desc->chan);
-
- /*
- * Figure out how many samples to read for this transfer and
- * how many will be stored for next time.
- */
- nsamples = max_samples - comedi_bytes_to_samples(s, residue);
- if (cmd->stop_src == TRIG_COUNT) {
- if (devpriv->count <= nsamples) {
- nsamples = devpriv->count;
- leftover = 0;
- } else {
- leftover = devpriv->count - nsamples;
- if (leftover > max_samples)
- leftover = max_samples;
- }
- devpriv->count -= nsamples;
- } else {
- leftover = max_samples;
- }
- desc->size = comedi_samples_to_bytes(s, leftover);
-
- comedi_buf_write_samples(s, desc->virt_addr, nsamples);
-}
-EXPORT_SYMBOL_GPL(labpc_drain_dma);
-
-static void handle_isa_dma(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
-
- labpc_drain_dma(dev);
-
- if (desc->size)
- comedi_isadma_program(desc);
-
- /* clear dma tc interrupt */
- devpriv->write_byte(dev, 0x1, DMATC_CLEAR_REG);
-}
-
-void labpc_handle_dma_status(struct comedi_device *dev)
-{
- const struct labpc_boardinfo *board = dev->board_ptr;
- struct labpc_private *devpriv = dev->private;
-
- /*
- * if a dma terminal count of external stop trigger
- * has occurred
- */
- if (devpriv->stat1 & STAT1_GATA0 ||
- (board->is_labpc1200 && devpriv->stat2 & STAT2_OUTA1))
- handle_isa_dma(dev);
-}
-EXPORT_SYMBOL_GPL(labpc_handle_dma_status);
-
-void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan)
-{
- struct labpc_private *devpriv = dev->private;
-
- /* only DMA channels 3 and 1 are valid */
- if (dma_chan != 1 && dma_chan != 3)
- return;
-
- /* DMA uses 1 buffer */
- devpriv->dma = comedi_isadma_alloc(dev, 1, dma_chan, dma_chan,
- LABPC_ISADMA_BUFFER_SIZE,
- COMEDI_ISADMA_READ);
-}
-EXPORT_SYMBOL_GPL(labpc_init_dma_chan);
-
-void labpc_free_dma_chan(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
-
- if (devpriv)
- comedi_isadma_free(devpriv->dma);
-}
-EXPORT_SYMBOL_GPL(labpc_free_dma_chan);
-
-static int __init ni_labpc_isadma_init_module(void)
-{
- return 0;
-}
-module_init(ni_labpc_isadma_init_module);
-
-static void __exit ni_labpc_isadma_cleanup_module(void)
-{
-}
-module_exit(ni_labpc_isadma_cleanup_module);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi NI Lab-PC ISA DMA support");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.h b/drivers/staging/comedi/drivers/ni_labpc_isadma.h
deleted file mode 100644
index f06f9353cb6c..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * ni_labpc ISA DMA support.
- */
-
-#ifndef _NI_LABPC_ISADMA_H
-#define _NI_LABPC_ISADMA_H
-
-#if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISADMA)
-
-void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan);
-void labpc_free_dma_chan(struct comedi_device *dev);
-void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s);
-void labpc_drain_dma(struct comedi_device *dev);
-void labpc_handle_dma_status(struct comedi_device *dev);
-
-#else
-
-static inline void labpc_init_dma_chan(struct comedi_device *dev,
- unsigned int dma_chan)
-{
-}
-
-static inline void labpc_free_dma_chan(struct comedi_device *dev)
-{
-}
-
-static inline void labpc_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
-}
-
-static inline void labpc_drain_dma(struct comedi_device *dev)
-{
-}
-
-static inline void labpc_handle_dma_status(struct comedi_device *dev)
-{
-}
-
-#endif
-
-#endif /* _NI_LABPC_ISADMA_H */
diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c
deleted file mode 100644
index ec180b0fedf7..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc_pci.c
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/ni_labpc_pci.c
- * Driver for National Instruments Lab-PC PCI-1200
- * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-/*
- * Driver: ni_labpc_pci
- * Description: National Instruments Lab-PC PCI-1200
- * Devices: [National Instruments] PCI-1200 (ni_pci-1200)
- * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
- * Status: works
- *
- * This is the PCI-specific support split off from the ni_labpc driver.
- *
- * Configuration Options: not applicable, uses PCI auto config
- *
- * NI manuals:
- * 340914a (pci-1200)
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "ni_labpc.h"
-
-enum labpc_pci_boardid {
- BOARD_NI_PCI1200,
-};
-
-static const struct labpc_boardinfo labpc_pci_boards[] = {
- [BOARD_NI_PCI1200] = {
- .name = "ni_pci-1200",
- .ai_speed = 10000,
- .ai_scan_up = 1,
- .has_ao = 1,
- .is_labpc1200 = 1,
- },
-};
-
-/* ripped from mite.h and mite_setup2() to avoid mite dependency */
-#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
-#define WENAB BIT(7) /* window enable */
-
-static int labpc_pci_mite_init(struct pci_dev *pcidev)
-{
- void __iomem *mite_base;
- u32 main_phys_addr;
-
- /* ioremap the MITE registers (BAR 0) temporarily */
- mite_base = pci_ioremap_bar(pcidev, 0);
- if (!mite_base)
- return -ENOMEM;
-
- /* set data window to main registers (BAR 1) */
- main_phys_addr = pci_resource_start(pcidev, 1);
- writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
-
- /* finished with MITE registers */
- iounmap(mite_base);
- return 0;
-}
-
-static int labpc_pci_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct labpc_boardinfo *board = NULL;
- int ret;
-
- if (context < ARRAY_SIZE(labpc_pci_boards))
- board = &labpc_pci_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- ret = labpc_pci_mite_init(pcidev);
- if (ret)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 1);
- if (!dev->mmio)
- return -ENOMEM;
-
- return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED);
-}
-
-static void labpc_pci_detach(struct comedi_device *dev)
-{
- labpc_common_detach(dev);
- comedi_pci_detach(dev);
-}
-
-static struct comedi_driver labpc_pci_comedi_driver = {
- .driver_name = "labpc_pci",
- .module = THIS_MODULE,
- .auto_attach = labpc_pci_auto_attach,
- .detach = labpc_pci_detach,
-};
-
-static const struct pci_device_id labpc_pci_table[] = {
- { PCI_VDEVICE(NI, 0x161), BOARD_NI_PCI1200 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, labpc_pci_table);
-
-static int labpc_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &labpc_pci_comedi_driver,
- id->driver_data);
-}
-
-static struct pci_driver labpc_pci_driver = {
- .name = "labpc_pci",
- .id_table = labpc_pci_table,
- .probe = labpc_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(labpc_pci_comedi_driver, labpc_pci_driver);
-
-MODULE_DESCRIPTION("Comedi: National Instruments Lab-PC PCI-1200 driver");
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc_regs.h b/drivers/staging/comedi/drivers/ni_labpc_regs.h
deleted file mode 100644
index ace40065a25b..000000000000
--- a/drivers/staging/comedi/drivers/ni_labpc_regs.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * ni_labpc register definitions.
- */
-
-#ifndef _NI_LABPC_REGS_H
-#define _NI_LABPC_REGS_H
-
-/*
- * Register map (all registers are 8-bit)
- */
-#define STAT1_REG 0x00 /* R: Status 1 reg */
-#define STAT1_DAVAIL BIT(0)
-#define STAT1_OVERRUN BIT(1)
-#define STAT1_OVERFLOW BIT(2)
-#define STAT1_CNTINT BIT(3)
-#define STAT1_GATA0 BIT(5)
-#define STAT1_EXTGATA0 BIT(6)
-#define CMD1_REG 0x00 /* W: Command 1 reg */
-#define CMD1_MA(x) (((x) & 0x7) << 0)
-#define CMD1_TWOSCMP BIT(3)
-#define CMD1_GAIN(x) (((x) & 0x7) << 4)
-#define CMD1_SCANEN BIT(7)
-#define CMD2_REG 0x01 /* W: Command 2 reg */
-#define CMD2_PRETRIG BIT(0)
-#define CMD2_HWTRIG BIT(1)
-#define CMD2_SWTRIG BIT(2)
-#define CMD2_TBSEL BIT(3)
-#define CMD2_2SDAC0 BIT(4)
-#define CMD2_2SDAC1 BIT(5)
-#define CMD2_LDAC(x) BIT(6 + ((x) & 0x1))
-#define CMD3_REG 0x02 /* W: Command 3 reg */
-#define CMD3_DMAEN BIT(0)
-#define CMD3_DIOINTEN BIT(1)
-#define CMD3_DMATCINTEN BIT(2)
-#define CMD3_CNTINTEN BIT(3)
-#define CMD3_ERRINTEN BIT(4)
-#define CMD3_FIFOINTEN BIT(5)
-#define ADC_START_CONVERT_REG 0x03 /* W: Start Convert reg */
-#define DAC_LSB_REG(x) (0x04 + 2 * (x)) /* W: DAC0/1 LSB reg */
-#define DAC_MSB_REG(x) (0x05 + 2 * (x)) /* W: DAC0/1 MSB reg */
-#define ADC_FIFO_CLEAR_REG 0x08 /* W: A/D FIFO Clear reg */
-#define ADC_FIFO_REG 0x0a /* R: A/D FIFO reg */
-#define DMATC_CLEAR_REG 0x0a /* W: DMA Interrupt Clear reg */
-#define TIMER_CLEAR_REG 0x0c /* W: Timer Interrupt Clear reg */
-#define CMD6_REG 0x0e /* W: Command 6 reg */
-#define CMD6_NRSE BIT(0)
-#define CMD6_ADCUNI BIT(1)
-#define CMD6_DACUNI(x) BIT(2 + ((x) & 0x1))
-#define CMD6_HFINTEN BIT(5)
-#define CMD6_DQINTEN BIT(6)
-#define CMD6_SCANUP BIT(7)
-#define CMD4_REG 0x0f /* W: Command 3 reg */
-#define CMD4_INTSCAN BIT(0)
-#define CMD4_EOIRCV BIT(1)
-#define CMD4_ECLKDRV BIT(2)
-#define CMD4_SEDIFF BIT(3)
-#define CMD4_ECLKRCV BIT(4)
-#define DIO_BASE_REG 0x10 /* R/W: 8255 DIO base reg */
-#define COUNTER_A_BASE_REG 0x14 /* R/W: 8253 Counter A base reg */
-#define COUNTER_B_BASE_REG 0x18 /* R/W: 8253 Counter B base reg */
-#define CMD5_REG 0x1c /* W: Command 5 reg */
-#define CMD5_WRTPRT BIT(2)
-#define CMD5_DITHEREN BIT(3)
-#define CMD5_CALDACLD BIT(4)
-#define CMD5_SCLK BIT(5)
-#define CMD5_SDATA BIT(6)
-#define CMD5_EEPROMCS BIT(7)
-#define STAT2_REG 0x1d /* R: Status 2 reg */
-#define STAT2_PROMOUT BIT(0)
-#define STAT2_OUTA1 BIT(1)
-#define STAT2_FIFONHF BIT(2)
-#define INTERVAL_COUNT_REG 0x1e /* W: Interval Counter Data reg */
-#define INTERVAL_STROBE_REG 0x1f /* W: Interval Counter Strobe reg */
-
-#endif /* _NI_LABPC_REGS_H */
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
deleted file mode 100644
index 4f80a4991f95..000000000000
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ /dev/null
@@ -1,6341 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Hardware driver for DAQ-STC based boards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
- * Copyright (C) 2002-2006 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-/*
- * This file is meant to be included by another file, e.g.,
- * ni_atmio.c or ni_pcimio.c.
- *
- * Interrupt support originally added by Truxton Fulton <trux@truxton.com>
- *
- * References (ftp://ftp.natinst.com/support/manuals):
- * 340747b.pdf AT-MIO E series Register Level Programmer Manual
- * 341079b.pdf PCI E Series RLPM
- * 340934b.pdf DAQ-STC reference manual
- *
- * 67xx and 611x registers (ftp://ftp.ni.com/support/daq/mhddk/documentation/)
- * release_ni611x.pdf
- * release_ni67xx.pdf
- *
- * Other possibly relevant info:
- * 320517c.pdf User manual (obsolete)
- * 320517f.pdf User manual (new)
- * 320889a.pdf delete
- * 320906c.pdf maximum signal ratings
- * 321066a.pdf about 16x
- * 321791a.pdf discontinuation of at-mio-16e-10 rev. c
- * 321808a.pdf about at-mio-16e-10 rev P
- * 321837a.pdf discontinuation of at-mio-16de-10 rev d
- * 321838a.pdf about at-mio-16de-10 rev N
- *
- * ISSUES:
- * - the interrupt routine needs to be cleaned up
- *
- * 2006-02-07: S-Series PCI-6143: Support has been added but is not
- * fully tested as yet. Terry Barnaby, BEAM Ltd.
- */
-
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include "8255.h"
-#include "mite.h"
-
-/* A timeout count */
-#define NI_TIMEOUT 1000
-
-/* Note: this table must match the ai_gain_* definitions */
-static const short ni_gainlkup[][16] = {
- [ai_gain_16] = {0, 1, 2, 3, 4, 5, 6, 7,
- 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
- [ai_gain_8] = {1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107},
- [ai_gain_14] = {1, 2, 3, 4, 5, 6, 7,
- 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
- [ai_gain_4] = {0, 1, 4, 7},
- [ai_gain_611x] = {0x00a, 0x00b, 0x001, 0x002,
- 0x003, 0x004, 0x005, 0x006},
- [ai_gain_622x] = {0, 1, 4, 5},
- [ai_gain_628x] = {1, 2, 3, 4, 5, 6, 7},
- [ai_gain_6143] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-};
-
-static const struct comedi_lrange range_ni_E_ai = {
- 16, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.25),
- BIP_RANGE(0.1),
- BIP_RANGE(0.05),
- UNI_RANGE(20),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5),
- UNI_RANGE(0.2),
- UNI_RANGE(0.1)
- }
-};
-
-static const struct comedi_lrange range_ni_E_ai_limited = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(1),
- UNI_RANGE(0.1)
- }
-};
-
-static const struct comedi_lrange range_ni_E_ai_limited14 = {
- 14, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.2),
- BIP_RANGE(0.1),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5),
- UNI_RANGE(0.2),
- UNI_RANGE(0.1)
- }
-};
-
-static const struct comedi_lrange range_ni_E_ai_bipolar4 = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05)
- }
-};
-
-static const struct comedi_lrange range_ni_E_ai_611x = {
- 8, {
- BIP_RANGE(50),
- BIP_RANGE(20),
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.2)
- }
-};
-
-static const struct comedi_lrange range_ni_M_ai_622x = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(1),
- BIP_RANGE(0.2)
- }
-};
-
-static const struct comedi_lrange range_ni_M_ai_628x = {
- 7, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- BIP_RANGE(0.5),
- BIP_RANGE(0.2),
- BIP_RANGE(0.1)
- }
-};
-
-static const struct comedi_lrange range_ni_E_ao_ext = {
- 4, {
- BIP_RANGE(10),
- UNI_RANGE(10),
- RANGE_ext(-1, 1),
- RANGE_ext(0, 1)
- }
-};
-
-static const struct comedi_lrange *const ni_range_lkup[] = {
- [ai_gain_16] = &range_ni_E_ai,
- [ai_gain_8] = &range_ni_E_ai_limited,
- [ai_gain_14] = &range_ni_E_ai_limited14,
- [ai_gain_4] = &range_ni_E_ai_bipolar4,
- [ai_gain_611x] = &range_ni_E_ai_611x,
- [ai_gain_622x] = &range_ni_M_ai_622x,
- [ai_gain_628x] = &range_ni_M_ai_628x,
- [ai_gain_6143] = &range_bipolar5
-};
-
-enum aimodes {
- AIMODE_NONE = 0,
- AIMODE_HALF_FULL = 1,
- AIMODE_SCAN = 2,
- AIMODE_SAMPLE = 3,
-};
-
-enum ni_common_subdevices {
- NI_AI_SUBDEV,
- NI_AO_SUBDEV,
- NI_DIO_SUBDEV,
- NI_8255_DIO_SUBDEV,
- NI_UNUSED_SUBDEV,
- NI_CALIBRATION_SUBDEV,
- NI_EEPROM_SUBDEV,
- NI_PFI_DIO_SUBDEV,
- NI_CS5529_CALIBRATION_SUBDEV,
- NI_SERIAL_SUBDEV,
- NI_RTSI_SUBDEV,
- NI_GPCT0_SUBDEV,
- NI_GPCT1_SUBDEV,
- NI_FREQ_OUT_SUBDEV,
- NI_NUM_SUBDEVICES
-};
-
-#define NI_GPCT_SUBDEV(x) (NI_GPCT0_SUBDEV + (x))
-
-enum timebase_nanoseconds {
- TIMEBASE_1_NS = 50,
- TIMEBASE_2_NS = 10000
-};
-
-#define SERIAL_DISABLED 0
-#define SERIAL_600NS 600
-#define SERIAL_1_2US 1200
-#define SERIAL_10US 10000
-
-static const int num_adc_stages_611x = 3;
-
-static void ni_writel(struct comedi_device *dev, unsigned int data, int reg)
-{
- if (dev->mmio)
- writel(data, dev->mmio + reg);
- else
- outl(data, dev->iobase + reg);
-}
-
-static void ni_writew(struct comedi_device *dev, unsigned int data, int reg)
-{
- if (dev->mmio)
- writew(data, dev->mmio + reg);
- else
- outw(data, dev->iobase + reg);
-}
-
-static void ni_writeb(struct comedi_device *dev, unsigned int data, int reg)
-{
- if (dev->mmio)
- writeb(data, dev->mmio + reg);
- else
- outb(data, dev->iobase + reg);
-}
-
-static unsigned int ni_readl(struct comedi_device *dev, int reg)
-{
- if (dev->mmio)
- return readl(dev->mmio + reg);
-
- return inl(dev->iobase + reg);
-}
-
-static unsigned int ni_readw(struct comedi_device *dev, int reg)
-{
- if (dev->mmio)
- return readw(dev->mmio + reg);
-
- return inw(dev->iobase + reg);
-}
-
-static unsigned int ni_readb(struct comedi_device *dev, int reg)
-{
- if (dev->mmio)
- return readb(dev->mmio + reg);
-
- return inb(dev->iobase + reg);
-}
-
-/*
- * We automatically take advantage of STC registers that can be
- * read/written directly in the I/O space of the board.
- *
- * The AT-MIO and DAQCard devices map the low 8 STC registers to
- * iobase+reg*2.
- *
- * Most PCIMIO devices also map the low 8 STC registers but the
- * 611x devices map the read registers to iobase+(addr-1)*2.
- * For now non-windowed STC access is disabled if a PCIMIO device
- * is detected (devpriv->mite has been initialized).
- *
- * The M series devices do not used windowed registers for the
- * STC registers. The functions below handle the mapping of the
- * windowed STC registers to the m series register offsets.
- */
-
-struct mio_regmap {
- unsigned int mio_reg;
- int size;
-};
-
-static const struct mio_regmap m_series_stc_write_regmap[] = {
- [NISTC_INTA_ACK_REG] = { 0x104, 2 },
- [NISTC_INTB_ACK_REG] = { 0x106, 2 },
- [NISTC_AI_CMD2_REG] = { 0x108, 2 },
- [NISTC_AO_CMD2_REG] = { 0x10a, 2 },
- [NISTC_G0_CMD_REG] = { 0x10c, 2 },
- [NISTC_G1_CMD_REG] = { 0x10e, 2 },
- [NISTC_AI_CMD1_REG] = { 0x110, 2 },
- [NISTC_AO_CMD1_REG] = { 0x112, 2 },
- /*
- * NISTC_DIO_OUT_REG maps to:
- * { NI_M_DIO_REG, 4 } and { NI_M_SCXI_SER_DO_REG, 1 }
- */
- [NISTC_DIO_OUT_REG] = { 0, 0 }, /* DOES NOT MAP CLEANLY */
- [NISTC_DIO_CTRL_REG] = { 0, 0 }, /* DOES NOT MAP CLEANLY */
- [NISTC_AI_MODE1_REG] = { 0x118, 2 },
- [NISTC_AI_MODE2_REG] = { 0x11a, 2 },
- [NISTC_AI_SI_LOADA_REG] = { 0x11c, 4 },
- [NISTC_AI_SI_LOADB_REG] = { 0x120, 4 },
- [NISTC_AI_SC_LOADA_REG] = { 0x124, 4 },
- [NISTC_AI_SC_LOADB_REG] = { 0x128, 4 },
- [NISTC_AI_SI2_LOADA_REG] = { 0x12c, 4 },
- [NISTC_AI_SI2_LOADB_REG] = { 0x130, 4 },
- [NISTC_G0_MODE_REG] = { 0x134, 2 },
- [NISTC_G1_MODE_REG] = { 0x136, 2 },
- [NISTC_G0_LOADA_REG] = { 0x138, 4 },
- [NISTC_G0_LOADB_REG] = { 0x13c, 4 },
- [NISTC_G1_LOADA_REG] = { 0x140, 4 },
- [NISTC_G1_LOADB_REG] = { 0x144, 4 },
- [NISTC_G0_INPUT_SEL_REG] = { 0x148, 2 },
- [NISTC_G1_INPUT_SEL_REG] = { 0x14a, 2 },
- [NISTC_AO_MODE1_REG] = { 0x14c, 2 },
- [NISTC_AO_MODE2_REG] = { 0x14e, 2 },
- [NISTC_AO_UI_LOADA_REG] = { 0x150, 4 },
- [NISTC_AO_UI_LOADB_REG] = { 0x154, 4 },
- [NISTC_AO_BC_LOADA_REG] = { 0x158, 4 },
- [NISTC_AO_BC_LOADB_REG] = { 0x15c, 4 },
- [NISTC_AO_UC_LOADA_REG] = { 0x160, 4 },
- [NISTC_AO_UC_LOADB_REG] = { 0x164, 4 },
- [NISTC_CLK_FOUT_REG] = { 0x170, 2 },
- [NISTC_IO_BIDIR_PIN_REG] = { 0x172, 2 },
- [NISTC_RTSI_TRIG_DIR_REG] = { 0x174, 2 },
- [NISTC_INT_CTRL_REG] = { 0x176, 2 },
- [NISTC_AI_OUT_CTRL_REG] = { 0x178, 2 },
- [NISTC_ATRIG_ETC_REG] = { 0x17a, 2 },
- [NISTC_AI_START_STOP_REG] = { 0x17c, 2 },
- [NISTC_AI_TRIG_SEL_REG] = { 0x17e, 2 },
- [NISTC_AI_DIV_LOADA_REG] = { 0x180, 4 },
- [NISTC_AO_START_SEL_REG] = { 0x184, 2 },
- [NISTC_AO_TRIG_SEL_REG] = { 0x186, 2 },
- [NISTC_G0_AUTOINC_REG] = { 0x188, 2 },
- [NISTC_G1_AUTOINC_REG] = { 0x18a, 2 },
- [NISTC_AO_MODE3_REG] = { 0x18c, 2 },
- [NISTC_RESET_REG] = { 0x190, 2 },
- [NISTC_INTA_ENA_REG] = { 0x192, 2 },
- [NISTC_INTA2_ENA_REG] = { 0, 0 }, /* E-Series only */
- [NISTC_INTB_ENA_REG] = { 0x196, 2 },
- [NISTC_INTB2_ENA_REG] = { 0, 0 }, /* E-Series only */
- [NISTC_AI_PERSONAL_REG] = { 0x19a, 2 },
- [NISTC_AO_PERSONAL_REG] = { 0x19c, 2 },
- [NISTC_RTSI_TRIGA_OUT_REG] = { 0x19e, 2 },
- [NISTC_RTSI_TRIGB_OUT_REG] = { 0x1a0, 2 },
- /* doc for following line: mhddk/nimseries/ChipObjects/tMSeries.h */
- [NISTC_RTSI_BOARD_REG] = { 0x1a2, 2 },
- [NISTC_CFG_MEM_CLR_REG] = { 0x1a4, 2 },
- [NISTC_ADC_FIFO_CLR_REG] = { 0x1a6, 2 },
- [NISTC_DAC_FIFO_CLR_REG] = { 0x1a8, 2 },
- [NISTC_AO_OUT_CTRL_REG] = { 0x1ac, 2 },
- [NISTC_AI_MODE3_REG] = { 0x1ae, 2 },
-};
-
-static void m_series_stc_write(struct comedi_device *dev,
- unsigned int data, unsigned int reg)
-{
- const struct mio_regmap *regmap;
-
- if (reg < ARRAY_SIZE(m_series_stc_write_regmap)) {
- regmap = &m_series_stc_write_regmap[reg];
- } else {
- dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n",
- __func__, reg);
- return;
- }
-
- switch (regmap->size) {
- case 4:
- ni_writel(dev, data, regmap->mio_reg);
- break;
- case 2:
- ni_writew(dev, data, regmap->mio_reg);
- break;
- default:
- dev_warn(dev->class_dev, "%s: unmapped register=0x%x\n",
- __func__, reg);
- break;
- }
-}
-
-static const struct mio_regmap m_series_stc_read_regmap[] = {
- [NISTC_AI_STATUS1_REG] = { 0x104, 2 },
- [NISTC_AO_STATUS1_REG] = { 0x106, 2 },
- [NISTC_G01_STATUS_REG] = { 0x108, 2 },
- [NISTC_AI_STATUS2_REG] = { 0, 0 }, /* Unknown */
- [NISTC_AO_STATUS2_REG] = { 0x10c, 2 },
- [NISTC_DIO_IN_REG] = { 0, 0 }, /* Unknown */
- [NISTC_G0_HW_SAVE_REG] = { 0x110, 4 },
- [NISTC_G1_HW_SAVE_REG] = { 0x114, 4 },
- [NISTC_G0_SAVE_REG] = { 0x118, 4 },
- [NISTC_G1_SAVE_REG] = { 0x11c, 4 },
- [NISTC_AO_UI_SAVE_REG] = { 0x120, 4 },
- [NISTC_AO_BC_SAVE_REG] = { 0x124, 4 },
- [NISTC_AO_UC_SAVE_REG] = { 0x128, 4 },
- [NISTC_STATUS1_REG] = { 0x136, 2 },
- [NISTC_DIO_SERIAL_IN_REG] = { 0x009, 1 },
- [NISTC_STATUS2_REG] = { 0x13a, 2 },
- [NISTC_AI_SI_SAVE_REG] = { 0x180, 4 },
- [NISTC_AI_SC_SAVE_REG] = { 0x184, 4 },
-};
-
-static unsigned int m_series_stc_read(struct comedi_device *dev,
- unsigned int reg)
-{
- const struct mio_regmap *regmap;
-
- if (reg < ARRAY_SIZE(m_series_stc_read_regmap)) {
- regmap = &m_series_stc_read_regmap[reg];
- } else {
- dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n",
- __func__, reg);
- return 0;
- }
-
- switch (regmap->size) {
- case 4:
- return ni_readl(dev, regmap->mio_reg);
- case 2:
- return ni_readw(dev, regmap->mio_reg);
- case 1:
- return ni_readb(dev, regmap->mio_reg);
- default:
- dev_warn(dev->class_dev, "%s: unmapped register=0x%x\n",
- __func__, reg);
- return 0;
- }
-}
-
-static void ni_stc_writew(struct comedi_device *dev,
- unsigned int data, int reg)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- if (devpriv->is_m_series) {
- m_series_stc_write(dev, data, reg);
- } else {
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (!devpriv->mite && reg < 8) {
- ni_writew(dev, data, reg * 2);
- } else {
- ni_writew(dev, reg, NI_E_STC_WINDOW_ADDR_REG);
- ni_writew(dev, data, NI_E_STC_WINDOW_DATA_REG);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
- }
-}
-
-static void ni_stc_writel(struct comedi_device *dev,
- unsigned int data, int reg)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->is_m_series) {
- m_series_stc_write(dev, data, reg);
- } else {
- ni_stc_writew(dev, data >> 16, reg);
- ni_stc_writew(dev, data & 0xffff, reg + 1);
- }
-}
-
-static unsigned int ni_stc_readw(struct comedi_device *dev, int reg)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
- unsigned int val;
-
- if (devpriv->is_m_series) {
- val = m_series_stc_read(dev, reg);
- } else {
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (!devpriv->mite && reg < 8) {
- val = ni_readw(dev, reg * 2);
- } else {
- ni_writew(dev, reg, NI_E_STC_WINDOW_ADDR_REG);
- val = ni_readw(dev, NI_E_STC_WINDOW_DATA_REG);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
- }
- return val;
-}
-
-static unsigned int ni_stc_readl(struct comedi_device *dev, int reg)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int val;
-
- if (devpriv->is_m_series) {
- val = m_series_stc_read(dev, reg);
- } else {
- val = ni_stc_readw(dev, reg) << 16;
- val |= ni_stc_readw(dev, reg + 1);
- }
- return val;
-}
-
-static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
- unsigned int bit_mask,
- unsigned int bit_values)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
- switch (reg) {
- case NISTC_INTA_ENA_REG:
- devpriv->int_a_enable_reg &= ~bit_mask;
- devpriv->int_a_enable_reg |= bit_values & bit_mask;
- ni_stc_writew(dev, devpriv->int_a_enable_reg, reg);
- break;
- case NISTC_INTB_ENA_REG:
- devpriv->int_b_enable_reg &= ~bit_mask;
- devpriv->int_b_enable_reg |= bit_values & bit_mask;
- ni_stc_writew(dev, devpriv->int_b_enable_reg, reg);
- break;
- case NISTC_IO_BIDIR_PIN_REG:
- devpriv->io_bidirection_pin_reg &= ~bit_mask;
- devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
- ni_stc_writew(dev, devpriv->io_bidirection_pin_reg, reg);
- break;
- case NI_E_DMA_AI_AO_SEL_REG:
- devpriv->ai_ao_select_reg &= ~bit_mask;
- devpriv->ai_ao_select_reg |= bit_values & bit_mask;
- ni_writeb(dev, devpriv->ai_ao_select_reg, reg);
- break;
- case NI_E_DMA_G0_G1_SEL_REG:
- devpriv->g0_g1_select_reg &= ~bit_mask;
- devpriv->g0_g1_select_reg |= bit_values & bit_mask;
- ni_writeb(dev, devpriv->g0_g1_select_reg, reg);
- break;
- case NI_M_CDIO_DMA_SEL_REG:
- devpriv->cdio_dma_select_reg &= ~bit_mask;
- devpriv->cdio_dma_select_reg |= bit_values & bit_mask;
- ni_writeb(dev, devpriv->cdio_dma_select_reg, reg);
- break;
- default:
- dev_err(dev->class_dev, "called with invalid register %d\n",
- reg);
- break;
- }
- spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
-}
-
-#ifdef PCIDMA
-
-/* selects the MITE channel to use for DMA */
-#define NI_STC_DMA_CHAN_SEL(x) (((x) < 4) ? BIT(x) : \
- ((x) == 4) ? 0x3 : \
- ((x) == 5) ? 0x5 : 0x0)
-
-/* DMA channel setup */
-static int ni_request_ai_mite_channel(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct mite_channel *mite_chan;
- unsigned long flags;
- unsigned int bits;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- mite_chan = mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
- if (!mite_chan) {
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- dev_err(dev->class_dev,
- "failed to reserve mite dma channel for analog input\n");
- return -EBUSY;
- }
- mite_chan->dir = COMEDI_INPUT;
- devpriv->ai_mite_chan = mite_chan;
-
- bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
- ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
- NI_E_DMA_AI_SEL_MASK, NI_E_DMA_AI_SEL(bits));
-
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- return 0;
-}
-
-static int ni_request_ao_mite_channel(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct mite_channel *mite_chan;
- unsigned long flags;
- unsigned int bits;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- mite_chan = mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
- if (!mite_chan) {
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- dev_err(dev->class_dev,
- "failed to reserve mite dma channel for analog output\n");
- return -EBUSY;
- }
- mite_chan->dir = COMEDI_OUTPUT;
- devpriv->ao_mite_chan = mite_chan;
-
- bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
- ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
- NI_E_DMA_AO_SEL_MASK, NI_E_DMA_AO_SEL(bits));
-
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- return 0;
-}
-
-static int ni_request_gpct_mite_channel(struct comedi_device *dev,
- unsigned int gpct_index,
- enum comedi_io_direction direction)
-{
- struct ni_private *devpriv = dev->private;
- struct ni_gpct *counter = &devpriv->counter_dev->counters[gpct_index];
- struct mite_channel *mite_chan;
- unsigned long flags;
- unsigned int bits;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- mite_chan = mite_request_channel(devpriv->mite,
- devpriv->gpct_mite_ring[gpct_index]);
- if (!mite_chan) {
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- dev_err(dev->class_dev,
- "failed to reserve mite dma channel for counter\n");
- return -EBUSY;
- }
- mite_chan->dir = direction;
- ni_tio_set_mite_channel(counter, mite_chan);
-
- bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
- ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
- NI_E_DMA_G0_G1_SEL_MASK(gpct_index),
- NI_E_DMA_G0_G1_SEL(gpct_index, bits));
-
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- return 0;
-}
-
-static int ni_request_cdo_mite_channel(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct mite_channel *mite_chan;
- unsigned long flags;
- unsigned int bits;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- mite_chan = mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
- if (!mite_chan) {
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- dev_err(dev->class_dev,
- "failed to reserve mite dma channel for correlated digital output\n");
- return -EBUSY;
- }
- mite_chan->dir = COMEDI_OUTPUT;
- devpriv->cdo_mite_chan = mite_chan;
-
- /*
- * XXX just guessing NI_STC_DMA_CHAN_SEL()
- * returns the right bits, under the assumption the cdio dma
- * selection works just like ai/ao/gpct.
- * Definitely works for dma channels 0 and 1.
- */
- bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
- ni_set_bitfield(dev, NI_M_CDIO_DMA_SEL_REG,
- NI_M_CDIO_DMA_SEL_CDO_MASK,
- NI_M_CDIO_DMA_SEL_CDO(bits));
-
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- return 0;
-}
-#endif /* PCIDMA */
-
-static void ni_release_ai_mite_channel(struct comedi_device *dev)
-{
-#ifdef PCIDMA
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ai_mite_chan) {
- ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
- NI_E_DMA_AI_SEL_MASK, 0);
- mite_release_channel(devpriv->ai_mite_chan);
- devpriv->ai_mite_chan = NULL;
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-#endif /* PCIDMA */
-}
-
-static void ni_release_ao_mite_channel(struct comedi_device *dev)
-{
-#ifdef PCIDMA
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ao_mite_chan) {
- ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
- NI_E_DMA_AO_SEL_MASK, 0);
- mite_release_channel(devpriv->ao_mite_chan);
- devpriv->ao_mite_chan = NULL;
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-#endif /* PCIDMA */
-}
-
-#ifdef PCIDMA
-static void ni_release_gpct_mite_channel(struct comedi_device *dev,
- unsigned int gpct_index)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->counter_dev->counters[gpct_index].mite_chan) {
- struct mite_channel *mite_chan =
- devpriv->counter_dev->counters[gpct_index].mite_chan;
-
- ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
- NI_E_DMA_G0_G1_SEL_MASK(gpct_index), 0);
- ni_tio_set_mite_channel(&devpriv->counter_dev->counters[gpct_index],
- NULL);
- mite_release_channel(mite_chan);
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-}
-
-static void ni_release_cdo_mite_channel(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->cdo_mite_chan) {
- ni_set_bitfield(dev, NI_M_CDIO_DMA_SEL_REG,
- NI_M_CDIO_DMA_SEL_CDO_MASK, 0);
- mite_release_channel(devpriv->cdo_mite_chan);
- devpriv->cdo_mite_chan = NULL;
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-}
-
-static void ni_e_series_enable_second_irq(struct comedi_device *dev,
- unsigned int gpct_index, short enable)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int val = 0;
- int reg;
-
- if (devpriv->is_m_series || gpct_index > 1)
- return;
-
- /*
- * e-series boards use the second irq signals to generate
- * dma requests for their counters
- */
- if (gpct_index == 0) {
- reg = NISTC_INTA2_ENA_REG;
- if (enable)
- val = NISTC_INTA_ENA_G0_GATE;
- } else {
- reg = NISTC_INTB2_ENA_REG;
- if (enable)
- val = NISTC_INTB_ENA_G1_GATE;
- }
- ni_stc_writew(dev, val, reg);
-}
-#endif /* PCIDMA */
-
-static void ni_clear_ai_fifo(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- static const int timeout = 10000;
- int i;
-
- if (devpriv->is_6143) {
- /* Flush the 6143 data FIFO */
- ni_writel(dev, 0x10, NI6143_AI_FIFO_CTRL_REG);
- ni_writel(dev, 0x00, NI6143_AI_FIFO_CTRL_REG);
- /* Wait for complete */
- for (i = 0; i < timeout; i++) {
- if (!(ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x10))
- break;
- udelay(1);
- }
- if (i == timeout)
- dev_err(dev->class_dev, "FIFO flush timeout\n");
- } else {
- ni_stc_writew(dev, 1, NISTC_ADC_FIFO_CLR_REG);
- if (devpriv->is_625x) {
- ni_writeb(dev, 0, NI_M_STATIC_AI_CTRL_REG(0));
- ni_writeb(dev, 1, NI_M_STATIC_AI_CTRL_REG(0));
-#if 0
- /*
- * The NI example code does 3 convert pulses for 625x
- * boards, But that appears to be wrong in practice.
- */
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
- NISTC_AI_CMD1_REG);
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
- NISTC_AI_CMD1_REG);
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
- NISTC_AI_CMD1_REG);
-#endif
- }
- }
-}
-
-static inline void ni_ao_win_outw(struct comedi_device *dev,
- unsigned int data, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG);
- ni_writew(dev, data, NI611X_AO_WINDOW_DATA_REG);
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-}
-
-static inline void ni_ao_win_outl(struct comedi_device *dev,
- unsigned int data, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG);
- ni_writel(dev, data, NI611X_AO_WINDOW_DATA_REG);
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-}
-
-static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
- unsigned short data;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG);
- data = ni_readw(dev, NI611X_AO_WINDOW_DATA_REG);
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
- return data;
-}
-
-/*
- * ni_set_bits( ) allows different parts of the ni_mio_common driver to
- * share registers (such as Interrupt_A_Register) without interfering with
- * each other.
- *
- * NOTE: the switch/case statements are optimized out for a constant argument
- * so this is actually quite fast--- If you must wrap another function around
- * this make it inline to avoid a large speed penalty.
- *
- * value should only be 1 or 0.
- */
-static inline void ni_set_bits(struct comedi_device *dev, int reg,
- unsigned int bits, unsigned int value)
-{
- unsigned int bit_values;
-
- if (value)
- bit_values = bits;
- else
- bit_values = 0;
- ni_set_bitfield(dev, reg, bits, bit_values);
-}
-
-#ifdef PCIDMA
-static void ni_sync_ai_dma(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ai_mite_chan)
- mite_sync_dma(devpriv->ai_mite_chan, s);
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-}
-
-static int ni_ai_drain_dma(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int i;
- static const int timeout = 10000;
- unsigned long flags;
- int retval = 0;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ai_mite_chan) {
- for (i = 0; i < timeout; i++) {
- if ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_E) &&
- mite_bytes_in_transit(devpriv->ai_mite_chan) == 0)
- break;
- udelay(5);
- }
- if (i == timeout) {
- dev_err(dev->class_dev, "timed out\n");
- dev_err(dev->class_dev,
- "mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
- mite_bytes_in_transit(devpriv->ai_mite_chan),
- ni_stc_readw(dev, NISTC_AI_STATUS1_REG));
- retval = -1;
- }
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- ni_sync_ai_dma(dev);
-
- return retval;
-}
-
-static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
-{
- static const int timeout = 10000;
- int i;
-
- for (i = 0; i < timeout; i++) {
- unsigned short b_status;
-
- b_status = ni_stc_readw(dev, NISTC_AO_STATUS1_REG);
- if (b_status & NISTC_AO_STATUS1_FIFO_HF)
- break;
- /*
- * If we poll too often, the pci bus activity seems
- * to slow the dma transfer down.
- */
- usleep_range(10, 100);
- }
- if (i == timeout) {
- dev_err(dev->class_dev, "timed out waiting for dma load\n");
- return -EPIPE;
- }
- return 0;
-}
-#endif /* PCIDMA */
-
-#ifndef PCIDMA
-
-static void ni_ao_fifo_load(struct comedi_device *dev,
- struct comedi_subdevice *s, int n)
-{
- struct ni_private *devpriv = dev->private;
- int i;
- unsigned short d;
- unsigned int packed_data;
-
- for (i = 0; i < n; i++) {
- comedi_buf_read_samples(s, &d, 1);
-
- if (devpriv->is_6xxx) {
- packed_data = d & 0xffff;
- /* 6711 only has 16 bit wide ao fifo */
- if (!devpriv->is_6711) {
- comedi_buf_read_samples(s, &d, 1);
- i++;
- packed_data |= (d << 16) & 0xffff0000;
- }
- ni_writel(dev, packed_data, NI611X_AO_FIFO_DATA_REG);
- } else {
- ni_writew(dev, d, NI_E_AO_FIFO_DATA_REG);
- }
- }
-}
-
-/*
- * There's a small problem if the FIFO gets really low and we
- * don't have the data to fill it. Basically, if after we fill
- * the FIFO with all the data available, the FIFO is _still_
- * less than half full, we never clear the interrupt. If the
- * IRQ is in edge mode, we never get another interrupt, because
- * this one wasn't cleared. If in level mode, we get flooded
- * with interrupts that we can't fulfill, because nothing ever
- * gets put into the buffer.
- *
- * This kind of situation is recoverable, but it is easier to
- * just pretend we had a FIFO underrun, since there is a good
- * chance it will happen anyway. This is _not_ the case for
- * RT code, as RT code might purposely be running close to the
- * metal. Needs to be fixed eventually.
- */
-static int ni_ao_fifo_half_empty(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- unsigned int nbytes;
- unsigned int nsamples;
-
- nbytes = comedi_buf_read_n_available(s);
- if (nbytes == 0) {
- s->async->events |= COMEDI_CB_OVERFLOW;
- return 0;
- }
-
- nsamples = comedi_bytes_to_samples(s, nbytes);
- if (nsamples > board->ao_fifo_depth / 2)
- nsamples = board->ao_fifo_depth / 2;
-
- ni_ao_fifo_load(dev, s, nsamples);
-
- return 1;
-}
-
-static int ni_ao_prep_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- unsigned int nbytes;
- unsigned int nsamples;
-
- /* reset fifo */
- ni_stc_writew(dev, 1, NISTC_DAC_FIFO_CLR_REG);
- if (devpriv->is_6xxx)
- ni_ao_win_outl(dev, 0x6, NI611X_AO_FIFO_OFFSET_LOAD_REG);
-
- /* load some data */
- nbytes = comedi_buf_read_n_available(s);
- if (nbytes == 0)
- return 0;
-
- nsamples = comedi_bytes_to_samples(s, nbytes);
- if (nsamples > board->ao_fifo_depth)
- nsamples = board->ao_fifo_depth;
-
- ni_ao_fifo_load(dev, s, nsamples);
-
- return nsamples;
-}
-
-static void ni_ai_fifo_read(struct comedi_device *dev,
- struct comedi_subdevice *s, int n)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- unsigned int dl;
- unsigned short data;
- int i;
-
- if (devpriv->is_611x) {
- for (i = 0; i < n / 2; i++) {
- dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
- /* This may get the hi/lo data in the wrong order */
- data = (dl >> 16) & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- data = dl & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
- /* Check if there's a single sample stuck in the FIFO */
- if (n % 2) {
- dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
- data = dl & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
- } else if (devpriv->is_6143) {
- /*
- * This just reads the FIFO assuming the data is present,
- * no checks on the FIFO status are performed.
- */
- for (i = 0; i < n / 2; i++) {
- dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
-
- data = (dl >> 16) & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- data = dl & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
- if (n % 2) {
- /* Assume there is a single sample stuck in the FIFO */
- /* Get stranded sample into FIFO */
- ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG);
- dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
- data = (dl >> 16) & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
- } else {
- if (n > ARRAY_SIZE(devpriv->ai_fifo_buffer)) {
- dev_err(dev->class_dev,
- "bug! ai_fifo_buffer too small\n");
- async->events |= COMEDI_CB_ERROR;
- return;
- }
- for (i = 0; i < n; i++) {
- devpriv->ai_fifo_buffer[i] =
- ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
- }
- comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, n);
- }
-}
-
-static void ni_handle_fifo_half_full(struct comedi_device *dev)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct comedi_subdevice *s = dev->read_subdev;
- int n;
-
- n = board->ai_fifo_depth / 2;
-
- ni_ai_fifo_read(dev, s, n);
-}
-#endif
-
-/* Empties the AI fifo */
-static void ni_handle_fifo_dregs(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int dl;
- unsigned short data;
- int i;
-
- if (devpriv->is_611x) {
- while ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_E) == 0) {
- dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
-
- /* This may get the hi/lo data in the wrong order */
- data = dl >> 16;
- comedi_buf_write_samples(s, &data, 1);
- data = dl & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
- } else if (devpriv->is_6143) {
- i = 0;
- while (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x04) {
- dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
-
- /* This may get the hi/lo data in the wrong order */
- data = dl >> 16;
- comedi_buf_write_samples(s, &data, 1);
- data = dl & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- i += 2;
- }
- /* Check if stranded sample is present */
- if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x01) {
- /* Get stranded sample into FIFO */
- ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG);
- dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
- data = (dl >> 16) & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
-
- } else {
- unsigned short fe; /* fifo empty */
-
- fe = ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_E;
- while (fe == 0) {
- for (i = 0;
- i < ARRAY_SIZE(devpriv->ai_fifo_buffer); i++) {
- fe = ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_E;
- if (fe)
- break;
- devpriv->ai_fifo_buffer[i] =
- ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
- }
- comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, i);
- }
- }
-}
-
-static void get_last_sample_611x(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned short data;
- unsigned int dl;
-
- if (!devpriv->is_611x)
- return;
-
- /* Check if there's a single sample stuck in the FIFO */
- if (ni_readb(dev, NI_E_STATUS_REG) & 0x80) {
- dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
- data = dl & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
-}
-
-static void get_last_sample_6143(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned short data;
- unsigned int dl;
-
- if (!devpriv->is_6143)
- return;
-
- /* Check if there's a single sample stuck in the FIFO */
- if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x01) {
- /* Get stranded sample into FIFO */
- ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG);
- dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
-
- /* This may get the hi/lo data in the wrong order */
- data = (dl >> 16) & 0xffff;
- comedi_buf_write_samples(s, &data, 1);
- }
-}
-
-static void shutdown_ai_command(struct comedi_device *dev)
-{
- struct comedi_subdevice *s = dev->read_subdev;
-
-#ifdef PCIDMA
- ni_ai_drain_dma(dev);
-#endif
- ni_handle_fifo_dregs(dev);
- get_last_sample_611x(dev);
- get_last_sample_6143(dev);
-
- s->async->events |= COMEDI_CB_EOA;
-}
-
-static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->aimode == AIMODE_SCAN) {
-#ifdef PCIDMA
- static const int timeout = 10;
- int i;
-
- for (i = 0; i < timeout; i++) {
- ni_sync_ai_dma(dev);
- if ((s->async->events & COMEDI_CB_EOS))
- break;
- udelay(1);
- }
-#else
- ni_handle_fifo_dregs(dev);
- s->async->events |= COMEDI_CB_EOS;
-#endif
- }
- /* handle special case of single scan */
- if (devpriv->ai_cmd2 & NISTC_AI_CMD2_END_ON_EOS)
- shutdown_ai_command(dev);
-}
-
-static void handle_gpct_interrupt(struct comedi_device *dev,
- unsigned short counter_index)
-{
-#ifdef PCIDMA
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s;
-
- s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)];
-
- ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
- s);
- comedi_handle_events(dev, s);
-#endif
-}
-
-static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
-{
- unsigned short ack = 0;
-
- if (a_status & NISTC_AI_STATUS1_SC_TC)
- ack |= NISTC_INTA_ACK_AI_SC_TC;
- if (a_status & NISTC_AI_STATUS1_START1)
- ack |= NISTC_INTA_ACK_AI_START1;
- if (a_status & NISTC_AI_STATUS1_START)
- ack |= NISTC_INTA_ACK_AI_START;
- if (a_status & NISTC_AI_STATUS1_STOP)
- ack |= NISTC_INTA_ACK_AI_STOP;
- if (a_status & NISTC_AI_STATUS1_OVER)
- ack |= NISTC_INTA_ACK_AI_ERR;
- if (ack)
- ni_stc_writew(dev, ack, NISTC_INTA_ACK_REG);
-}
-
-static void handle_a_interrupt(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned short status)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- /* test for all uncommon interrupt events at the same time */
- if (status & (NISTC_AI_STATUS1_ERR |
- NISTC_AI_STATUS1_SC_TC | NISTC_AI_STATUS1_START1)) {
- if (status == 0xffff) {
- dev_err(dev->class_dev, "Card removed?\n");
- /*
- * We probably aren't even running a command now,
- * so it's a good idea to be careful.
- */
- if (comedi_is_subdevice_running(s))
- s->async->events |= COMEDI_CB_ERROR;
- return;
- }
- if (status & NISTC_AI_STATUS1_ERR) {
- dev_err(dev->class_dev, "ai error a_status=%04x\n",
- status);
-
- shutdown_ai_command(dev);
-
- s->async->events |= COMEDI_CB_ERROR;
- if (status & NISTC_AI_STATUS1_OVER)
- s->async->events |= COMEDI_CB_OVERFLOW;
- return;
- }
- if (status & NISTC_AI_STATUS1_SC_TC) {
- if (cmd->stop_src == TRIG_COUNT)
- shutdown_ai_command(dev);
- }
- }
-#ifndef PCIDMA
- if (status & NISTC_AI_STATUS1_FIFO_HF) {
- int i;
- static const int timeout = 10;
- /*
- * PCMCIA cards (at least 6036) seem to stop producing
- * interrupts if we fail to get the fifo less than half
- * full, so loop to be sure.
- */
- for (i = 0; i < timeout; ++i) {
- ni_handle_fifo_half_full(dev);
- if ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_HF) == 0)
- break;
- }
- }
-#endif /* !PCIDMA */
-
- if (status & NISTC_AI_STATUS1_STOP)
- ni_handle_eos(dev, s);
-}
-
-static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
-{
- unsigned short ack = 0;
-
- if (b_status & NISTC_AO_STATUS1_BC_TC)
- ack |= NISTC_INTB_ACK_AO_BC_TC;
- if (b_status & NISTC_AO_STATUS1_OVERRUN)
- ack |= NISTC_INTB_ACK_AO_ERR;
- if (b_status & NISTC_AO_STATUS1_START)
- ack |= NISTC_INTB_ACK_AO_START;
- if (b_status & NISTC_AO_STATUS1_START1)
- ack |= NISTC_INTB_ACK_AO_START1;
- if (b_status & NISTC_AO_STATUS1_UC_TC)
- ack |= NISTC_INTB_ACK_AO_UC_TC;
- if (b_status & NISTC_AO_STATUS1_UI2_TC)
- ack |= NISTC_INTB_ACK_AO_UI2_TC;
- if (b_status & NISTC_AO_STATUS1_UPDATE)
- ack |= NISTC_INTB_ACK_AO_UPDATE;
- if (ack)
- ni_stc_writew(dev, ack, NISTC_INTB_ACK_REG);
-}
-
-static void handle_b_interrupt(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned short b_status)
-{
- if (b_status == 0xffff)
- return;
- if (b_status & NISTC_AO_STATUS1_OVERRUN) {
- dev_err(dev->class_dev,
- "AO FIFO underrun status=0x%04x status2=0x%04x\n",
- b_status, ni_stc_readw(dev, NISTC_AO_STATUS2_REG));
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
-
- if (s->async->cmd.stop_src != TRIG_NONE &&
- b_status & NISTC_AO_STATUS1_BC_TC)
- s->async->events |= COMEDI_CB_EOA;
-
-#ifndef PCIDMA
- if (b_status & NISTC_AO_STATUS1_FIFO_REQ) {
- int ret;
-
- ret = ni_ao_fifo_half_empty(dev, s);
- if (!ret) {
- dev_err(dev->class_dev, "AO buffer underrun\n");
- ni_set_bits(dev, NISTC_INTB_ENA_REG,
- NISTC_INTB_ENA_AO_FIFO |
- NISTC_INTB_ENA_AO_ERR, 0);
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
- }
-#endif
-}
-
-static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
- void *data, unsigned int num_bytes,
- unsigned int chan_index)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes);
- unsigned short *array = data;
- unsigned int *larray = data;
- unsigned int i;
-#ifdef PCIDMA
- __le16 *barray = data;
- __le32 *blarray = data;
-#endif
-
- for (i = 0; i < nsamples; i++) {
-#ifdef PCIDMA
- if (s->subdev_flags & SDF_LSAMPL)
- larray[i] = le32_to_cpu(blarray[i]);
- else
- array[i] = le16_to_cpu(barray[i]);
-#endif
- if (s->subdev_flags & SDF_LSAMPL)
- larray[i] += devpriv->ai_offset[chan_index];
- else
- array[i] += devpriv->ai_offset[chan_index];
- chan_index++;
- chan_index %= cmd->chanlist_len;
- }
-}
-
-#ifdef PCIDMA
-
-static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- int retval;
- unsigned long flags;
-
- retval = ni_request_ai_mite_channel(dev);
- if (retval)
- return retval;
-
- /* write alloc the entire buffer */
- comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (!devpriv->ai_mite_chan) {
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- return -EIO;
- }
-
- if (devpriv->is_611x || devpriv->is_6143)
- mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
- else if (devpriv->is_628x)
- mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
- else
- mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
-
- /*start the MITE */
- mite_dma_arm(devpriv->ai_mite_chan);
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- return 0;
-}
-
-static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- int retval;
- unsigned long flags;
-
- retval = ni_request_ao_mite_channel(dev);
- if (retval)
- return retval;
-
- /* read alloc the entire buffer */
- comedi_buf_read_alloc(s, s->async->prealloc_bufsz);
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ao_mite_chan) {
- if (devpriv->is_611x || devpriv->is_6713) {
- mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
- } else {
- /*
- * Doing 32 instead of 16 bit wide transfers from
- * memory makes the mite do 32 bit pci transfers,
- * doubling pci bandwidth.
- */
- mite_prep_dma(devpriv->ao_mite_chan, 16, 32);
- }
- mite_dma_arm(devpriv->ao_mite_chan);
- } else {
- retval = -EIO;
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- return retval;
-}
-
-#endif /* PCIDMA */
-
-/*
- * used for both cancel ioctl and board initialization
- *
- * this is pretty harsh for a cancel, but it works...
- */
-static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int ai_personal;
- unsigned int ai_out_ctrl;
-
- ni_release_ai_mite_channel(dev);
- /* ai configuration */
- ni_stc_writew(dev, NISTC_RESET_AI_CFG_START | NISTC_RESET_AI,
- NISTC_RESET_REG);
-
- ni_set_bits(dev, NISTC_INTA_ENA_REG, NISTC_INTA_ENA_AI_MASK, 0);
-
- ni_clear_ai_fifo(dev);
-
- if (!devpriv->is_6143)
- ni_writeb(dev, NI_E_MISC_CMD_EXT_ATRIG, NI_E_MISC_CMD_REG);
-
- ni_stc_writew(dev, NISTC_AI_CMD1_DISARM, NISTC_AI_CMD1_REG);
- ni_stc_writew(dev, NISTC_AI_MODE1_START_STOP |
- NISTC_AI_MODE1_RSVD
- /*| NISTC_AI_MODE1_TRIGGER_ONCE */,
- NISTC_AI_MODE1_REG);
- ni_stc_writew(dev, 0, NISTC_AI_MODE2_REG);
- /* generate FIFO interrupts on non-empty */
- ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE,
- NISTC_AI_MODE3_REG);
-
- ai_personal = NISTC_AI_PERSONAL_SHIFTIN_PW |
- NISTC_AI_PERSONAL_SOC_POLARITY |
- NISTC_AI_PERSONAL_LOCALMUX_CLK_PW;
- ai_out_ctrl = NISTC_AI_OUT_CTRL_SCAN_IN_PROG_SEL(3) |
- NISTC_AI_OUT_CTRL_EXTMUX_CLK_SEL(0) |
- NISTC_AI_OUT_CTRL_LOCALMUX_CLK_SEL(2) |
- NISTC_AI_OUT_CTRL_SC_TC_SEL(3);
- if (devpriv->is_611x) {
- ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_HIGH;
- } else if (devpriv->is_6143) {
- ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_LOW;
- } else {
- ai_personal |= NISTC_AI_PERSONAL_CONVERT_PW;
- if (devpriv->is_622x)
- ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_HIGH;
- else
- ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_LOW;
- }
- ni_stc_writew(dev, ai_personal, NISTC_AI_PERSONAL_REG);
- ni_stc_writew(dev, ai_out_ctrl, NISTC_AI_OUT_CTRL_REG);
-
- /* the following registers should not be changed, because there
- * are no backup registers in devpriv. If you want to change
- * any of these, add a backup register and other appropriate code:
- * NISTC_AI_MODE1_REG
- * NISTC_AI_MODE3_REG
- * NISTC_AI_PERSONAL_REG
- * NISTC_AI_OUT_CTRL_REG
- */
-
- /* clear interrupts */
- ni_stc_writew(dev, NISTC_INTA_ACK_AI_ALL, NISTC_INTA_ACK_REG);
-
- ni_stc_writew(dev, NISTC_RESET_AI_CFG_END, NISTC_RESET_REG);
-
- return 0;
-}
-
-static int ni_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- unsigned long flags;
- int count;
-
- /* lock to avoid race with interrupt handler */
- spin_lock_irqsave(&dev->spinlock, flags);
-#ifndef PCIDMA
- ni_handle_fifo_dregs(dev);
-#else
- ni_sync_ai_dma(dev);
-#endif
- count = comedi_buf_n_bytes_ready(s);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return count;
-}
-
-static void ni_prime_channelgain_list(struct comedi_device *dev)
-{
- int i;
-
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, NISTC_AI_CMD1_REG);
- for (i = 0; i < NI_TIMEOUT; ++i) {
- if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_E)) {
- ni_stc_writew(dev, 1, NISTC_ADC_FIFO_CLR_REG);
- return;
- }
- udelay(1);
- }
- dev_err(dev->class_dev, "timeout loading channel/gain list\n");
-}
-
-static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
- unsigned int n_chan,
- unsigned int *list)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- unsigned int chan, range, aref;
- unsigned int i;
- unsigned int dither;
- unsigned int range_code;
-
- ni_stc_writew(dev, 1, NISTC_CFG_MEM_CLR_REG);
-
- if ((list[0] & CR_ALT_SOURCE)) {
- unsigned int bypass_bits;
-
- chan = CR_CHAN(list[0]);
- range = CR_RANGE(list[0]);
- range_code = ni_gainlkup[board->gainlkup][range];
- dither = (list[0] & CR_ALT_FILTER) != 0;
- bypass_bits = NI_M_CFG_BYPASS_FIFO |
- NI_M_CFG_BYPASS_AI_CHAN(chan) |
- NI_M_CFG_BYPASS_AI_GAIN(range_code) |
- devpriv->ai_calib_source;
- if (dither)
- bypass_bits |= NI_M_CFG_BYPASS_AI_DITHER;
- /* don't use 2's complement encoding */
- bypass_bits |= NI_M_CFG_BYPASS_AI_POLARITY;
- ni_writel(dev, bypass_bits, NI_M_CFG_BYPASS_FIFO_REG);
- } else {
- ni_writel(dev, 0, NI_M_CFG_BYPASS_FIFO_REG);
- }
- for (i = 0; i < n_chan; i++) {
- unsigned int config_bits = 0;
-
- chan = CR_CHAN(list[i]);
- aref = CR_AREF(list[i]);
- range = CR_RANGE(list[i]);
- dither = (list[i] & CR_ALT_FILTER) != 0;
-
- range_code = ni_gainlkup[board->gainlkup][range];
- devpriv->ai_offset[i] = 0;
- switch (aref) {
- case AREF_DIFF:
- config_bits |= NI_M_AI_CFG_CHAN_TYPE_DIFF;
- break;
- case AREF_COMMON:
- config_bits |= NI_M_AI_CFG_CHAN_TYPE_COMMON;
- break;
- case AREF_GROUND:
- config_bits |= NI_M_AI_CFG_CHAN_TYPE_GROUND;
- break;
- case AREF_OTHER:
- break;
- }
- config_bits |= NI_M_AI_CFG_CHAN_SEL(chan);
- config_bits |= NI_M_AI_CFG_BANK_SEL(chan);
- config_bits |= NI_M_AI_CFG_GAIN(range_code);
- if (i == n_chan - 1)
- config_bits |= NI_M_AI_CFG_LAST_CHAN;
- if (dither)
- config_bits |= NI_M_AI_CFG_DITHER;
- /* don't use 2's complement encoding */
- config_bits |= NI_M_AI_CFG_POLARITY;
- ni_writew(dev, config_bits, NI_M_AI_CFG_FIFO_DATA_REG);
- }
- ni_prime_channelgain_list(dev);
-}
-
-/*
- * Notes on the 6110 and 6111:
- * These boards a slightly different than the rest of the series, since
- * they have multiple A/D converters.
- * From the driver side, the configuration memory is a
- * little different.
- * Configuration Memory Low:
- * bits 15-9: same
- * bit 8: unipolar/bipolar (should be 0 for bipolar)
- * bits 0-3: gain. This is 4 bits instead of 3 for the other boards
- * 1001 gain=0.1 (+/- 50)
- * 1010 0.2
- * 1011 0.1
- * 0001 1
- * 0010 2
- * 0011 5
- * 0100 10
- * 0101 20
- * 0110 50
- * Configuration Memory High:
- * bits 12-14: Channel Type
- * 001 for differential
- * 000 for calibration
- * bit 11: coupling (this is not currently handled)
- * 1 AC coupling
- * 0 DC coupling
- * bits 0-2: channel
- * valid channels are 0-3
- */
-static void ni_load_channelgain_list(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int n_chan, unsigned int *list)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- unsigned int offset = (s->maxdata + 1) >> 1;
- unsigned int chan, range, aref;
- unsigned int i;
- unsigned int hi, lo;
- unsigned int dither;
-
- if (devpriv->is_m_series) {
- ni_m_series_load_channelgain_list(dev, n_chan, list);
- return;
- }
- if (n_chan == 1 && !devpriv->is_611x && !devpriv->is_6143) {
- if (devpriv->changain_state &&
- devpriv->changain_spec == list[0]) {
- /* ready to go. */
- return;
- }
- devpriv->changain_state = 1;
- devpriv->changain_spec = list[0];
- } else {
- devpriv->changain_state = 0;
- }
-
- ni_stc_writew(dev, 1, NISTC_CFG_MEM_CLR_REG);
-
- /* Set up Calibration mode if required */
- if (devpriv->is_6143) {
- if ((list[0] & CR_ALT_SOURCE) &&
- !devpriv->ai_calib_source_enabled) {
- /* Strobe Relay enable bit */
- ni_writew(dev, devpriv->ai_calib_source |
- NI6143_CALIB_CHAN_RELAY_ON,
- NI6143_CALIB_CHAN_REG);
- ni_writew(dev, devpriv->ai_calib_source,
- NI6143_CALIB_CHAN_REG);
- devpriv->ai_calib_source_enabled = 1;
- /* Allow relays to change */
- msleep_interruptible(100);
- } else if (!(list[0] & CR_ALT_SOURCE) &&
- devpriv->ai_calib_source_enabled) {
- /* Strobe Relay disable bit */
- ni_writew(dev, devpriv->ai_calib_source |
- NI6143_CALIB_CHAN_RELAY_OFF,
- NI6143_CALIB_CHAN_REG);
- ni_writew(dev, devpriv->ai_calib_source,
- NI6143_CALIB_CHAN_REG);
- devpriv->ai_calib_source_enabled = 0;
- /* Allow relays to change */
- msleep_interruptible(100);
- }
- }
-
- for (i = 0; i < n_chan; i++) {
- if (!devpriv->is_6143 && (list[i] & CR_ALT_SOURCE))
- chan = devpriv->ai_calib_source;
- else
- chan = CR_CHAN(list[i]);
- aref = CR_AREF(list[i]);
- range = CR_RANGE(list[i]);
- dither = (list[i] & CR_ALT_FILTER) != 0;
-
- /* fix the external/internal range differences */
- range = ni_gainlkup[board->gainlkup][range];
- if (devpriv->is_611x)
- devpriv->ai_offset[i] = offset;
- else
- devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
-
- hi = 0;
- if ((list[i] & CR_ALT_SOURCE)) {
- if (devpriv->is_611x)
- ni_writew(dev, CR_CHAN(list[i]) & 0x0003,
- NI611X_CALIB_CHAN_SEL_REG);
- } else {
- if (devpriv->is_611x)
- aref = AREF_DIFF;
- else if (devpriv->is_6143)
- aref = AREF_OTHER;
- switch (aref) {
- case AREF_DIFF:
- hi |= NI_E_AI_CFG_HI_TYPE_DIFF;
- break;
- case AREF_COMMON:
- hi |= NI_E_AI_CFG_HI_TYPE_COMMON;
- break;
- case AREF_GROUND:
- hi |= NI_E_AI_CFG_HI_TYPE_GROUND;
- break;
- case AREF_OTHER:
- break;
- }
- }
- hi |= NI_E_AI_CFG_HI_CHAN(chan);
-
- ni_writew(dev, hi, NI_E_AI_CFG_HI_REG);
-
- if (!devpriv->is_6143) {
- lo = NI_E_AI_CFG_LO_GAIN(range);
-
- if (i == n_chan - 1)
- lo |= NI_E_AI_CFG_LO_LAST_CHAN;
- if (dither)
- lo |= NI_E_AI_CFG_LO_DITHER;
-
- ni_writew(dev, lo, NI_E_AI_CFG_LO_REG);
- }
- }
-
- /* prime the channel/gain list */
- if (!devpriv->is_611x && !devpriv->is_6143)
- ni_prime_channelgain_list(dev);
-}
-
-static int ni_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int mask = s->maxdata;
- int i, n;
- unsigned int signbits;
- unsigned int d;
-
- ni_load_channelgain_list(dev, s, 1, &insn->chanspec);
-
- ni_clear_ai_fifo(dev);
-
- signbits = devpriv->ai_offset[0];
- if (devpriv->is_611x) {
- for (n = 0; n < num_adc_stages_611x; n++) {
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
- NISTC_AI_CMD1_REG);
- udelay(1);
- }
- for (n = 0; n < insn->n; n++) {
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
- NISTC_AI_CMD1_REG);
- /* The 611x has screwy 32-bit FIFOs. */
- d = 0;
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (ni_readb(dev, NI_E_STATUS_REG) & 0x80) {
- d = ni_readl(dev,
- NI611X_AI_FIFO_DATA_REG);
- d >>= 16;
- d &= 0xffff;
- break;
- }
- if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_E)) {
- d = ni_readl(dev,
- NI611X_AI_FIFO_DATA_REG);
- d &= 0xffff;
- break;
- }
- }
- if (i == NI_TIMEOUT) {
- dev_err(dev->class_dev, "timeout\n");
- return -ETIME;
- }
- d += signbits;
- data[n] = d & 0xffff;
- }
- } else if (devpriv->is_6143) {
- for (n = 0; n < insn->n; n++) {
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
- NISTC_AI_CMD1_REG);
-
- /*
- * The 6143 has 32-bit FIFOs. You need to strobe a
- * bit to move a single 16bit stranded sample into
- * the FIFO.
- */
- d = 0;
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) &
- 0x01) {
- /* Get stranded sample into FIFO */
- ni_writel(dev, 0x01,
- NI6143_AI_FIFO_CTRL_REG);
- d = ni_readl(dev,
- NI6143_AI_FIFO_DATA_REG);
- break;
- }
- }
- if (i == NI_TIMEOUT) {
- dev_err(dev->class_dev, "timeout\n");
- return -ETIME;
- }
- data[n] = (((d >> 16) & 0xFFFF) + signbits) & 0xFFFF;
- }
- } else {
- for (n = 0; n < insn->n; n++) {
- ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
- NISTC_AI_CMD1_REG);
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
- NISTC_AI_STATUS1_FIFO_E))
- break;
- }
- if (i == NI_TIMEOUT) {
- dev_err(dev->class_dev, "timeout\n");
- return -ETIME;
- }
- if (devpriv->is_m_series) {
- d = ni_readl(dev, NI_M_AI_FIFO_DATA_REG);
- d &= mask;
- data[n] = d;
- } else {
- d = ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
- d += signbits;
- data[n] = d & 0xffff;
- }
- }
- }
- return insn->n;
-}
-
-static int ni_ns_to_timer(const struct comedi_device *dev,
- unsigned int nanosec, unsigned int flags)
-{
- struct ni_private *devpriv = dev->private;
- int divider;
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- divider = DIV_ROUND_CLOSEST(nanosec, devpriv->clock_ns);
- break;
- case CMDF_ROUND_DOWN:
- divider = (nanosec) / devpriv->clock_ns;
- break;
- case CMDF_ROUND_UP:
- divider = DIV_ROUND_UP(nanosec, devpriv->clock_ns);
- break;
- }
- return divider - 1;
-}
-
-static unsigned int ni_timer_to_ns(const struct comedi_device *dev, int timer)
-{
- struct ni_private *devpriv = dev->private;
-
- return devpriv->clock_ns * (timer + 1);
-}
-
-static void ni_cmd_set_mite_transfer(struct mite_ring *ring,
- struct comedi_subdevice *sdev,
- const struct comedi_cmd *cmd,
- unsigned int max_count)
-{
-#ifdef PCIDMA
- unsigned int nbytes = max_count;
-
- if (cmd->stop_arg > 0 && cmd->stop_arg < max_count)
- nbytes = cmd->stop_arg;
- nbytes *= comedi_bytes_per_scan(sdev);
-
- if (nbytes > sdev->async->prealloc_bufsz) {
- if (cmd->stop_arg > 0)
- dev_err(sdev->device->class_dev,
- "%s: tried exact data transfer limits greater than buffer size\n",
- __func__);
-
- /*
- * we can only transfer up to the size of the buffer. In this
- * case, the user is expected to continue to write into the
- * comedi buffer (already implemented as a ring buffer).
- */
- nbytes = sdev->async->prealloc_bufsz;
- }
-
- mite_init_ring_descriptors(ring, sdev, nbytes);
-#else
- dev_err(sdev->device->class_dev,
- "%s: exact data transfer limits not implemented yet without DMA\n",
- __func__);
-#endif
-}
-
-static unsigned int ni_min_ai_scan_period_ns(struct comedi_device *dev,
- unsigned int num_channels)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
-
- /* simultaneously-sampled inputs */
- if (devpriv->is_611x || devpriv->is_6143)
- return board->ai_speed;
-
- /* multiplexed inputs */
- return board->ai_speed * num_channels;
-}
-
-static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- int err = 0;
- unsigned int sources;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src,
- TRIG_NOW | TRIG_INT | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
-
- sources = TRIG_TIMER | TRIG_EXT;
- if (devpriv->is_611x || devpriv->is_6143)
- sources |= TRIG_NOW;
- err |= comedi_check_trigger_src(&cmd->convert_src, sources);
-
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- case TRIG_INT:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->start_arg),
- NI_AI_StartTrigger,
- &devpriv->routing_tables, 1);
- break;
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- ni_min_ai_scan_period_ns(dev, cmd->chanlist_len));
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- devpriv->clock_ns *
- 0xffffff);
- } else if (cmd->scan_begin_src == TRIG_EXT) {
- /* external trigger */
- err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->scan_begin_arg),
- NI_AI_SampleClock,
- &devpriv->routing_tables, 1);
- } else { /* TRIG_OTHER */
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- if (devpriv->is_611x || devpriv->is_6143) {
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg,
- 0);
- } else {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_speed);
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
- devpriv->clock_ns *
- 0xffff);
- }
- } else if (cmd->convert_src == TRIG_EXT) {
- /* external trigger */
- err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->convert_arg),
- NI_AI_ConvertClock,
- &devpriv->routing_tables, 1);
- } else if (cmd->convert_src == TRIG_NOW) {
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT) {
- unsigned int max_count = 0x01000000;
-
- if (devpriv->is_611x)
- max_count -= num_adc_stages_611x;
- err |= comedi_check_trigger_arg_max(&cmd->stop_arg, max_count);
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- } else {
- /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
- }
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- unsigned int tmp = cmd->scan_begin_arg;
-
- cmd->scan_begin_arg =
- ni_timer_to_ns(dev, ni_ns_to_timer(dev,
- cmd->scan_begin_arg,
- cmd->flags));
- if (tmp != cmd->scan_begin_arg)
- err++;
- }
- if (cmd->convert_src == TRIG_TIMER) {
- if (!devpriv->is_611x && !devpriv->is_6143) {
- unsigned int tmp = cmd->convert_arg;
-
- cmd->convert_arg =
- ni_timer_to_ns(dev, ni_ns_to_timer(dev,
- cmd->convert_arg,
- cmd->flags));
- if (tmp != cmd->convert_arg)
- err++;
- if (cmd->scan_begin_src == TRIG_TIMER &&
- cmd->scan_begin_arg <
- cmd->convert_arg * cmd->scan_end_arg) {
- cmd->scan_begin_arg =
- cmd->convert_arg * cmd->scan_end_arg;
- err++;
- }
- }
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int ni_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- ni_stc_writew(dev, NISTC_AI_CMD2_START1_PULSE | devpriv->ai_cmd2,
- NISTC_AI_CMD2_REG);
- s->async->inttrig = NULL;
-
- return 1;
-}
-
-static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- const struct comedi_cmd *cmd = &s->async->cmd;
- int timer;
- int mode1 = 0; /* mode1 is needed for both stop and convert */
- int mode2 = 0;
- int start_stop_select = 0;
- unsigned int stop_count;
- int interrupt_a_enable = 0;
- unsigned int ai_trig;
-
- if (dev->irq == 0) {
- dev_err(dev->class_dev, "cannot run command without an irq\n");
- return -EIO;
- }
- ni_clear_ai_fifo(dev);
-
- ni_load_channelgain_list(dev, s, cmd->chanlist_len, cmd->chanlist);
-
- /* start configuration */
- ni_stc_writew(dev, NISTC_RESET_AI_CFG_START, NISTC_RESET_REG);
-
- /*
- * Disable analog triggering for now, since it interferes
- * with the use of pfi0.
- */
- devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_ENA;
- ni_stc_writew(dev, devpriv->an_trig_etc_reg, NISTC_ATRIG_ETC_REG);
-
- ai_trig = NISTC_AI_TRIG_START2_SEL(0) | NISTC_AI_TRIG_START1_SYNC;
- switch (cmd->start_src) {
- case TRIG_INT:
- case TRIG_NOW:
- ai_trig |= NISTC_AI_TRIG_START1_EDGE |
- NISTC_AI_TRIG_START1_SEL(0);
- break;
- case TRIG_EXT:
- ai_trig |= NISTC_AI_TRIG_START1_SEL(
- ni_get_reg_value_roffs(
- CR_CHAN(cmd->start_arg),
- NI_AI_StartTrigger,
- &devpriv->routing_tables, 1));
-
- if (cmd->start_arg & CR_INVERT)
- ai_trig |= NISTC_AI_TRIG_START1_POLARITY;
- if (cmd->start_arg & CR_EDGE)
- ai_trig |= NISTC_AI_TRIG_START1_EDGE;
- break;
- }
- ni_stc_writew(dev, ai_trig, NISTC_AI_TRIG_SEL_REG);
-
- mode2 &= ~NISTC_AI_MODE2_PRE_TRIGGER;
- mode2 &= ~NISTC_AI_MODE2_SC_INIT_LOAD_SRC;
- mode2 &= ~NISTC_AI_MODE2_SC_RELOAD_MODE;
- ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
-
- if (cmd->chanlist_len == 1 || devpriv->is_611x || devpriv->is_6143) {
- /* logic low */
- start_stop_select |= NISTC_AI_STOP_POLARITY |
- NISTC_AI_STOP_SEL(31) |
- NISTC_AI_STOP_SYNC;
- } else {
- /* ai configuration memory */
- start_stop_select |= NISTC_AI_STOP_SEL(19);
- }
- ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG);
-
- devpriv->ai_cmd2 = 0;
- switch (cmd->stop_src) {
- case TRIG_COUNT:
- stop_count = cmd->stop_arg - 1;
-
- if (devpriv->is_611x) {
- /* have to take 3 stage adc pipeline into account */
- stop_count += num_adc_stages_611x;
- }
- /* stage number of scans */
- ni_stc_writel(dev, stop_count, NISTC_AI_SC_LOADA_REG);
-
- mode1 |= NISTC_AI_MODE1_START_STOP |
- NISTC_AI_MODE1_RSVD |
- NISTC_AI_MODE1_TRIGGER_ONCE;
- ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG);
- /* load SC (Scan Count) */
- ni_stc_writew(dev, NISTC_AI_CMD1_SC_LOAD, NISTC_AI_CMD1_REG);
-
- if (stop_count == 0) {
- devpriv->ai_cmd2 |= NISTC_AI_CMD2_END_ON_EOS;
- interrupt_a_enable |= NISTC_INTA_ENA_AI_STOP;
- /*
- * This is required to get the last sample for
- * chanlist_len > 1, not sure why.
- */
- if (cmd->chanlist_len > 1)
- start_stop_select |= NISTC_AI_STOP_POLARITY |
- NISTC_AI_STOP_EDGE;
- }
- break;
- case TRIG_NONE:
- /* stage number of scans */
- ni_stc_writel(dev, 0, NISTC_AI_SC_LOADA_REG);
-
- mode1 |= NISTC_AI_MODE1_START_STOP |
- NISTC_AI_MODE1_RSVD |
- NISTC_AI_MODE1_CONTINUOUS;
- ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG);
-
- /* load SC (Scan Count) */
- ni_stc_writew(dev, NISTC_AI_CMD1_SC_LOAD, NISTC_AI_CMD1_REG);
- break;
- }
-
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- /*
- * stop bits for non 611x boards
- * NISTC_AI_MODE3_SI_TRIG_DELAY=0
- * NISTC_AI_MODE2_PRE_TRIGGER=0
- * NISTC_AI_START_STOP_REG:
- * NISTC_AI_START_POLARITY=0 (?) rising edge
- * NISTC_AI_START_EDGE=1 edge triggered
- * NISTC_AI_START_SYNC=1 (?)
- * NISTC_AI_START_SEL=0 SI_TC
- * NISTC_AI_STOP_POLARITY=0 rising edge
- * NISTC_AI_STOP_EDGE=0 level
- * NISTC_AI_STOP_SYNC=1
- * NISTC_AI_STOP_SEL=19 external pin (configuration mem)
- */
- start_stop_select |= NISTC_AI_START_EDGE | NISTC_AI_START_SYNC;
- ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG);
-
- mode2 &= ~NISTC_AI_MODE2_SI_INIT_LOAD_SRC; /* A */
- mode2 |= NISTC_AI_MODE2_SI_RELOAD_MODE(0);
- /* mode2 |= NISTC_AI_MODE2_SC_RELOAD_MODE; */
- ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
-
- /* load SI */
- timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
- CMDF_ROUND_NEAREST);
- ni_stc_writel(dev, timer, NISTC_AI_SI_LOADA_REG);
- ni_stc_writew(dev, NISTC_AI_CMD1_SI_LOAD, NISTC_AI_CMD1_REG);
- break;
- case TRIG_EXT:
- if (cmd->scan_begin_arg & CR_EDGE)
- start_stop_select |= NISTC_AI_START_EDGE;
- if (cmd->scan_begin_arg & CR_INVERT) /* falling edge */
- start_stop_select |= NISTC_AI_START_POLARITY;
- if (cmd->scan_begin_src != cmd->convert_src ||
- (cmd->scan_begin_arg & ~CR_EDGE) !=
- (cmd->convert_arg & ~CR_EDGE))
- start_stop_select |= NISTC_AI_START_SYNC;
-
- start_stop_select |= NISTC_AI_START_SEL(
- ni_get_reg_value_roffs(
- CR_CHAN(cmd->scan_begin_arg),
- NI_AI_SampleClock,
- &devpriv->routing_tables, 1));
- ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG);
- break;
- }
-
- switch (cmd->convert_src) {
- case TRIG_TIMER:
- case TRIG_NOW:
- if (cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW)
- timer = 1;
- else
- timer = ni_ns_to_timer(dev, cmd->convert_arg,
- CMDF_ROUND_NEAREST);
- /* 0,0 does not work */
- ni_stc_writew(dev, 1, NISTC_AI_SI2_LOADA_REG);
- ni_stc_writew(dev, timer, NISTC_AI_SI2_LOADB_REG);
-
- mode2 &= ~NISTC_AI_MODE2_SI2_INIT_LOAD_SRC; /* A */
- mode2 |= NISTC_AI_MODE2_SI2_RELOAD_MODE; /* alternate */
- ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
-
- ni_stc_writew(dev, NISTC_AI_CMD1_SI2_LOAD, NISTC_AI_CMD1_REG);
-
- mode2 |= NISTC_AI_MODE2_SI2_INIT_LOAD_SRC; /* B */
- mode2 |= NISTC_AI_MODE2_SI2_RELOAD_MODE; /* alternate */
- ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
- break;
- case TRIG_EXT:
- mode1 |= NISTC_AI_MODE1_CONVERT_SRC(
- ni_get_reg_value_roffs(
- CR_CHAN(cmd->convert_arg),
- NI_AI_ConvertClock,
- &devpriv->routing_tables, 1));
- if ((cmd->convert_arg & CR_INVERT) == 0)
- mode1 |= NISTC_AI_MODE1_CONVERT_POLARITY;
- ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG);
-
- mode2 |= NISTC_AI_MODE2_SC_GATE_ENA |
- NISTC_AI_MODE2_START_STOP_GATE_ENA;
- ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
-
- break;
- }
-
- if (dev->irq) {
- /* interrupt on FIFO, errors, SC_TC */
- interrupt_a_enable |= NISTC_INTA_ENA_AI_ERR |
- NISTC_INTA_ENA_AI_SC_TC;
-
-#ifndef PCIDMA
- interrupt_a_enable |= NISTC_INTA_ENA_AI_FIFO;
-#endif
-
- if ((cmd->flags & CMDF_WAKE_EOS) ||
- (devpriv->ai_cmd2 & NISTC_AI_CMD2_END_ON_EOS)) {
- /* wake on end-of-scan */
- devpriv->aimode = AIMODE_SCAN;
- } else {
- devpriv->aimode = AIMODE_HALF_FULL;
- }
-
- switch (devpriv->aimode) {
- case AIMODE_HALF_FULL:
- /* FIFO interrupts and DMA requests on half-full */
-#ifdef PCIDMA
- ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF_E,
- NISTC_AI_MODE3_REG);
-#else
- ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF,
- NISTC_AI_MODE3_REG);
-#endif
- break;
- case AIMODE_SAMPLE:
- /* generate FIFO interrupts on non-empty */
- ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE,
- NISTC_AI_MODE3_REG);
- break;
- case AIMODE_SCAN:
-#ifdef PCIDMA
- ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE,
- NISTC_AI_MODE3_REG);
-#else
- ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF,
- NISTC_AI_MODE3_REG);
-#endif
- interrupt_a_enable |= NISTC_INTA_ENA_AI_STOP;
- break;
- default:
- break;
- }
-
- /* clear interrupts */
- ni_stc_writew(dev, NISTC_INTA_ACK_AI_ALL, NISTC_INTA_ACK_REG);
-
- ni_set_bits(dev, NISTC_INTA_ENA_REG, interrupt_a_enable, 1);
- } else {
- /* interrupt on nothing */
- ni_set_bits(dev, NISTC_INTA_ENA_REG, ~0, 0);
-
- /* XXX start polling if necessary */
- }
-
- /* end configuration */
- ni_stc_writew(dev, NISTC_RESET_AI_CFG_END, NISTC_RESET_REG);
-
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER:
- ni_stc_writew(dev, NISTC_AI_CMD1_SI2_ARM |
- NISTC_AI_CMD1_SI_ARM |
- NISTC_AI_CMD1_DIV_ARM |
- NISTC_AI_CMD1_SC_ARM,
- NISTC_AI_CMD1_REG);
- break;
- case TRIG_EXT:
- ni_stc_writew(dev, NISTC_AI_CMD1_SI2_ARM |
- NISTC_AI_CMD1_SI_ARM | /* XXX ? */
- NISTC_AI_CMD1_DIV_ARM |
- NISTC_AI_CMD1_SC_ARM,
- NISTC_AI_CMD1_REG);
- break;
- }
-
-#ifdef PCIDMA
- {
- int retval = ni_ai_setup_MITE_dma(dev);
-
- if (retval)
- return retval;
- }
-#endif
-
- if (cmd->start_src == TRIG_NOW) {
- ni_stc_writew(dev, NISTC_AI_CMD2_START1_PULSE |
- devpriv->ai_cmd2,
- NISTC_AI_CMD2_REG);
- s->async->inttrig = NULL;
- } else if (cmd->start_src == TRIG_EXT) {
- s->async->inttrig = NULL;
- } else { /* TRIG_INT */
- s->async->inttrig = ni_ai_inttrig;
- }
-
- return 0;
-}
-
-static int ni_ai_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
-
- if (insn->n < 1)
- return -EINVAL;
-
- switch (data[0]) {
- case INSN_CONFIG_ALT_SOURCE:
- if (devpriv->is_m_series) {
- if (data[1] & ~NI_M_CFG_BYPASS_AI_CAL_MASK)
- return -EINVAL;
- devpriv->ai_calib_source = data[1];
- } else if (devpriv->is_6143) {
- unsigned int calib_source;
-
- calib_source = data[1] & 0xf;
-
- devpriv->ai_calib_source = calib_source;
- ni_writew(dev, calib_source, NI6143_CALIB_CHAN_REG);
- } else {
- unsigned int calib_source;
- unsigned int calib_source_adjust;
-
- calib_source = data[1] & 0xf;
- calib_source_adjust = (data[1] >> 4) & 0xff;
-
- if (calib_source >= 8)
- return -EINVAL;
- devpriv->ai_calib_source = calib_source;
- if (devpriv->is_611x) {
- ni_writeb(dev, calib_source_adjust,
- NI611X_CAL_GAIN_SEL_REG);
- }
- }
- return 2;
- case INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS:
- /* we don't care about actual channels */
- /* data[3] : chanlist_len */
- data[1] = ni_min_ai_scan_period_ns(dev, data[3]);
- if (devpriv->is_611x || devpriv->is_6143)
- data[2] = 0; /* simultaneous output */
- else
- data[2] = board->ai_speed;
- return 0;
- default:
- break;
- }
-
- return -EINVAL;
-}
-
-static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
- void *data, unsigned int num_bytes,
- unsigned int chan_index)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes);
- unsigned short *array = data;
- unsigned int i;
-#ifdef PCIDMA
- __le16 buf, *barray = data;
-#endif
-
- for (i = 0; i < nsamples; i++) {
- unsigned int range = CR_RANGE(cmd->chanlist[chan_index]);
- unsigned short val = array[i];
-
- /*
- * Munge data from unsigned to two's complement for
- * bipolar ranges.
- */
- if (comedi_range_is_bipolar(s, range))
- val = comedi_offset_munge(s, val);
-#ifdef PCIDMA
- buf = cpu_to_le16(val);
- barray[i] = buf;
-#else
- array[i] = val;
-#endif
- chan_index++;
- chan_index %= cmd->chanlist_len;
- }
-}
-
-static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chanspec[],
- unsigned int n_chans, int timed)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int range;
- unsigned int chan;
- unsigned int conf;
- int i;
- int invert = 0;
-
- if (timed) {
- for (i = 0; i < s->n_chan; ++i) {
- devpriv->ao_conf[i] &= ~NI_M_AO_CFG_BANK_UPDATE_TIMED;
- ni_writeb(dev, devpriv->ao_conf[i],
- NI_M_AO_CFG_BANK_REG(i));
- ni_writeb(dev, 0xf, NI_M_AO_WAVEFORM_ORDER_REG(i));
- }
- }
- for (i = 0; i < n_chans; i++) {
- const struct comedi_krange *krange;
-
- chan = CR_CHAN(chanspec[i]);
- range = CR_RANGE(chanspec[i]);
- krange = s->range_table->range + range;
- invert = 0;
- conf = 0;
- switch (krange->max - krange->min) {
- case 20000000:
- conf |= NI_M_AO_CFG_BANK_REF_INT_10V;
- ni_writeb(dev, 0, NI_M_AO_REF_ATTENUATION_REG(chan));
- break;
- case 10000000:
- conf |= NI_M_AO_CFG_BANK_REF_INT_5V;
- ni_writeb(dev, 0, NI_M_AO_REF_ATTENUATION_REG(chan));
- break;
- case 4000000:
- conf |= NI_M_AO_CFG_BANK_REF_INT_10V;
- ni_writeb(dev, NI_M_AO_REF_ATTENUATION_X5,
- NI_M_AO_REF_ATTENUATION_REG(chan));
- break;
- case 2000000:
- conf |= NI_M_AO_CFG_BANK_REF_INT_5V;
- ni_writeb(dev, NI_M_AO_REF_ATTENUATION_X5,
- NI_M_AO_REF_ATTENUATION_REG(chan));
- break;
- default:
- dev_err(dev->class_dev,
- "bug! unhandled ao reference voltage\n");
- break;
- }
- switch (krange->max + krange->min) {
- case 0:
- conf |= NI_M_AO_CFG_BANK_OFFSET_0V;
- break;
- case 10000000:
- conf |= NI_M_AO_CFG_BANK_OFFSET_5V;
- break;
- default:
- dev_err(dev->class_dev,
- "bug! unhandled ao offset voltage\n");
- break;
- }
- if (timed)
- conf |= NI_M_AO_CFG_BANK_UPDATE_TIMED;
- ni_writeb(dev, conf, NI_M_AO_CFG_BANK_REG(chan));
- devpriv->ao_conf[chan] = conf;
- ni_writeb(dev, i, NI_M_AO_WAVEFORM_ORDER_REG(chan));
- }
- return invert;
-}
-
-static int ni_old_ao_config_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chanspec[],
- unsigned int n_chans)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int range;
- unsigned int chan;
- unsigned int conf;
- int i;
- int invert = 0;
-
- for (i = 0; i < n_chans; i++) {
- chan = CR_CHAN(chanspec[i]);
- range = CR_RANGE(chanspec[i]);
- conf = NI_E_AO_DACSEL(chan);
-
- if (comedi_range_is_bipolar(s, range)) {
- conf |= NI_E_AO_CFG_BIP;
- invert = (s->maxdata + 1) >> 1;
- } else {
- invert = 0;
- }
- if (comedi_range_is_external(s, range))
- conf |= NI_E_AO_EXT_REF;
-
- /* not all boards can deglitch, but this shouldn't hurt */
- if (chanspec[i] & CR_DEGLITCH)
- conf |= NI_E_AO_DEGLITCH;
-
- /* analog reference */
- /* AREF_OTHER connects AO ground to AI ground, i think */
- if (CR_AREF(chanspec[i]) == AREF_OTHER)
- conf |= NI_E_AO_GROUND_REF;
-
- ni_writew(dev, conf, NI_E_AO_CFG_REG);
- devpriv->ao_conf[chan] = conf;
- }
- return invert;
-}
-
-static int ni_ao_config_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chanspec[], unsigned int n_chans,
- int timed)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->is_m_series)
- return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
- timed);
- else
- return ni_old_ao_config_chanlist(dev, s, chanspec, n_chans);
-}
-
-static int ni_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int reg;
- int i;
-
- if (devpriv->is_6xxx) {
- ni_ao_win_outw(dev, 1 << chan, NI671X_AO_IMMEDIATE_REG);
-
- reg = NI671X_DAC_DIRECT_DATA_REG(chan);
- } else if (devpriv->is_m_series) {
- reg = NI_M_DAC_DIRECT_DATA_REG(chan);
- } else {
- reg = NI_E_DAC_DIRECT_DATA_REG(chan);
- }
-
- ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- if (devpriv->is_6xxx) {
- /*
- * 6xxx boards have bipolar outputs, munge the
- * unsigned comedi values to 2's complement
- */
- val = comedi_offset_munge(s, val);
-
- ni_ao_win_outw(dev, val, reg);
- } else if (devpriv->is_m_series) {
- /*
- * M-series boards use offset binary values for
- * bipolar and uinpolar outputs
- */
- ni_writew(dev, val, reg);
- } else {
- /*
- * Non-M series boards need two's complement values
- * for bipolar ranges.
- */
- if (comedi_range_is_bipolar(s, range))
- val = comedi_offset_munge(s, val);
-
- ni_writew(dev, val, reg);
- }
- }
-
- return insn->n;
-}
-
-/*
- * Arms the AO device in preparation for a trigger event.
- * This function also allocates and prepares a DMA channel (or FIFO if DMA is
- * not used). As a part of this preparation, this function preloads the DAC
- * registers with the first values of the output stream. This ensures that the
- * first clock cycle after the trigger can be used for output.
- *
- * Note that this function _must_ happen after a user has written data to the
- * output buffers via either mmap or write(fileno,...).
- */
-static int ni_ao_arm(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
- int interrupt_b_bits;
- int i;
- static const int timeout = 1000;
-
- /*
- * Prevent ao from doing things like trying to allocate the ao dma
- * channel multiple times.
- */
- if (!devpriv->ao_needs_arming) {
- dev_dbg(dev->class_dev, "%s: device does not need arming!\n",
- __func__);
- return -EINVAL;
- }
-
- devpriv->ao_needs_arming = 0;
-
- ni_set_bits(dev, NISTC_INTB_ENA_REG,
- NISTC_INTB_ENA_AO_FIFO | NISTC_INTB_ENA_AO_ERR, 0);
- interrupt_b_bits = NISTC_INTB_ENA_AO_ERR;
-#ifdef PCIDMA
- ni_stc_writew(dev, 1, NISTC_DAC_FIFO_CLR_REG);
- if (devpriv->is_6xxx)
- ni_ao_win_outl(dev, 0x6, NI611X_AO_FIFO_OFFSET_LOAD_REG);
- ret = ni_ao_setup_MITE_dma(dev);
- if (ret)
- return ret;
- ret = ni_ao_wait_for_dma_load(dev);
- if (ret < 0)
- return ret;
-#else
- ret = ni_ao_prep_fifo(dev, s);
- if (ret == 0)
- return -EPIPE;
-
- interrupt_b_bits |= NISTC_INTB_ENA_AO_FIFO;
-#endif
-
- ni_stc_writew(dev, devpriv->ao_mode3 | NISTC_AO_MODE3_NOT_AN_UPDATE,
- NISTC_AO_MODE3_REG);
- ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
- /* wait for DACs to be loaded */
- for (i = 0; i < timeout; i++) {
- udelay(1);
- if ((ni_stc_readw(dev, NISTC_STATUS2_REG) &
- NISTC_STATUS2_AO_TMRDACWRS_IN_PROGRESS) == 0)
- break;
- }
- if (i == timeout) {
- dev_err(dev->class_dev,
- "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear\n");
- return -EIO;
- }
- /*
- * stc manual says we are need to clear error interrupt after
- * AO_TMRDACWRs_In_Progress_St clears
- */
- ni_stc_writew(dev, NISTC_INTB_ACK_AO_ERR, NISTC_INTB_ACK_REG);
-
- ni_set_bits(dev, NISTC_INTB_ENA_REG, interrupt_b_bits, 1);
-
- ni_stc_writew(dev, NISTC_AO_CMD1_UI_ARM |
- NISTC_AO_CMD1_UC_ARM |
- NISTC_AO_CMD1_BC_ARM |
- devpriv->ao_cmd1,
- NISTC_AO_CMD1_REG);
-
- return 0;
-}
-
-static int ni_ao_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- unsigned int nbytes;
-
- switch (data[0]) {
- case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
- switch (data[1]) {
- case COMEDI_OUTPUT:
- nbytes = comedi_samples_to_bytes(s,
- board->ao_fifo_depth);
- data[2] = 1 + nbytes;
- if (devpriv->mite)
- data[2] += devpriv->mite->fifo_size;
- break;
- case COMEDI_INPUT:
- data[2] = 0;
- break;
- default:
- return -EINVAL;
- }
- return 0;
- case INSN_CONFIG_ARM:
- return ni_ao_arm(dev, s);
- case INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS:
- /* we don't care about actual channels */
- /* data[3] : chanlist_len */
- data[1] = board->ao_speed * data[3];
- data[2] = 0;
- return 0;
- default:
- break;
- }
-
- return -EINVAL;
-}
-
-static int ni_ao_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- /*
- * Require trig_num == cmd->start_arg when cmd->start_src == TRIG_INT.
- * For backwards compatibility, also allow trig_num == 0 when
- * cmd->start_src != TRIG_INT (i.e. when cmd->start_src == TRIG_EXT);
- * in that case, the internal trigger is being used as a pre-trigger
- * before the external trigger.
- */
- if (!(trig_num == cmd->start_arg ||
- (trig_num == 0 && cmd->start_src != TRIG_INT)))
- return -EINVAL;
-
- /*
- * Null trig at beginning prevent ao start trigger from executing more
- * than once per command.
- */
- s->async->inttrig = NULL;
-
- if (devpriv->ao_needs_arming) {
- /* only arm this device if it still needs arming */
- ret = ni_ao_arm(dev, s);
- if (ret)
- return ret;
- }
-
- ni_stc_writew(dev, NISTC_AO_CMD2_START1_PULSE | devpriv->ao_cmd2,
- NISTC_AO_CMD2_REG);
-
- return 0;
-}
-
-/*
- * begin ni_ao_cmd.
- * Organized similar to NI-STC and MHDDK examples.
- * ni_ao_cmd is broken out into configuration sub-routines for clarity.
- */
-
-static void ni_ao_cmd_personalize(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- unsigned int bits;
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
-
- bits =
- /* fast CPU interface--only eseries */
- /* ((slow CPU interface) ? 0 : AO_Fast_CPU) | */
- NISTC_AO_PERSONAL_BC_SRC_SEL |
- 0 /* (use_original_pulse ? 0 : NISTC_AO_PERSONAL_UPDATE_TIMEBASE) */ |
- /*
- * FIXME: start setting following bit when appropriate. Need to
- * determine whether board is E4 or E1.
- * FROM MHHDK:
- * if board is E4 or E1
- * Set bit "NISTC_AO_PERSONAL_UPDATE_PW" to 0
- * else
- * set it to 1
- */
- NISTC_AO_PERSONAL_UPDATE_PW |
- /* FIXME: when should we set following bit to zero? */
- NISTC_AO_PERSONAL_TMRDACWR_PW |
- (board->ao_fifo_depth ?
- NISTC_AO_PERSONAL_FIFO_ENA : NISTC_AO_PERSONAL_DMA_PIO_CTRL)
- ;
-#if 0
- /*
- * FIXME:
- * add something like ".has_individual_dacs = 0" to ni_board_struct
- * since, as F Hess pointed out, not all in m series have singles. not
- * sure if e-series all have duals...
- */
-
- /*
- * F Hess: windows driver does not set NISTC_AO_PERSONAL_NUM_DAC bit for
- * 6281, verified with bus analyzer.
- */
- if (devpriv->is_m_series)
- bits |= NISTC_AO_PERSONAL_NUM_DAC;
-#endif
- ni_stc_writew(dev, bits, NISTC_AO_PERSONAL_REG);
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
-}
-
-static void ni_ao_cmd_set_trigger(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int trigsel;
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
-
- /* sync */
- if (cmd->stop_src == TRIG_NONE) {
- devpriv->ao_mode1 |= NISTC_AO_MODE1_CONTINUOUS;
- devpriv->ao_mode1 &= ~NISTC_AO_MODE1_TRIGGER_ONCE;
- } else {
- devpriv->ao_mode1 &= ~NISTC_AO_MODE1_CONTINUOUS;
- devpriv->ao_mode1 |= NISTC_AO_MODE1_TRIGGER_ONCE;
- }
- ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
-
- if (cmd->start_src == TRIG_INT) {
- trigsel = NISTC_AO_TRIG_START1_EDGE |
- NISTC_AO_TRIG_START1_SYNC;
- } else { /* TRIG_EXT */
- trigsel = NISTC_AO_TRIG_START1_SEL(
- ni_get_reg_value_roffs(
- CR_CHAN(cmd->start_arg),
- NI_AO_StartTrigger,
- &devpriv->routing_tables, 1));
-
- /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */
- if (cmd->start_arg & CR_INVERT)
- trigsel |= NISTC_AO_TRIG_START1_POLARITY;
- /* 0=edge detection disabled, 1=enabled */
- if (cmd->start_arg & CR_EDGE)
- trigsel |= NISTC_AO_TRIG_START1_EDGE;
- }
- ni_stc_writew(dev, trigsel, NISTC_AO_TRIG_SEL_REG);
-
- /* AO_Delayed_START1 = 0, we do not support delayed start...yet */
-
- /* sync */
- /* select DA_START1 as PFI6/AO_START1 when configured as an output */
- devpriv->ao_mode3 &= ~NISTC_AO_MODE3_TRIG_LEN;
- ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
-}
-
-static void ni_ao_cmd_set_counters(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct ni_private *devpriv = dev->private;
- /* Not supporting 'waveform staging' or 'local buffer with pauses' */
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
- /*
- * This relies on ao_mode1/(Trigger_Once | Continuous) being set in
- * set_trigger above. It is unclear whether we really need to re-write
- * this register with these values. The mhddk examples for e-series
- * show writing this in both places, but the examples for m-series show
- * a single write in the set_counters function (here).
- */
- ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
-
- /* sync (upload number of buffer iterations -1) */
- /* indicate that we want to use BC_Load_A_Register as the source */
- devpriv->ao_mode2 &= ~NISTC_AO_MODE2_BC_INIT_LOAD_SRC;
- ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
-
- /*
- * if the BC_TC interrupt is still issued in spite of UC, BC, UI
- * ignoring BC_TC, then we will need to find a way to ignore that
- * interrupt in continuous mode.
- */
- ni_stc_writel(dev, 0, NISTC_AO_BC_LOADA_REG); /* iter once */
-
- /* sync (issue command to load number of buffer iterations -1) */
- ni_stc_writew(dev, NISTC_AO_CMD1_BC_LOAD, NISTC_AO_CMD1_REG);
-
- /* sync (upload number of updates in buffer) */
- /* indicate that we want to use UC_Load_A_Register as the source */
- devpriv->ao_mode2 &= ~NISTC_AO_MODE2_UC_INIT_LOAD_SRC;
- ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
-
- /*
- * if a user specifies '0', this automatically assumes the entire 24bit
- * address space is available for the (multiple iterations of single
- * buffer) MISB. Otherwise, stop_arg specifies the MISB length that
- * will be used, regardless of whether we are in continuous mode or not.
- * In continuous mode, the output will just iterate indefinitely over
- * the MISB.
- */
- {
- unsigned int stop_arg = cmd->stop_arg > 0 ?
- (cmd->stop_arg & 0xffffff) : 0xffffff;
-
- if (devpriv->is_m_series) {
- /*
- * this is how the NI example code does it for m-series
- * boards, verified correct with 6259
- */
- ni_stc_writel(dev, stop_arg - 1, NISTC_AO_UC_LOADA_REG);
-
- /* sync (issue cmd to load number of updates in MISB) */
- ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD,
- NISTC_AO_CMD1_REG);
- } else {
- ni_stc_writel(dev, stop_arg, NISTC_AO_UC_LOADA_REG);
-
- /* sync (issue cmd to load number of updates in MISB) */
- ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD,
- NISTC_AO_CMD1_REG);
-
- /*
- * sync (upload number of updates-1 in MISB)
- * --eseries only?
- */
- ni_stc_writel(dev, stop_arg - 1, NISTC_AO_UC_LOADA_REG);
- }
- }
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
-}
-
-static void ni_ao_cmd_set_update(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct ni_private *devpriv = dev->private;
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
-
- /*
- * zero out these bit fields to be set below. Does an ao-reset do this
- * automatically?
- */
- devpriv->ao_mode1 &= ~(NISTC_AO_MODE1_UI_SRC_MASK |
- NISTC_AO_MODE1_UI_SRC_POLARITY |
- NISTC_AO_MODE1_UPDATE_SRC_MASK |
- NISTC_AO_MODE1_UPDATE_SRC_POLARITY);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- unsigned int trigvar;
-
- devpriv->ao_cmd2 &= ~NISTC_AO_CMD2_BC_GATE_ENA;
-
- /*
- * NOTE: there are several other ways of configuring internal
- * updates, but we'll only support one for now: using
- * AO_IN_TIMEBASE, w/o waveform staging, w/o a delay between
- * START1 and first update, and also w/o local buffer mode w/
- * pauses.
- */
-
- /*
- * This is already done above:
- * devpriv->ao_mode1 &= ~(
- * // set UPDATE_Source to UI_TC:
- * NISTC_AO_MODE1_UPDATE_SRC_MASK |
- * // set UPDATE_Source_Polarity to rising (required?)
- * NISTC_AO_MODE1_UPDATE_SRC_POLARITY |
- * // set UI_Source to AO_IN_TIMEBASE1:
- * NISTC_AO_MODE1_UI_SRC_MASK |
- * // set UI_Source_Polarity to rising (required?)
- * NISTC_AO_MODE1_UI_SRC_POLARITY
- * );
- */
-
- /*
- * TODO: use ao_ui_clock_source to allow all possible signals
- * to be routed to UI_Source_Select. See tSTC.h for
- * eseries/ni67xx and tMSeries.h for mseries.
- */
-
- trigvar = ni_ns_to_timer(dev, cmd->scan_begin_arg,
- CMDF_ROUND_NEAREST);
-
- /*
- * Wait N TB3 ticks after the start trigger before
- * clocking (N must be >=2).
- */
- /* following line: 2-1 per STC */
- ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_REG);
- ni_stc_writew(dev, NISTC_AO_CMD1_UI_LOAD, NISTC_AO_CMD1_REG);
- ni_stc_writel(dev, trigvar, NISTC_AO_UI_LOADA_REG);
- } else { /* TRIG_EXT */
- /* FIXME: assert scan_begin_arg != 0, ret failure otherwise */
- devpriv->ao_cmd2 |= NISTC_AO_CMD2_BC_GATE_ENA;
- devpriv->ao_mode1 |= NISTC_AO_MODE1_UPDATE_SRC(
- ni_get_reg_value(
- CR_CHAN(cmd->scan_begin_arg),
- NI_AO_SampleClock,
- &devpriv->routing_tables));
- if (cmd->scan_begin_arg & CR_INVERT)
- devpriv->ao_mode1 |= NISTC_AO_MODE1_UPDATE_SRC_POLARITY;
- }
-
- ni_stc_writew(dev, devpriv->ao_cmd2, NISTC_AO_CMD2_REG);
- ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
- devpriv->ao_mode2 &= ~(NISTC_AO_MODE2_UI_RELOAD_MODE(3) |
- NISTC_AO_MODE2_UI_INIT_LOAD_SRC);
- ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
-
- /* Configure DAQ-STC for Timed update mode */
- devpriv->ao_cmd1 |= NISTC_AO_CMD1_DAC1_UPDATE_MODE |
- NISTC_AO_CMD1_DAC0_UPDATE_MODE;
- /* We are not using UPDATE2-->don't have to set DACx_Source_Select */
- ni_stc_writew(dev, devpriv->ao_cmd1, NISTC_AO_CMD1_REG);
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
-}
-
-static void ni_ao_cmd_set_channels(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- const struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int bits = 0;
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
-
- if (devpriv->is_6xxx) {
- unsigned int i;
-
- bits = 0;
- for (i = 0; i < cmd->chanlist_len; ++i) {
- int chan = CR_CHAN(cmd->chanlist[i]);
-
- bits |= 1 << chan;
- ni_ao_win_outw(dev, chan, NI611X_AO_WAVEFORM_GEN_REG);
- }
- ni_ao_win_outw(dev, bits, NI611X_AO_TIMED_REG);
- }
-
- ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
-
- if (cmd->scan_end_arg > 1) {
- devpriv->ao_mode1 |= NISTC_AO_MODE1_MULTI_CHAN;
- bits = NISTC_AO_OUT_CTRL_CHANS(cmd->scan_end_arg - 1)
- | NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ;
-
- } else {
- devpriv->ao_mode1 &= ~NISTC_AO_MODE1_MULTI_CHAN;
- bits = NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ;
- if (devpriv->is_m_series | devpriv->is_6xxx)
- bits |= NISTC_AO_OUT_CTRL_CHANS(0);
- else
- bits |= NISTC_AO_OUT_CTRL_CHANS(
- CR_CHAN(cmd->chanlist[0]));
- }
-
- ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
- ni_stc_writew(dev, bits, NISTC_AO_OUT_CTRL_REG);
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
-}
-
-static void ni_ao_cmd_set_stop_conditions(struct comedi_device *dev,
- const struct comedi_cmd *cmd)
-{
- struct ni_private *devpriv = dev->private;
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
-
- devpriv->ao_mode3 |= NISTC_AO_MODE3_STOP_ON_OVERRUN_ERR;
- ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
-
- /*
- * Since we are not supporting waveform staging, we ignore these errors:
- * NISTC_AO_MODE3_STOP_ON_BC_TC_ERR,
- * NISTC_AO_MODE3_STOP_ON_BC_TC_TRIG_ERR
- */
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
-}
-
-static void ni_ao_cmd_set_fifo_mode(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
-
- devpriv->ao_mode2 &= ~NISTC_AO_MODE2_FIFO_MODE_MASK;
-#ifdef PCIDMA
- devpriv->ao_mode2 |= NISTC_AO_MODE2_FIFO_MODE_HF_F;
-#else
- devpriv->ao_mode2 |= NISTC_AO_MODE2_FIFO_MODE_HF;
-#endif
- /* NOTE: this is where use_onboard_memory=True would be implemented */
- devpriv->ao_mode2 &= ~NISTC_AO_MODE2_FIFO_REXMIT_ENA;
- ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
-
- /* enable sending of ao fifo requests (dma request) */
- ni_stc_writew(dev, NISTC_AO_START_AOFREQ_ENA, NISTC_AO_START_SEL_REG);
-
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
-
- /* we are not supporting boards with virtual fifos */
-}
-
-static void ni_ao_cmd_set_interrupts(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- if (s->async->cmd.stop_src == TRIG_COUNT)
- ni_set_bits(dev, NISTC_INTB_ENA_REG,
- NISTC_INTB_ENA_AO_BC_TC, 1);
-
- s->async->inttrig = ni_ao_inttrig;
-}
-
-static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- const struct comedi_cmd *cmd = &s->async->cmd;
-
- if (dev->irq == 0) {
- dev_err(dev->class_dev, "cannot run command without an irq");
- return -EIO;
- }
-
- /* ni_ao_reset should have already been done */
- ni_ao_cmd_personalize(dev, cmd);
- /* clearing fifo and preload happens elsewhere */
-
- ni_ao_cmd_set_trigger(dev, cmd);
- ni_ao_cmd_set_counters(dev, cmd);
- ni_ao_cmd_set_update(dev, cmd);
- ni_ao_cmd_set_channels(dev, s);
- ni_ao_cmd_set_stop_conditions(dev, cmd);
- ni_ao_cmd_set_fifo_mode(dev);
- ni_cmd_set_mite_transfer(devpriv->ao_mite_ring, s, cmd, 0x00ffffff);
- ni_ao_cmd_set_interrupts(dev, s);
-
- /*
- * arm(ing) must happen later so that DMA can be setup and DACs
- * preloaded with the actual output buffer before starting.
- *
- * start(ing) must happen _after_ arming is completed. Starting can be
- * done either via ni_ao_inttrig, or via an external trigger.
- *
- * **Currently, ni_ao_inttrig will automatically attempt a call to
- * ni_ao_arm if the device still needs arming at that point. This
- * allows backwards compatibility.
- */
- devpriv->ao_needs_arming = 1;
- return 0;
-}
-
-/* end ni_ao_cmd */
-
-static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- int err = 0;
- unsigned int tmp;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_INT:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->start_arg),
- NI_AO_StartTrigger,
- &devpriv->routing_tables, 1);
- break;
- }
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- board->ao_speed);
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- devpriv->clock_ns *
- 0xffffff);
- } else { /* TRIG_EXT */
- err |= ni_check_trigger_arg(CR_CHAN(cmd->scan_begin_arg),
- NI_AO_SampleClock,
- &devpriv->routing_tables);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- tmp = cmd->scan_begin_arg;
- cmd->scan_begin_arg =
- ni_timer_to_ns(dev, ni_ns_to_timer(dev,
- cmd->scan_begin_arg,
- cmd->flags));
- if (tmp != cmd->scan_begin_arg)
- err++;
- }
- if (err)
- return 4;
-
- return 0;
-}
-
-static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- /* See 3.6.1.2 "Resetting", of DAQ-STC Technical Reference Manual */
-
- /*
- * In the following, the "--sync" comments are meant to denote
- * asynchronous boundaries for setting the registers as described in the
- * DAQ-STC mostly in the order also described in the DAQ-STC.
- */
-
- struct ni_private *devpriv = dev->private;
-
- ni_release_ao_mite_channel(dev);
-
- /* --sync (reset AO) */
- if (devpriv->is_m_series)
- /* following example in mhddk for m-series */
- ni_stc_writew(dev, NISTC_RESET_AO, NISTC_RESET_REG);
-
- /*--sync (start config) */
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
-
- /*--sync (Disarm) */
- ni_stc_writew(dev, NISTC_AO_CMD1_DISARM, NISTC_AO_CMD1_REG);
-
- /*
- * --sync
- * (clear bunch of registers--mseries mhddk examples do not include
- * this)
- */
- devpriv->ao_cmd1 = 0;
- devpriv->ao_cmd2 = 0;
- devpriv->ao_mode1 = 0;
- devpriv->ao_mode2 = 0;
- if (devpriv->is_m_series)
- devpriv->ao_mode3 = NISTC_AO_MODE3_LAST_GATE_DISABLE;
- else
- devpriv->ao_mode3 = 0;
-
- ni_stc_writew(dev, 0, NISTC_AO_PERSONAL_REG);
- ni_stc_writew(dev, 0, NISTC_AO_CMD1_REG);
- ni_stc_writew(dev, 0, NISTC_AO_CMD2_REG);
- ni_stc_writew(dev, 0, NISTC_AO_MODE1_REG);
- ni_stc_writew(dev, 0, NISTC_AO_MODE2_REG);
- ni_stc_writew(dev, 0, NISTC_AO_OUT_CTRL_REG);
- ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
- ni_stc_writew(dev, 0, NISTC_AO_START_SEL_REG);
- ni_stc_writew(dev, 0, NISTC_AO_TRIG_SEL_REG);
-
- /*--sync (disable interrupts) */
- ni_set_bits(dev, NISTC_INTB_ENA_REG, ~0, 0);
-
- /*--sync (ack) */
- ni_stc_writew(dev, NISTC_AO_PERSONAL_BC_SRC_SEL, NISTC_AO_PERSONAL_REG);
- ni_stc_writew(dev, NISTC_INTB_ACK_AO_ALL, NISTC_INTB_ACK_REG);
-
- /*--not in DAQ-STC. which doc? */
- if (devpriv->is_6xxx) {
- ni_ao_win_outw(dev, (1u << s->n_chan) - 1u,
- NI671X_AO_IMMEDIATE_REG);
- ni_ao_win_outw(dev, NI611X_AO_MISC_CLEAR_WG,
- NI611X_AO_MISC_REG);
- }
- ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
- /*--end */
-
- return 0;
-}
-
-/* digital io */
-
-static int ni_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- devpriv->dio_control &= ~NISTC_DIO_CTRL_DIR_MASK;
- devpriv->dio_control |= NISTC_DIO_CTRL_DIR(s->io_bits);
- ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
-
- return insn->n;
-}
-
-static int ni_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
-
- /* Make sure we're not using the serial part of the dio */
- if ((data[0] & (NISTC_DIO_SDIN | NISTC_DIO_SDOUT)) &&
- devpriv->serial_interval_ns)
- return -EBUSY;
-
- if (comedi_dio_update_state(s, data)) {
- devpriv->dio_output &= ~NISTC_DIO_OUT_PARALLEL_MASK;
- devpriv->dio_output |= NISTC_DIO_OUT_PARALLEL(s->state);
- ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG);
- }
-
- data[1] = ni_stc_readw(dev, NISTC_DIO_IN_REG);
-
- return insn->n;
-}
-
-#ifdef PCIDMA
-static int ni_m_series_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
- const struct ni_board_struct *board = dev->board_ptr;
-
- /* we don't care about actual channels */
- data[1] = board->dio_speed;
- data[2] = 0;
- return 0;
- }
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- ni_writel(dev, s->io_bits, NI_M_DIO_DIR_REG);
-
- return insn->n;
-}
-
-static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- ni_writel(dev, s->state, NI_M_DIO_REG);
-
- data[1] = ni_readl(dev, NI_M_DIO_REG);
-
- return insn->n;
-}
-
-static int ni_cdio_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int i;
-
- for (i = 0; i < cmd->chanlist_len; ++i) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (chan != i)
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ni_cdio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int bytes_per_scan;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- /*
- * Although NI_D[IO]_SampleClock are the same, perhaps we should still,
- * for completeness, test whether the cmd is output or input?
- */
- err |= ni_check_trigger_arg(CR_CHAN(cmd->scan_begin_arg),
- NI_DO_SampleClock,
- &devpriv->routing_tables);
- if (CR_RANGE(cmd->scan_begin_arg) != 0 ||
- CR_AREF(cmd->scan_begin_arg) != 0)
- err |= -EINVAL;
-
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- bytes_per_scan = comedi_bytes_per_scan_cmd(s, cmd);
- if (bytes_per_scan) {
- err |= comedi_check_trigger_arg_max(&cmd->stop_arg,
- s->async->prealloc_bufsz /
- bytes_per_scan);
- }
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= ni_cdio_check_chanlist(dev, s, cmd);
-
- if (err)
- return 5;
-
- return 0;
-}
-
-static int ni_cdo_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- const unsigned int timeout = 1000;
- int retval = 0;
- unsigned int i;
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- s->async->inttrig = NULL;
-
- /* read alloc the entire buffer */
- comedi_buf_read_alloc(s, s->async->prealloc_bufsz);
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->cdo_mite_chan) {
- mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
- mite_dma_arm(devpriv->cdo_mite_chan);
- } else {
- dev_err(dev->class_dev, "BUG: no cdo mite channel?\n");
- retval = -EIO;
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- if (retval < 0)
- return retval;
-
- /*
- * XXX not sure what interrupt C group does
- * wait for dma to fill output fifo
- * ni_writeb(dev, NI_M_INTC_ENA, NI_M_INTC_ENA_REG);
- */
- for (i = 0; i < timeout; ++i) {
- if (ni_readl(dev, NI_M_CDIO_STATUS_REG) &
- NI_M_CDIO_STATUS_CDO_FIFO_FULL)
- break;
- usleep_range(10, 100);
- }
- if (i == timeout) {
- dev_err(dev->class_dev, "dma failed to fill cdo fifo!\n");
- s->cancel(dev, s);
- return -EIO;
- }
- ni_writel(dev, NI_M_CDO_CMD_ARM |
- NI_M_CDO_CMD_ERR_INT_ENA_SET |
- NI_M_CDO_CMD_F_E_INT_ENA_SET,
- NI_M_CDIO_CMD_REG);
- return retval;
-}
-
-static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- const struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int cdo_mode_bits;
- int retval;
-
- ni_writel(dev, NI_M_CDO_CMD_RESET, NI_M_CDIO_CMD_REG);
- /*
- * Although NI_D[IO]_SampleClock are the same, perhaps we should still,
- * for completeness, test whether the cmd is output or input(?)
- */
- cdo_mode_bits = NI_M_CDO_MODE_FIFO_MODE |
- NI_M_CDO_MODE_HALT_ON_ERROR |
- NI_M_CDO_MODE_SAMPLE_SRC(
- ni_get_reg_value(
- CR_CHAN(cmd->scan_begin_arg),
- NI_DO_SampleClock,
- &devpriv->routing_tables));
- if (cmd->scan_begin_arg & CR_INVERT)
- cdo_mode_bits |= NI_M_CDO_MODE_POLARITY;
- ni_writel(dev, cdo_mode_bits, NI_M_CDO_MODE_REG);
- if (s->io_bits) {
- ni_writel(dev, s->state, NI_M_CDO_FIFO_DATA_REG);
- ni_writel(dev, NI_M_CDO_CMD_SW_UPDATE, NI_M_CDIO_CMD_REG);
- ni_writel(dev, s->io_bits, NI_M_CDO_MASK_ENA_REG);
- } else {
- dev_err(dev->class_dev,
- "attempted to run digital output command with no lines configured as outputs\n");
- return -EIO;
- }
- retval = ni_request_cdo_mite_channel(dev);
- if (retval < 0)
- return retval;
-
- ni_cmd_set_mite_transfer(devpriv->cdo_mite_ring, s, cmd,
- s->async->prealloc_bufsz /
- comedi_bytes_per_scan(s));
-
- s->async->inttrig = ni_cdo_inttrig;
-
- return 0;
-}
-
-static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- ni_writel(dev, NI_M_CDO_CMD_DISARM |
- NI_M_CDO_CMD_ERR_INT_ENA_CLR |
- NI_M_CDO_CMD_F_E_INT_ENA_CLR |
- NI_M_CDO_CMD_F_REQ_INT_ENA_CLR,
- NI_M_CDIO_CMD_REG);
- /*
- * XXX not sure what interrupt C group does
- * ni_writeb(dev, 0, NI_M_INTC_ENA_REG);
- */
- ni_writel(dev, 0, NI_M_CDO_MASK_ENA_REG);
- ni_release_cdo_mite_channel(dev);
- return 0;
-}
-
-static void handle_cdio_interrupt(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int cdio_status;
- struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV];
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->cdo_mite_chan)
- mite_ack_linkc(devpriv->cdo_mite_chan, s, true);
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- cdio_status = ni_readl(dev, NI_M_CDIO_STATUS_REG);
- if (cdio_status & NI_M_CDIO_STATUS_CDO_ERROR) {
- /* XXX just guessing this is needed and does something useful */
- ni_writel(dev, NI_M_CDO_CMD_ERR_INT_CONFIRM,
- NI_M_CDIO_CMD_REG);
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
- if (cdio_status & NI_M_CDIO_STATUS_CDO_FIFO_EMPTY) {
- ni_writel(dev, NI_M_CDO_CMD_F_E_INT_ENA_CLR,
- NI_M_CDIO_CMD_REG);
- /* s->async->events |= COMEDI_CB_EOA; */
- }
- comedi_handle_events(dev, s);
-}
-#endif /* PCIDMA */
-
-static int ni_serial_hw_readwrite8(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned char data_out,
- unsigned char *data_in)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int status1;
- int err = 0, count = 20;
-
- devpriv->dio_output &= ~NISTC_DIO_OUT_SERIAL_MASK;
- devpriv->dio_output |= NISTC_DIO_OUT_SERIAL(data_out);
- ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG);
-
- status1 = ni_stc_readw(dev, NISTC_STATUS1_REG);
- if (status1 & NISTC_STATUS1_SERIO_IN_PROG) {
- err = -EBUSY;
- goto error;
- }
-
- devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_START;
- ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
- devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_START;
-
- /* Wait until STC says we're done, but don't loop infinitely. */
- while ((status1 = ni_stc_readw(dev, NISTC_STATUS1_REG)) &
- NISTC_STATUS1_SERIO_IN_PROG) {
- /* Delay one bit per loop */
- udelay((devpriv->serial_interval_ns + 999) / 1000);
- if (--count < 0) {
- dev_err(dev->class_dev,
- "SPI serial I/O didn't finish in time!\n");
- err = -ETIME;
- goto error;
- }
- }
-
- /*
- * Delay for last bit. This delay is absolutely necessary, because
- * NISTC_STATUS1_SERIO_IN_PROG goes high one bit too early.
- */
- udelay((devpriv->serial_interval_ns + 999) / 1000);
-
- if (data_in)
- *data_in = ni_stc_readw(dev, NISTC_DIO_SERIAL_IN_REG);
-
-error:
- ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
-
- return err;
-}
-
-static int ni_serial_sw_readwrite8(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned char data_out,
- unsigned char *data_in)
-{
- struct ni_private *devpriv = dev->private;
- unsigned char mask, input = 0;
-
- /* Wait for one bit before transfer */
- udelay((devpriv->serial_interval_ns + 999) / 1000);
-
- for (mask = 0x80; mask; mask >>= 1) {
- /*
- * Output current bit; note that we cannot touch s->state
- * because it is a per-subdevice field, and serial is
- * a separate subdevice from DIO.
- */
- devpriv->dio_output &= ~NISTC_DIO_SDOUT;
- if (data_out & mask)
- devpriv->dio_output |= NISTC_DIO_SDOUT;
- ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG);
-
- /*
- * Assert SDCLK (active low, inverted), wait for half of
- * the delay, deassert SDCLK, and wait for the other half.
- */
- devpriv->dio_control |= NISTC_DIO_SDCLK;
- ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
-
- udelay((devpriv->serial_interval_ns + 999) / 2000);
-
- devpriv->dio_control &= ~NISTC_DIO_SDCLK;
- ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
-
- udelay((devpriv->serial_interval_ns + 999) / 2000);
-
- /* Input current bit */
- if (ni_stc_readw(dev, NISTC_DIO_IN_REG) & NISTC_DIO_SDIN)
- input |= mask;
- }
-
- if (data_in)
- *data_in = input;
-
- return 0;
-}
-
-static int ni_serial_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int clk_fout = devpriv->clock_and_fout;
- int err = insn->n;
- unsigned char byte_out, byte_in = 0;
-
- if (insn->n != 2)
- return -EINVAL;
-
- switch (data[0]) {
- case INSN_CONFIG_SERIAL_CLOCK:
- devpriv->serial_hw_mode = 1;
- devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_ENA;
-
- if (data[1] == SERIAL_DISABLED) {
- devpriv->serial_hw_mode = 0;
- devpriv->dio_control &= ~(NISTC_DIO_CTRL_HW_SER_ENA |
- NISTC_DIO_SDCLK);
- data[1] = SERIAL_DISABLED;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_600NS) {
- /*
- * Warning: this clock speed is too fast to reliably
- * control SCXI.
- */
- devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_TIMEBASE;
- clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE;
- clk_fout &= ~NISTC_CLK_FOUT_DIO_SER_OUT_DIV2;
- data[1] = SERIAL_600NS;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_1_2US) {
- devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_TIMEBASE;
- clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE |
- NISTC_CLK_FOUT_DIO_SER_OUT_DIV2;
- data[1] = SERIAL_1_2US;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_10US) {
- devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_TIMEBASE;
- clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE |
- NISTC_CLK_FOUT_DIO_SER_OUT_DIV2;
- /*
- * Note: NISTC_CLK_FOUT_DIO_SER_OUT_DIV2 only affects
- * 600ns/1.2us. If you turn divide_by_2 off with the
- * slow clock, you will still get 10us, except then
- * all your delays are wrong.
- */
- data[1] = SERIAL_10US;
- devpriv->serial_interval_ns = data[1];
- } else {
- devpriv->dio_control &= ~(NISTC_DIO_CTRL_HW_SER_ENA |
- NISTC_DIO_SDCLK);
- devpriv->serial_hw_mode = 0;
- data[1] = (data[1] / 1000) * 1000;
- devpriv->serial_interval_ns = data[1];
- }
- devpriv->clock_and_fout = clk_fout;
-
- ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
- ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
- return 1;
-
- case INSN_CONFIG_BIDIRECTIONAL_DATA:
-
- if (devpriv->serial_interval_ns == 0)
- return -EINVAL;
-
- byte_out = data[1] & 0xFF;
-
- if (devpriv->serial_hw_mode) {
- err = ni_serial_hw_readwrite8(dev, s, byte_out,
- &byte_in);
- } else if (devpriv->serial_interval_ns > 0) {
- err = ni_serial_sw_readwrite8(dev, s, byte_out,
- &byte_in);
- } else {
- dev_err(dev->class_dev, "serial disabled!\n");
- return -EINVAL;
- }
- if (err < 0)
- return err;
- data[1] = byte_in & 0xFF;
- return insn->n;
-
- break;
- default:
- return -EINVAL;
- }
-}
-
-static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- int i;
-
- for (i = 0; i < s->n_chan; i++) {
- ni_ao_win_outw(dev, NI_E_AO_DACSEL(i) | 0x0,
- NI67XX_AO_CFG2_REG);
- }
- ni_ao_win_outw(dev, 0x0, NI67XX_AO_SP_UPDATES_REG);
-}
-
-static const struct mio_regmap ni_gpct_to_stc_regmap[] = {
- [NITIO_G0_AUTO_INC] = { NISTC_G0_AUTOINC_REG, 2 },
- [NITIO_G1_AUTO_INC] = { NISTC_G1_AUTOINC_REG, 2 },
- [NITIO_G0_CMD] = { NISTC_G0_CMD_REG, 2 },
- [NITIO_G1_CMD] = { NISTC_G1_CMD_REG, 2 },
- [NITIO_G0_HW_SAVE] = { NISTC_G0_HW_SAVE_REG, 4 },
- [NITIO_G1_HW_SAVE] = { NISTC_G1_HW_SAVE_REG, 4 },
- [NITIO_G0_SW_SAVE] = { NISTC_G0_SAVE_REG, 4 },
- [NITIO_G1_SW_SAVE] = { NISTC_G1_SAVE_REG, 4 },
- [NITIO_G0_MODE] = { NISTC_G0_MODE_REG, 2 },
- [NITIO_G1_MODE] = { NISTC_G1_MODE_REG, 2 },
- [NITIO_G0_LOADA] = { NISTC_G0_LOADA_REG, 4 },
- [NITIO_G1_LOADA] = { NISTC_G1_LOADA_REG, 4 },
- [NITIO_G0_LOADB] = { NISTC_G0_LOADB_REG, 4 },
- [NITIO_G1_LOADB] = { NISTC_G1_LOADB_REG, 4 },
- [NITIO_G0_INPUT_SEL] = { NISTC_G0_INPUT_SEL_REG, 2 },
- [NITIO_G1_INPUT_SEL] = { NISTC_G1_INPUT_SEL_REG, 2 },
- [NITIO_G0_CNT_MODE] = { 0x1b0, 2 }, /* M-Series only */
- [NITIO_G1_CNT_MODE] = { 0x1b2, 2 }, /* M-Series only */
- [NITIO_G0_GATE2] = { 0x1b4, 2 }, /* M-Series only */
- [NITIO_G1_GATE2] = { 0x1b6, 2 }, /* M-Series only */
- [NITIO_G01_STATUS] = { NISTC_G01_STATUS_REG, 2 },
- [NITIO_G01_RESET] = { NISTC_RESET_REG, 2 },
- [NITIO_G01_STATUS1] = { NISTC_STATUS1_REG, 2 },
- [NITIO_G01_STATUS2] = { NISTC_STATUS2_REG, 2 },
- [NITIO_G0_DMA_CFG] = { 0x1b8, 2 }, /* M-Series only */
- [NITIO_G1_DMA_CFG] = { 0x1ba, 2 }, /* M-Series only */
- [NITIO_G0_DMA_STATUS] = { 0x1b8, 2 }, /* M-Series only */
- [NITIO_G1_DMA_STATUS] = { 0x1ba, 2 }, /* M-Series only */
- [NITIO_G0_ABZ] = { 0x1c0, 2 }, /* M-Series only */
- [NITIO_G1_ABZ] = { 0x1c2, 2 }, /* M-Series only */
- [NITIO_G0_INT_ACK] = { NISTC_INTA_ACK_REG, 2 },
- [NITIO_G1_INT_ACK] = { NISTC_INTB_ACK_REG, 2 },
- [NITIO_G0_STATUS] = { NISTC_AI_STATUS1_REG, 2 },
- [NITIO_G1_STATUS] = { NISTC_AO_STATUS1_REG, 2 },
- [NITIO_G0_INT_ENA] = { NISTC_INTA_ENA_REG, 2 },
- [NITIO_G1_INT_ENA] = { NISTC_INTB_ENA_REG, 2 },
-};
-
-static unsigned int ni_gpct_to_stc_register(struct comedi_device *dev,
- enum ni_gpct_register reg)
-{
- const struct mio_regmap *regmap;
-
- if (reg < ARRAY_SIZE(ni_gpct_to_stc_regmap)) {
- regmap = &ni_gpct_to_stc_regmap[reg];
- } else {
- dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n",
- __func__, reg);
- return 0;
- }
-
- return regmap->mio_reg;
-}
-
-static void ni_gpct_write_register(struct ni_gpct *counter, unsigned int bits,
- enum ni_gpct_register reg)
-{
- struct comedi_device *dev = counter->counter_dev->dev;
- unsigned int stc_register = ni_gpct_to_stc_register(dev, reg);
-
- if (stc_register == 0)
- return;
-
- switch (reg) {
- /* m-series only registers */
- case NITIO_G0_CNT_MODE:
- case NITIO_G1_CNT_MODE:
- case NITIO_G0_GATE2:
- case NITIO_G1_GATE2:
- case NITIO_G0_DMA_CFG:
- case NITIO_G1_DMA_CFG:
- case NITIO_G0_ABZ:
- case NITIO_G1_ABZ:
- ni_writew(dev, bits, stc_register);
- break;
-
- /* 32 bit registers */
- case NITIO_G0_LOADA:
- case NITIO_G1_LOADA:
- case NITIO_G0_LOADB:
- case NITIO_G1_LOADB:
- ni_stc_writel(dev, bits, stc_register);
- break;
-
- /* 16 bit registers */
- case NITIO_G0_INT_ENA:
- ni_set_bitfield(dev, stc_register,
- NISTC_INTA_ENA_G0_GATE | NISTC_INTA_ENA_G0_TC,
- bits);
- break;
- case NITIO_G1_INT_ENA:
- ni_set_bitfield(dev, stc_register,
- NISTC_INTB_ENA_G1_GATE | NISTC_INTB_ENA_G1_TC,
- bits);
- break;
- default:
- ni_stc_writew(dev, bits, stc_register);
- }
-}
-
-static unsigned int ni_gpct_read_register(struct ni_gpct *counter,
- enum ni_gpct_register reg)
-{
- struct comedi_device *dev = counter->counter_dev->dev;
- unsigned int stc_register = ni_gpct_to_stc_register(dev, reg);
-
- if (stc_register == 0)
- return 0;
-
- switch (reg) {
- /* m-series only registers */
- case NITIO_G0_DMA_STATUS:
- case NITIO_G1_DMA_STATUS:
- return ni_readw(dev, stc_register);
-
- /* 32 bit registers */
- case NITIO_G0_HW_SAVE:
- case NITIO_G1_HW_SAVE:
- case NITIO_G0_SW_SAVE:
- case NITIO_G1_SW_SAVE:
- return ni_stc_readl(dev, stc_register);
-
- /* 16 bit registers */
- default:
- return ni_stc_readw(dev, stc_register);
- }
-}
-
-static int ni_freq_out_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int val = NISTC_CLK_FOUT_TO_DIVIDER(devpriv->clock_and_fout);
- int i;
-
- for (i = 0; i < insn->n; i++)
- data[i] = val;
-
- return insn->n;
-}
-
-static int ni_freq_out_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
-
- if (insn->n) {
- unsigned int val = data[insn->n - 1];
-
- devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_ENA;
- ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
- devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_DIVIDER_MASK;
-
- /* use the last data value to set the fout divider */
- devpriv->clock_and_fout |= NISTC_CLK_FOUT_DIVIDER(val);
-
- devpriv->clock_and_fout |= NISTC_CLK_FOUT_ENA;
- ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
- }
- return insn->n;
-}
-
-static int ni_freq_out_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_CLOCK_SRC:
- switch (data[1]) {
- case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
- devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_TIMEBASE_SEL;
- break;
- case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
- devpriv->clock_and_fout |= NISTC_CLK_FOUT_TIMEBASE_SEL;
- break;
- default:
- return -EINVAL;
- }
- ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- if (devpriv->clock_and_fout & NISTC_CLK_FOUT_TIMEBASE_SEL) {
- data[1] = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
- data[2] = TIMEBASE_2_NS;
- } else {
- data[1] = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
- data[2] = TIMEBASE_1_NS * 2;
- }
- break;
- default:
- return -EINVAL;
- }
- return insn->n;
-}
-
-static int ni_8255_callback(struct comedi_device *dev,
- int dir, int port, int data, unsigned long iobase)
-{
- if (dir) {
- ni_writeb(dev, data, iobase + 2 * port);
- return 0;
- }
-
- return ni_readb(dev, iobase + 2 * port);
-}
-
-static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
-
- data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
- data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
- return 3;
-}
-
-static int ni_m_series_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int up_count, down_count;
-
- switch (data[0]) {
- case INSN_CONFIG_PWM_OUTPUT:
- switch (data[1]) {
- case CMDF_ROUND_NEAREST:
- up_count = DIV_ROUND_CLOSEST(data[2],
- devpriv->clock_ns);
- break;
- case CMDF_ROUND_DOWN:
- up_count = data[2] / devpriv->clock_ns;
- break;
- case CMDF_ROUND_UP:
- up_count =
- DIV_ROUND_UP(data[2], devpriv->clock_ns);
- break;
- default:
- return -EINVAL;
- }
- switch (data[3]) {
- case CMDF_ROUND_NEAREST:
- down_count = DIV_ROUND_CLOSEST(data[4],
- devpriv->clock_ns);
- break;
- case CMDF_ROUND_DOWN:
- down_count = data[4] / devpriv->clock_ns;
- break;
- case CMDF_ROUND_UP:
- down_count =
- DIV_ROUND_UP(data[4], devpriv->clock_ns);
- break;
- default:
- return -EINVAL;
- }
- if (up_count * devpriv->clock_ns != data[2] ||
- down_count * devpriv->clock_ns != data[4]) {
- data[2] = up_count * devpriv->clock_ns;
- data[4] = down_count * devpriv->clock_ns;
- return -EAGAIN;
- }
- ni_writel(dev, NI_M_CAL_PWM_HIGH_TIME(up_count) |
- NI_M_CAL_PWM_LOW_TIME(down_count),
- NI_M_CAL_PWM_REG);
- devpriv->pwm_up_count = up_count;
- devpriv->pwm_down_count = down_count;
- return 5;
- case INSN_CONFIG_GET_PWM_OUTPUT:
- return ni_get_pwm_config(dev, data);
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int ni_6143_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int up_count, down_count;
-
- switch (data[0]) {
- case INSN_CONFIG_PWM_OUTPUT:
- switch (data[1]) {
- case CMDF_ROUND_NEAREST:
- up_count = DIV_ROUND_CLOSEST(data[2],
- devpriv->clock_ns);
- break;
- case CMDF_ROUND_DOWN:
- up_count = data[2] / devpriv->clock_ns;
- break;
- case CMDF_ROUND_UP:
- up_count =
- DIV_ROUND_UP(data[2], devpriv->clock_ns);
- break;
- default:
- return -EINVAL;
- }
- switch (data[3]) {
- case CMDF_ROUND_NEAREST:
- down_count = DIV_ROUND_CLOSEST(data[4],
- devpriv->clock_ns);
- break;
- case CMDF_ROUND_DOWN:
- down_count = data[4] / devpriv->clock_ns;
- break;
- case CMDF_ROUND_UP:
- down_count =
- DIV_ROUND_UP(data[4], devpriv->clock_ns);
- break;
- default:
- return -EINVAL;
- }
- if (up_count * devpriv->clock_ns != data[2] ||
- down_count * devpriv->clock_ns != data[4]) {
- data[2] = up_count * devpriv->clock_ns;
- data[4] = down_count * devpriv->clock_ns;
- return -EAGAIN;
- }
- ni_writel(dev, up_count, NI6143_CALIB_HI_TIME_REG);
- devpriv->pwm_up_count = up_count;
- ni_writel(dev, down_count, NI6143_CALIB_LO_TIME_REG);
- devpriv->pwm_down_count = down_count;
- return 5;
- case INSN_CONFIG_GET_PWM_OUTPUT:
- return ni_get_pwm_config(dev, data);
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int pack_mb88341(int addr, int val, int *bitstring)
-{
- /*
- * Fujitsu MB 88341
- * Note that address bits are reversed. Thanks to
- * Ingo Keen for noticing this.
- *
- * Note also that the 88341 expects address values from
- * 1-12, whereas we use channel numbers 0-11. The NI
- * docs use 1-12, also, so be careful here.
- */
- addr++;
- *bitstring = ((addr & 0x1) << 11) |
- ((addr & 0x2) << 9) |
- ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
- return 12;
-}
-
-static int pack_dac8800(int addr, int val, int *bitstring)
-{
- *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
- return 11;
-}
-
-static int pack_dac8043(int addr, int val, int *bitstring)
-{
- *bitstring = val & 0xfff;
- return 12;
-}
-
-static int pack_ad8522(int addr, int val, int *bitstring)
-{
- *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
- return 16;
-}
-
-static int pack_ad8804(int addr, int val, int *bitstring)
-{
- *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
- return 12;
-}
-
-static int pack_ad8842(int addr, int val, int *bitstring)
-{
- *bitstring = ((addr + 1) << 8) | (val & 0xff);
- return 12;
-}
-
-struct caldac_struct {
- int n_chans;
- int n_bits;
- int (*packbits)(int address, int value, int *bitstring);
-};
-
-static struct caldac_struct caldacs[] = {
- [mb88341] = {12, 8, pack_mb88341},
- [dac8800] = {8, 8, pack_dac8800},
- [dac8043] = {1, 12, pack_dac8043},
- [ad8522] = {2, 12, pack_ad8522},
- [ad8804] = {12, 8, pack_ad8804},
- [ad8842] = {8, 8, pack_ad8842},
- [ad8804_debug] = {16, 8, pack_ad8804},
-};
-
-static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
- unsigned int cmd;
- int i;
- int type;
-
- if (devpriv->caldacs[addr] == val)
- return;
- devpriv->caldacs[addr] = val;
-
- for (i = 0; i < 3; i++) {
- type = board->caldac[i];
- if (type == caldac_none)
- break;
- if (addr < caldacs[type].n_chans) {
- bits = caldacs[type].packbits(addr, val, &bitstring);
- loadbit = NI_E_SERIAL_CMD_DAC_LD(i);
- break;
- }
- addr -= caldacs[type].n_chans;
- }
-
- /* bits will be 0 if there is no caldac for the given addr */
- if (bits == 0)
- return;
-
- for (bit = 1 << (bits - 1); bit; bit >>= 1) {
- cmd = (bit & bitstring) ? NI_E_SERIAL_CMD_SDATA : 0;
- ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
- udelay(1);
- ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG);
- udelay(1);
- }
- ni_writeb(dev, loadbit, NI_E_SERIAL_CMD_REG);
- udelay(1);
- ni_writeb(dev, 0, NI_E_SERIAL_CMD_REG);
-}
-
-static int ni_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (insn->n) {
- /* only bother writing the last sample to the channel */
- ni_write_caldac(dev, CR_CHAN(insn->chanspec),
- data[insn->n - 1]);
- }
-
- return insn->n;
-}
-
-static int ni_calib_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int i;
-
- for (i = 0; i < insn->n; i++)
- data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
-
- return insn->n;
-}
-
-static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- int i, j;
- int n_dacs;
- int n_chans = 0;
- int n_bits;
- int diffbits = 0;
- int type;
- int chan;
-
- type = board->caldac[0];
- if (type == caldac_none)
- return;
- n_bits = caldacs[type].n_bits;
- for (i = 0; i < 3; i++) {
- type = board->caldac[i];
- if (type == caldac_none)
- break;
- if (caldacs[type].n_bits != n_bits)
- diffbits = 1;
- n_chans += caldacs[type].n_chans;
- }
- n_dacs = i;
- s->n_chan = n_chans;
-
- if (diffbits) {
- unsigned int *maxdata_list = devpriv->caldac_maxdata_list;
-
- if (n_chans > MAX_N_CALDACS)
- dev_err(dev->class_dev,
- "BUG! MAX_N_CALDACS too small\n");
- s->maxdata_list = maxdata_list;
- chan = 0;
- for (i = 0; i < n_dacs; i++) {
- type = board->caldac[i];
- for (j = 0; j < caldacs[type].n_chans; j++) {
- maxdata_list[chan] =
- (1 << caldacs[type].n_bits) - 1;
- chan++;
- }
- }
-
- for (chan = 0; chan < s->n_chan; chan++)
- ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
- } else {
- type = board->caldac[0];
- s->maxdata = (1 << caldacs[type].n_bits) - 1;
-
- for (chan = 0; chan < s->n_chan; chan++)
- ni_write_caldac(dev, i, s->maxdata / 2);
- }
-}
-
-static int ni_read_eeprom(struct comedi_device *dev, int addr)
-{
- unsigned int cmd = NI_E_SERIAL_CMD_EEPROM_CS;
- int bit;
- int bitstring;
-
- bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
- ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
- for (bit = 0x8000; bit; bit >>= 1) {
- if (bit & bitstring)
- cmd |= NI_E_SERIAL_CMD_SDATA;
- else
- cmd &= ~NI_E_SERIAL_CMD_SDATA;
-
- ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
- ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG);
- }
- cmd = NI_E_SERIAL_CMD_EEPROM_CS;
- bitstring = 0;
- for (bit = 0x80; bit; bit >>= 1) {
- ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
- ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG);
- if (ni_readb(dev, NI_E_STATUS_REG) & NI_E_STATUS_PROMOUT)
- bitstring |= bit;
- }
- ni_writeb(dev, 0, NI_E_SERIAL_CMD_REG);
-
- return bitstring;
-}
-
-static int ni_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int val;
- unsigned int i;
-
- if (insn->n) {
- val = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
- for (i = 0; i < insn->n; i++)
- data[i] = val;
- }
- return insn->n;
-}
-
-static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int i;
-
- for (i = 0; i < insn->n; i++)
- data[i] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
-
- return insn->n;
-}
-
-static unsigned int ni_old_get_pfi_routing(struct comedi_device *dev,
- unsigned int chan)
-{
- /* pre-m-series boards have fixed signals on pfi pins */
- switch (chan) {
- case 0:
- return NI_PFI_OUTPUT_AI_START1;
- case 1:
- return NI_PFI_OUTPUT_AI_START2;
- case 2:
- return NI_PFI_OUTPUT_AI_CONVERT;
- case 3:
- return NI_PFI_OUTPUT_G_SRC1;
- case 4:
- return NI_PFI_OUTPUT_G_GATE1;
- case 5:
- return NI_PFI_OUTPUT_AO_UPDATE_N;
- case 6:
- return NI_PFI_OUTPUT_AO_START1;
- case 7:
- return NI_PFI_OUTPUT_AI_START_PULSE;
- case 8:
- return NI_PFI_OUTPUT_G_SRC0;
- case 9:
- return NI_PFI_OUTPUT_G_GATE0;
- default:
- dev_err(dev->class_dev, "bug, unhandled case in switch.\n");
- break;
- }
- return 0;
-}
-
-static int ni_old_set_pfi_routing(struct comedi_device *dev,
- unsigned int chan, unsigned int source)
-{
- /* pre-m-series boards have fixed signals on pfi pins */
- if (source != ni_old_get_pfi_routing(dev, chan))
- return -EINVAL;
- return 2;
-}
-
-static unsigned int ni_m_series_get_pfi_routing(struct comedi_device *dev,
- unsigned int chan)
-{
- struct ni_private *devpriv = dev->private;
- const unsigned int array_offset = chan / 3;
-
- return NI_M_PFI_OUT_SEL_TO_SRC(chan,
- devpriv->pfi_output_select_reg[array_offset]);
-}
-
-static int ni_m_series_set_pfi_routing(struct comedi_device *dev,
- unsigned int chan, unsigned int source)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int index = chan / 3;
- unsigned short val = devpriv->pfi_output_select_reg[index];
-
- if ((source & 0x1f) != source)
- return -EINVAL;
-
- val &= ~NI_M_PFI_OUT_SEL_MASK(chan);
- val |= NI_M_PFI_OUT_SEL(chan, source);
- ni_writew(dev, val, NI_M_PFI_OUT_SEL_REG(index));
- devpriv->pfi_output_select_reg[index] = val;
-
- return 2;
-}
-
-static unsigned int ni_get_pfi_routing(struct comedi_device *dev,
- unsigned int chan)
-{
- struct ni_private *devpriv = dev->private;
-
- if (chan >= NI_PFI(0)) {
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
- }
- return (devpriv->is_m_series)
- ? ni_m_series_get_pfi_routing(dev, chan)
- : ni_old_get_pfi_routing(dev, chan);
-}
-
-/* Sets the output mux for the specified PFI channel. */
-static int ni_set_pfi_routing(struct comedi_device *dev,
- unsigned int chan, unsigned int source)
-{
- struct ni_private *devpriv = dev->private;
-
- if (chan >= NI_PFI(0)) {
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
- }
- return (devpriv->is_m_series)
- ? ni_m_series_set_pfi_routing(dev, chan, source)
- : ni_old_set_pfi_routing(dev, chan, source);
-}
-
-static int ni_config_pfi_filter(struct comedi_device *dev,
- unsigned int chan,
- enum ni_pfi_filter_select filter)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int bits;
-
- if (!devpriv->is_m_series)
- return -ENOTSUPP;
-
- if (chan >= NI_PFI(0)) {
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
- }
-
- bits = ni_readl(dev, NI_M_PFI_FILTER_REG);
- bits &= ~NI_M_PFI_FILTER_SEL_MASK(chan);
- bits |= NI_M_PFI_FILTER_SEL(chan, filter);
- ni_writel(dev, bits, NI_M_PFI_FILTER_REG);
- return 0;
-}
-
-static void ni_set_pfi_direction(struct comedi_device *dev, int chan,
- unsigned int direction)
-{
- if (chan >= NI_PFI(0)) {
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
- }
- direction = (direction == COMEDI_OUTPUT) ? 1u : 0u;
- ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, direction);
-}
-
-static int ni_get_pfi_direction(struct comedi_device *dev, int chan)
-{
- struct ni_private *devpriv = dev->private;
-
- if (chan >= NI_PFI(0)) {
- /* allow new and old names of pfi channels to work. */
- chan -= NI_PFI(0);
- }
- return devpriv->io_bidirection_pin_reg & (1 << chan) ?
- COMEDI_OUTPUT : COMEDI_INPUT;
-}
-
-static int ni_pfi_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan;
-
- if (insn->n < 1)
- return -EINVAL;
-
- chan = CR_CHAN(insn->chanspec);
-
- switch (data[0]) {
- case COMEDI_OUTPUT:
- case COMEDI_INPUT:
- ni_set_pfi_direction(dev, chan, data[0]);
- break;
- case INSN_CONFIG_DIO_QUERY:
- data[1] = ni_get_pfi_direction(dev, chan);
- break;
- case INSN_CONFIG_SET_ROUTING:
- return ni_set_pfi_routing(dev, chan, data[1]);
- case INSN_CONFIG_GET_ROUTING:
- data[1] = ni_get_pfi_routing(dev, chan);
- break;
- case INSN_CONFIG_FILTER:
- return ni_config_pfi_filter(dev, chan, data[1]);
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int ni_pfi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
-
- if (!devpriv->is_m_series)
- return -ENOTSUPP;
-
- if (comedi_dio_update_state(s, data))
- ni_writew(dev, s->state, NI_M_PFI_DO_REG);
-
- data[1] = ni_readw(dev, NI_M_PFI_DI_REG);
-
- return insn->n;
-}
-
-static int cs5529_wait_for_idle(struct comedi_device *dev)
-{
- unsigned short status;
- const int timeout = HZ;
- int i;
-
- for (i = 0; i < timeout; i++) {
- status = ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG);
- if ((status & NI67XX_CAL_STATUS_BUSY) == 0)
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(1))
- return -EIO;
- }
- if (i == timeout) {
- dev_err(dev->class_dev, "timeout\n");
- return -ETIME;
- }
- return 0;
-}
-
-static void cs5529_command(struct comedi_device *dev, unsigned short value)
-{
- static const int timeout = 100;
- int i;
-
- ni_ao_win_outw(dev, value, NI67XX_CAL_CMD_REG);
- /* give time for command to start being serially clocked into cs5529.
- * this insures that the NI67XX_CAL_STATUS_BUSY bit will get properly
- * set before we exit this function.
- */
- for (i = 0; i < timeout; i++) {
- if (ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG) &
- NI67XX_CAL_STATUS_BUSY)
- break;
- udelay(1);
- }
- if (i == timeout)
- dev_err(dev->class_dev,
- "possible problem - never saw adc go busy?\n");
-}
-
-static int cs5529_do_conversion(struct comedi_device *dev,
- unsigned short *data)
-{
- int retval;
- unsigned short status;
-
- cs5529_command(dev, CS5529_CMD_CB | CS5529_CMD_SINGLE_CONV);
- retval = cs5529_wait_for_idle(dev);
- if (retval) {
- dev_err(dev->class_dev,
- "timeout or signal in %s()\n", __func__);
- return -ETIME;
- }
- status = ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG);
- if (status & NI67XX_CAL_STATUS_OSC_DETECT) {
- dev_err(dev->class_dev,
- "cs5529 conversion error, status CSS_OSC_DETECT\n");
- return -EIO;
- }
- if (status & NI67XX_CAL_STATUS_OVERRANGE) {
- dev_err(dev->class_dev,
- "cs5529 conversion error, overrange (ignoring)\n");
- }
- if (data) {
- *data = ni_ao_win_inw(dev, NI67XX_CAL_DATA_REG);
- /* cs5529 returns 16 bit signed data in bipolar mode */
- *data ^= BIT(15);
- }
- return 0;
-}
-
-static int cs5529_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int n, retval;
- unsigned short sample;
- unsigned int channel_select;
- const unsigned int INTERNAL_REF = 0x1000;
-
- /*
- * Set calibration adc source. Docs lie, reference select bits 8 to 11
- * do nothing. bit 12 seems to chooses internal reference voltage, bit
- * 13 causes the adc input to go overrange (maybe reads external
- * reference?)
- */
- if (insn->chanspec & CR_ALT_SOURCE)
- channel_select = INTERNAL_REF;
- else
- channel_select = CR_CHAN(insn->chanspec);
- ni_ao_win_outw(dev, channel_select, NI67XX_AO_CAL_CHAN_SEL_REG);
-
- for (n = 0; n < insn->n; n++) {
- retval = cs5529_do_conversion(dev, &sample);
- if (retval < 0)
- return retval;
- data[n] = sample;
- }
- return insn->n;
-}
-
-static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
- unsigned int reg_select_bits)
-{
- ni_ao_win_outw(dev, (value >> 16) & 0xff, NI67XX_CAL_CFG_HI_REG);
- ni_ao_win_outw(dev, value & 0xffff, NI67XX_CAL_CFG_LO_REG);
- reg_select_bits &= CS5529_CMD_REG_MASK;
- cs5529_command(dev, CS5529_CMD_CB | reg_select_bits);
- if (cs5529_wait_for_idle(dev))
- dev_err(dev->class_dev,
- "timeout or signal in %s\n", __func__);
-}
-
-static int init_cs5529(struct comedi_device *dev)
-{
- unsigned int config_bits = CS5529_CFG_PORT_FLAG |
- CS5529_CFG_WORD_RATE_2180;
-
-#if 1
- /* do self-calibration */
- cs5529_config_write(dev, config_bits | CS5529_CFG_CALIB_BOTH_SELF,
- CS5529_CFG_REG);
- /* need to force a conversion for calibration to run */
- cs5529_do_conversion(dev, NULL);
-#else
- /* force gain calibration to 1 */
- cs5529_config_write(dev, 0x400000, CS5529_GAIN_REG);
- cs5529_config_write(dev, config_bits | CS5529_CFG_CALIB_OFFSET_SELF,
- CS5529_CFG_REG);
- if (cs5529_wait_for_idle(dev))
- dev_err(dev->class_dev,
- "timeout or signal in %s\n", __func__);
-#endif
- return 0;
-}
-
-/*
- * Find best multiplier/divider to try and get the PLL running at 80 MHz
- * given an arbitrary frequency input clock.
- */
-static int ni_mseries_get_pll_parameters(unsigned int reference_period_ns,
- unsigned int *freq_divider,
- unsigned int *freq_multiplier,
- unsigned int *actual_period_ns)
-{
- unsigned int div;
- unsigned int best_div = 1;
- unsigned int mult;
- unsigned int best_mult = 1;
- static const unsigned int pico_per_nano = 1000;
- const unsigned int reference_picosec = reference_period_ns *
- pico_per_nano;
- /*
- * m-series wants the phased-locked loop to output 80MHz, which is
- * divided by 4 to 20 MHz for most timing clocks
- */
- static const unsigned int target_picosec = 12500;
- int best_period_picosec = 0;
-
- for (div = 1; div <= NI_M_PLL_MAX_DIVISOR; ++div) {
- for (mult = 1; mult <= NI_M_PLL_MAX_MULTIPLIER; ++mult) {
- unsigned int new_period_ps =
- (reference_picosec * div) / mult;
- if (abs(new_period_ps - target_picosec) <
- abs(best_period_picosec - target_picosec)) {
- best_period_picosec = new_period_ps;
- best_div = div;
- best_mult = mult;
- }
- }
- }
- if (best_period_picosec == 0)
- return -EIO;
-
- *freq_divider = best_div;
- *freq_multiplier = best_mult;
- /* return the actual period (* fudge factor for 80 to 20 MHz) */
- *actual_period_ns = DIV_ROUND_CLOSEST(best_period_picosec * 4,
- pico_per_nano);
- return 0;
-}
-
-static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
- unsigned int source,
- unsigned int period_ns)
-{
- struct ni_private *devpriv = dev->private;
- static const unsigned int min_period_ns = 50;
- static const unsigned int max_period_ns = 1000;
- static const unsigned int timeout = 1000;
- unsigned int pll_control_bits;
- unsigned int freq_divider;
- unsigned int freq_multiplier;
- unsigned int rtsi;
- unsigned int i;
- int retval;
-
- if (source == NI_MIO_PLL_PXI10_CLOCK)
- period_ns = 100;
- /*
- * These limits are somewhat arbitrary, but NI advertises 1 to 20MHz
- * range so we'll use that.
- */
- if (period_ns < min_period_ns || period_ns > max_period_ns) {
- dev_err(dev->class_dev,
- "%s: you must specify an input clock frequency between %i and %i nanosec for the phased-lock loop\n",
- __func__, min_period_ns, max_period_ns);
- return -EINVAL;
- }
- devpriv->rtsi_trig_direction_reg &= ~NISTC_RTSI_TRIG_USE_CLK;
- ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- NISTC_RTSI_TRIG_DIR_REG);
- pll_control_bits = NI_M_PLL_CTRL_ENA | NI_M_PLL_CTRL_VCO_MODE_75_150MHZ;
- devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_TIMEBASE1_PLL |
- NI_M_CLK_FOUT2_TIMEBASE3_PLL;
- devpriv->clock_and_fout2 &= ~NI_M_CLK_FOUT2_PLL_SRC_MASK;
- switch (source) {
- case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
- devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_PLL_SRC_STAR;
- break;
- case NI_MIO_PLL_PXI10_CLOCK:
- /* pxi clock is 10MHz */
- devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_PLL_SRC_PXI10;
- break;
- default:
- for (rtsi = 0; rtsi <= NI_M_MAX_RTSI_CHAN; ++rtsi) {
- if (source == NI_MIO_PLL_RTSI_CLOCK(rtsi)) {
- devpriv->clock_and_fout2 |=
- NI_M_CLK_FOUT2_PLL_SRC_RTSI(rtsi);
- break;
- }
- }
- if (rtsi > NI_M_MAX_RTSI_CHAN)
- return -EINVAL;
- break;
- }
- retval = ni_mseries_get_pll_parameters(period_ns,
- &freq_divider,
- &freq_multiplier,
- &devpriv->clock_ns);
- if (retval < 0) {
- dev_err(dev->class_dev,
- "bug, failed to find pll parameters\n");
- return retval;
- }
-
- ni_writew(dev, devpriv->clock_and_fout2, NI_M_CLK_FOUT2_REG);
- pll_control_bits |= NI_M_PLL_CTRL_DIVISOR(freq_divider) |
- NI_M_PLL_CTRL_MULTIPLIER(freq_multiplier);
-
- ni_writew(dev, pll_control_bits, NI_M_PLL_CTRL_REG);
- devpriv->clock_source = source;
- /* it takes a few hundred microseconds for PLL to lock */
- for (i = 0; i < timeout; ++i) {
- if (ni_readw(dev, NI_M_PLL_STATUS_REG) & NI_M_PLL_STATUS_LOCKED)
- break;
- udelay(1);
- }
- if (i == timeout) {
- dev_err(dev->class_dev,
- "%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns\n",
- __func__, source, period_ns);
- return -ETIMEDOUT;
- }
- return 3;
-}
-
-static int ni_set_master_clock(struct comedi_device *dev,
- unsigned int source, unsigned int period_ns)
-{
- struct ni_private *devpriv = dev->private;
-
- if (source == NI_MIO_INTERNAL_CLOCK) {
- devpriv->rtsi_trig_direction_reg &= ~NISTC_RTSI_TRIG_USE_CLK;
- ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- NISTC_RTSI_TRIG_DIR_REG);
- devpriv->clock_ns = TIMEBASE_1_NS;
- if (devpriv->is_m_series) {
- devpriv->clock_and_fout2 &=
- ~(NI_M_CLK_FOUT2_TIMEBASE1_PLL |
- NI_M_CLK_FOUT2_TIMEBASE3_PLL);
- ni_writew(dev, devpriv->clock_and_fout2,
- NI_M_CLK_FOUT2_REG);
- ni_writew(dev, 0, NI_M_PLL_CTRL_REG);
- }
- devpriv->clock_source = source;
- } else {
- if (devpriv->is_m_series) {
- return ni_mseries_set_pll_master_clock(dev, source,
- period_ns);
- } else {
- if (source == NI_MIO_RTSI_CLOCK) {
- devpriv->rtsi_trig_direction_reg |=
- NISTC_RTSI_TRIG_USE_CLK;
- ni_stc_writew(dev,
- devpriv->rtsi_trig_direction_reg,
- NISTC_RTSI_TRIG_DIR_REG);
- if (period_ns == 0) {
- dev_err(dev->class_dev,
- "we don't handle an unspecified clock period correctly yet, returning error\n");
- return -EINVAL;
- }
- devpriv->clock_ns = period_ns;
- devpriv->clock_source = source;
- } else {
- return -EINVAL;
- }
- }
- }
- return 3;
-}
-
-static int ni_valid_rtsi_output_source(struct comedi_device *dev,
- unsigned int chan, unsigned int source)
-{
- struct ni_private *devpriv = dev->private;
-
- if (chan >= NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) {
- if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
- if (source == NI_RTSI_OUTPUT_RTSI_OSC)
- return 1;
-
- dev_err(dev->class_dev,
- "%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards\n",
- __func__, chan, NISTC_RTSI_TRIG_OLD_CLK_CHAN);
- return 0;
- }
- return 0;
- }
- switch (source) {
- case NI_RTSI_OUTPUT_ADR_START1:
- case NI_RTSI_OUTPUT_ADR_START2:
- case NI_RTSI_OUTPUT_SCLKG:
- case NI_RTSI_OUTPUT_DACUPDN:
- case NI_RTSI_OUTPUT_DA_START1:
- case NI_RTSI_OUTPUT_G_SRC0:
- case NI_RTSI_OUTPUT_G_GATE0:
- case NI_RTSI_OUTPUT_RGOUT0:
- case NI_RTSI_OUTPUT_RTSI_BRD(0):
- case NI_RTSI_OUTPUT_RTSI_BRD(1):
- case NI_RTSI_OUTPUT_RTSI_BRD(2):
- case NI_RTSI_OUTPUT_RTSI_BRD(3):
- return 1;
- case NI_RTSI_OUTPUT_RTSI_OSC:
- return (devpriv->is_m_series) ? 1 : 0;
- default:
- return 0;
- }
-}
-
-static int ni_set_rtsi_routing(struct comedi_device *dev,
- unsigned int chan, unsigned int src)
-{
- struct ni_private *devpriv = dev->private;
-
- if (chan >= TRIGGER_LINE(0))
- /* allow new and old names of rtsi channels to work. */
- chan -= TRIGGER_LINE(0);
-
- if (ni_valid_rtsi_output_source(dev, chan, src) == 0)
- return -EINVAL;
- if (chan < 4) {
- devpriv->rtsi_trig_a_output_reg &= ~NISTC_RTSI_TRIG_MASK(chan);
- devpriv->rtsi_trig_a_output_reg |= NISTC_RTSI_TRIG(chan, src);
- ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
- NISTC_RTSI_TRIGA_OUT_REG);
- } else if (chan < NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) {
- devpriv->rtsi_trig_b_output_reg &= ~NISTC_RTSI_TRIG_MASK(chan);
- devpriv->rtsi_trig_b_output_reg |= NISTC_RTSI_TRIG(chan, src);
- ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
- NISTC_RTSI_TRIGB_OUT_REG);
- } else if (chan != NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
- /* probably should never reach this, since the
- * ni_valid_rtsi_output_source above errors out if chan is too
- * high
- */
- dev_err(dev->class_dev, "%s: unknown rtsi channel\n", __func__);
- return -EINVAL;
- }
- return 2;
-}
-
-static unsigned int ni_get_rtsi_routing(struct comedi_device *dev,
- unsigned int chan)
-{
- struct ni_private *devpriv = dev->private;
-
- if (chan >= TRIGGER_LINE(0))
- /* allow new and old names of rtsi channels to work. */
- chan -= TRIGGER_LINE(0);
-
- if (chan < 4) {
- return NISTC_RTSI_TRIG_TO_SRC(chan,
- devpriv->rtsi_trig_a_output_reg);
- } else if (chan < NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) {
- return NISTC_RTSI_TRIG_TO_SRC(chan,
- devpriv->rtsi_trig_b_output_reg);
- } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
- return NI_RTSI_OUTPUT_RTSI_OSC;
- }
-
- dev_err(dev->class_dev, "%s: unknown rtsi channel\n", __func__);
- return -EINVAL;
-}
-
-static void ni_set_rtsi_direction(struct comedi_device *dev, int chan,
- unsigned int direction)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int max_chan = NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series);
-
- if (chan >= TRIGGER_LINE(0))
- /* allow new and old names of rtsi channels to work. */
- chan -= TRIGGER_LINE(0);
-
- if (direction == COMEDI_OUTPUT) {
- if (chan < max_chan) {
- devpriv->rtsi_trig_direction_reg |=
- NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series);
- } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
- devpriv->rtsi_trig_direction_reg |=
- NISTC_RTSI_TRIG_DRV_CLK;
- }
- } else {
- if (chan < max_chan) {
- devpriv->rtsi_trig_direction_reg &=
- ~NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series);
- } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
- devpriv->rtsi_trig_direction_reg &=
- ~NISTC_RTSI_TRIG_DRV_CLK;
- }
- }
- ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- NISTC_RTSI_TRIG_DIR_REG);
-}
-
-static int ni_get_rtsi_direction(struct comedi_device *dev, int chan)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int max_chan = NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series);
-
- if (chan >= TRIGGER_LINE(0))
- /* allow new and old names of rtsi channels to work. */
- chan -= TRIGGER_LINE(0);
-
- if (chan < max_chan) {
- return (devpriv->rtsi_trig_direction_reg &
- NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series))
- ? COMEDI_OUTPUT : COMEDI_INPUT;
- } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
- return (devpriv->rtsi_trig_direction_reg &
- NISTC_RTSI_TRIG_DRV_CLK)
- ? COMEDI_OUTPUT : COMEDI_INPUT;
- }
- return -EINVAL;
-}
-
-static int ni_rtsi_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- switch (data[0]) {
- case COMEDI_OUTPUT:
- case COMEDI_INPUT:
- ni_set_rtsi_direction(dev, chan, data[0]);
- break;
- case INSN_CONFIG_DIO_QUERY: {
- int ret = ni_get_rtsi_direction(dev, chan);
-
- if (ret < 0)
- return ret;
- data[1] = ret;
- return 2;
- }
- case INSN_CONFIG_SET_CLOCK_SRC:
- return ni_set_master_clock(dev, data[1], data[2]);
- case INSN_CONFIG_GET_CLOCK_SRC:
- data[1] = devpriv->clock_source;
- data[2] = devpriv->clock_ns;
- return 3;
- case INSN_CONFIG_SET_ROUTING:
- return ni_set_rtsi_routing(dev, chan, data[1]);
- case INSN_CONFIG_GET_ROUTING: {
- int ret = ni_get_rtsi_routing(dev, chan);
-
- if (ret < 0)
- return ret;
- data[1] = ret;
- return 2;
- }
- default:
- return -EINVAL;
- }
- return 1;
-}
-
-static int ni_rtsi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = 0;
-
- return insn->n;
-}
-
-/*
- * Default routing for RTSI trigger lines.
- *
- * These values are used here in the init function, as well as in the
- * disconnect_route function, after a RTSI route has been disconnected.
- */
-static const int default_rtsi_routing[] = {
- [0] = NI_RTSI_OUTPUT_ADR_START1,
- [1] = NI_RTSI_OUTPUT_ADR_START2,
- [2] = NI_RTSI_OUTPUT_SCLKG,
- [3] = NI_RTSI_OUTPUT_DACUPDN,
- [4] = NI_RTSI_OUTPUT_DA_START1,
- [5] = NI_RTSI_OUTPUT_G_SRC0,
- [6] = NI_RTSI_OUTPUT_G_GATE0,
- [7] = NI_RTSI_OUTPUT_RTSI_OSC,
-};
-
-/*
- * Route signals through RGOUT0 terminal.
- * @reg: raw register value of RGOUT0 bits (only bit0 is important).
- * @dev: comedi device handle.
- */
-static void set_rgout0_reg(int reg, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->is_m_series) {
- devpriv->rtsi_trig_direction_reg &=
- ~NISTC_RTSI_TRIG_DIR_SUB_SEL1;
- devpriv->rtsi_trig_direction_reg |=
- (reg << NISTC_RTSI_TRIG_DIR_SUB_SEL1_SHIFT) &
- NISTC_RTSI_TRIG_DIR_SUB_SEL1;
- ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- NISTC_RTSI_TRIG_DIR_REG);
- } else {
- devpriv->rtsi_trig_b_output_reg &= ~NISTC_RTSI_TRIGB_SUB_SEL1;
- devpriv->rtsi_trig_b_output_reg |=
- (reg << NISTC_RTSI_TRIGB_SUB_SEL1_SHIFT) &
- NISTC_RTSI_TRIGB_SUB_SEL1;
- ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
- NISTC_RTSI_TRIGB_OUT_REG);
- }
-}
-
-static int get_rgout0_reg(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int reg;
-
- if (devpriv->is_m_series)
- reg = (devpriv->rtsi_trig_direction_reg &
- NISTC_RTSI_TRIG_DIR_SUB_SEL1)
- >> NISTC_RTSI_TRIG_DIR_SUB_SEL1_SHIFT;
- else
- reg = (devpriv->rtsi_trig_b_output_reg &
- NISTC_RTSI_TRIGB_SUB_SEL1)
- >> NISTC_RTSI_TRIGB_SUB_SEL1_SHIFT;
- return reg;
-}
-
-static inline int get_rgout0_src(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int reg = get_rgout0_reg(dev);
-
- return ni_find_route_source(reg, NI_RGOUT0, &devpriv->routing_tables);
-}
-
-/*
- * Route signals through RGOUT0 terminal and increment the RGOUT0 use for this
- * particular route.
- * @src: device-global signal name
- * @dev: comedi device handle
- *
- * Return: -EINVAL if the source is not valid to route to RGOUT0;
- * -EBUSY if the RGOUT0 is already used;
- * 0 if successful.
- */
-static int incr_rgout0_src_use(int src, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- s8 reg = ni_lookup_route_register(CR_CHAN(src), NI_RGOUT0,
- &devpriv->routing_tables);
-
- if (reg < 0)
- return -EINVAL;
-
- if (devpriv->rgout0_usage > 0 && get_rgout0_reg(dev) != reg)
- return -EBUSY;
-
- ++devpriv->rgout0_usage;
- set_rgout0_reg(reg, dev);
- return 0;
-}
-
-/*
- * Unroute signals through RGOUT0 terminal and deccrement the RGOUT0 use for
- * this particular source. This function does not actually unroute anything
- * with respect to RGOUT0. It does, on the other hand, decrement the usage
- * counter for the current src->RGOUT0 mapping.
- *
- * Return: -EINVAL if the source is not already routed to RGOUT0 (or usage is
- * already at zero); 0 if successful.
- */
-static int decr_rgout0_src_use(int src, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- s8 reg = ni_lookup_route_register(CR_CHAN(src), NI_RGOUT0,
- &devpriv->routing_tables);
-
- if (devpriv->rgout0_usage > 0 && get_rgout0_reg(dev) == reg) {
- --devpriv->rgout0_usage;
- if (!devpriv->rgout0_usage)
- set_rgout0_reg(0, dev); /* ok default? */
- return 0;
- }
- return -EINVAL;
-}
-
-/*
- * Route signals through given NI_RTSI_BRD mux.
- * @i: index of mux to route
- * @reg: raw register value of RTSI_BRD bits
- * @dev: comedi device handle
- */
-static void set_ith_rtsi_brd_reg(int i, int reg, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int reg_i_sz = 3; /* value for e-series */
- int reg_i_mask;
- int reg_i_shift;
-
- if (devpriv->is_m_series)
- reg_i_sz = 4;
- reg_i_mask = ~((~0) << reg_i_sz);
- reg_i_shift = i * reg_i_sz;
-
- /* clear out the current reg_i for ith brd */
- devpriv->rtsi_shared_mux_reg &= ~(reg_i_mask << reg_i_shift);
- /* (softcopy) write the new reg_i for ith brd */
- devpriv->rtsi_shared_mux_reg |= (reg & reg_i_mask) << reg_i_shift;
- /* (hardcopy) write the new reg_i for ith brd */
- ni_stc_writew(dev, devpriv->rtsi_shared_mux_reg, NISTC_RTSI_BOARD_REG);
-}
-
-static int get_ith_rtsi_brd_reg(int i, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int reg_i_sz = 3; /* value for e-series */
- int reg_i_mask;
- int reg_i_shift;
-
- if (devpriv->is_m_series)
- reg_i_sz = 4;
- reg_i_mask = ~((~0) << reg_i_sz);
- reg_i_shift = i * reg_i_sz;
-
- return (devpriv->rtsi_shared_mux_reg >> reg_i_shift) & reg_i_mask;
-}
-
-static inline int get_rtsi_brd_src(int brd, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int brd_index = brd;
- int reg;
-
- if (brd >= NI_RTSI_BRD(0))
- brd_index = brd - NI_RTSI_BRD(0);
- else
- brd = NI_RTSI_BRD(brd);
- /*
- * And now:
- * brd : device-global name
- * brd_index : index number of RTSI_BRD mux
- */
-
- reg = get_ith_rtsi_brd_reg(brd_index, dev);
-
- return ni_find_route_source(reg, brd, &devpriv->routing_tables);
-}
-
-/*
- * Route signals through NI_RTSI_BRD mux and increment the use counter for this
- * particular route.
- *
- * Return: -EINVAL if the source is not valid to route to NI_RTSI_BRD(i);
- * -EBUSY if all NI_RTSI_BRD muxes are already used;
- * NI_RTSI_BRD(i) of allocated ith mux if successful.
- */
-static int incr_rtsi_brd_src_use(int src, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int first_available = -1;
- int err = -EINVAL;
- s8 reg;
- int i;
-
- /* first look for a mux that is already configured to provide src */
- for (i = 0; i < NUM_RTSI_SHARED_MUXS; ++i) {
- reg = ni_lookup_route_register(CR_CHAN(src), NI_RTSI_BRD(i),
- &devpriv->routing_tables);
-
- if (reg < 0)
- continue; /* invalid route */
-
- if (!devpriv->rtsi_shared_mux_usage[i]) {
- if (first_available < 0)
- /* found the first unused, but usable mux */
- first_available = i;
- } else {
- /*
- * we've seen at least one possible route, so change the
- * final error to -EBUSY in case there are no muxes
- * available.
- */
- err = -EBUSY;
-
- if (get_ith_rtsi_brd_reg(i, dev) == reg) {
- /*
- * we've found a mux that is already being used
- * to provide the requested signal. Reuse it.
- */
- goto success;
- }
- }
- }
-
- if (first_available < 0)
- return err;
-
- /* we did not find a mux to reuse, but there is at least one usable */
- i = first_available;
-
-success:
- ++devpriv->rtsi_shared_mux_usage[i];
- set_ith_rtsi_brd_reg(i, reg, dev);
- return NI_RTSI_BRD(i);
-}
-
-/*
- * Unroute signals through NI_RTSI_BRD mux and decrement the user counter for
- * this particular route.
- *
- * Return: -EINVAL if the source is not already routed to rtsi_brd(i) (or usage
- * is already at zero); 0 if successful.
- */
-static int decr_rtsi_brd_src_use(int src, int rtsi_brd,
- struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- s8 reg = ni_lookup_route_register(CR_CHAN(src), rtsi_brd,
- &devpriv->routing_tables);
- const int i = rtsi_brd - NI_RTSI_BRD(0);
-
- if (devpriv->rtsi_shared_mux_usage[i] > 0 &&
- get_ith_rtsi_brd_reg(i, dev) == reg) {
- --devpriv->rtsi_shared_mux_usage[i];
- if (!devpriv->rtsi_shared_mux_usage[i])
- set_ith_rtsi_brd_reg(i, 0, dev); /* ok default? */
- return 0;
- }
-
- return -EINVAL;
-}
-
-static void ni_rtsi_init(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int i;
-
- /* Initialises the RTSI bus signal switch to a default state */
-
- /*
- * Use 10MHz instead of 20MHz for RTSI clock frequency. Appears
- * to have no effect, at least on pxi-6281, which always uses
- * 20MHz rtsi clock frequency
- */
- devpriv->clock_and_fout2 = NI_M_CLK_FOUT2_RTSI_10MHZ;
- /* Set clock mode to internal */
- if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0)
- dev_err(dev->class_dev, "ni_set_master_clock failed, bug?\n");
-
- /* default internal lines routing to RTSI bus lines */
- for (i = 0; i < 8; ++i) {
- ni_set_rtsi_direction(dev, i, COMEDI_INPUT);
- ni_set_rtsi_routing(dev, i, default_rtsi_routing[i]);
- }
-
- /*
- * Sets the source and direction of the 4 on board lines.
- * This configures all board lines to be:
- * for e-series:
- * 1) inputs (not sure what "output" would mean)
- * 2) copying TRIGGER_LINE(0) (or RTSI0) output
- * for m-series:
- * copying NI_PFI(0) output
- */
- devpriv->rtsi_shared_mux_reg = 0;
- for (i = 0; i < 4; ++i)
- set_ith_rtsi_brd_reg(i, 0, dev);
- memset(devpriv->rtsi_shared_mux_usage, 0,
- sizeof(devpriv->rtsi_shared_mux_usage));
-
- /* initialize rgout0 pin as unused. */
- devpriv->rgout0_usage = 0;
- set_rgout0_reg(0, dev);
-}
-
-/* Get route of GPFO_i/CtrOut pins */
-static inline int ni_get_gout_routing(unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- unsigned int reg = devpriv->an_trig_etc_reg;
-
- switch (dest) {
- case 0:
- if (reg & NISTC_ATRIG_ETC_GPFO_0_ENA)
- return NISTC_ATRIG_ETC_GPFO_0_SEL_TO_SRC(reg);
- break;
- case 1:
- if (reg & NISTC_ATRIG_ETC_GPFO_1_ENA)
- return NISTC_ATRIG_ETC_GPFO_1_SEL_TO_SRC(reg);
- break;
- }
-
- return -EINVAL;
-}
-
-/* Set route of GPFO_i/CtrOut pins */
-static inline int ni_disable_gout_routing(unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
-
- switch (dest) {
- case 0:
- devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_0_ENA;
- break;
- case 1:
- devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_1_ENA;
- break;
- default:
- return -EINVAL;
- }
-
- ni_stc_writew(dev, devpriv->an_trig_etc_reg, NISTC_ATRIG_ETC_REG);
- return 0;
-}
-
-/* Set route of GPFO_i/CtrOut pins */
-static inline int ni_set_gout_routing(unsigned int src, unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
-
- switch (dest) {
- case 0:
- /* clear reg */
- devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_0_SEL(-1);
- /* set reg */
- devpriv->an_trig_etc_reg |= NISTC_ATRIG_ETC_GPFO_0_ENA
- | NISTC_ATRIG_ETC_GPFO_0_SEL(src);
- break;
- case 1:
- /* clear reg */
- devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_GPFO_1_SEL;
- src = src ? NISTC_ATRIG_ETC_GPFO_1_SEL : 0;
- /* set reg */
- devpriv->an_trig_etc_reg |= NISTC_ATRIG_ETC_GPFO_1_ENA | src;
- break;
- default:
- return -EINVAL;
- }
-
- ni_stc_writew(dev, devpriv->an_trig_etc_reg, NISTC_ATRIG_ETC_REG);
- return 0;
-}
-
-/*
- * Retrieves the current source of the output selector for the given
- * destination. If the terminal for the destination is not already configured
- * as an output, this function returns -EINVAL as error.
- *
- * Return: the register value of the destination output selector;
- * -EINVAL if terminal is not configured for output.
- */
-static int get_output_select_source(int dest, struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int reg = -1;
-
- if (channel_is_pfi(dest)) {
- if (ni_get_pfi_direction(dev, dest) == COMEDI_OUTPUT)
- reg = ni_get_pfi_routing(dev, dest);
- } else if (channel_is_rtsi(dest)) {
- if (ni_get_rtsi_direction(dev, dest) == COMEDI_OUTPUT) {
- reg = ni_get_rtsi_routing(dev, dest);
-
- if (reg == NI_RTSI_OUTPUT_RGOUT0) {
- dest = NI_RGOUT0; /* prepare for lookup below */
- reg = get_rgout0_reg(dev);
- } else if (reg >= NI_RTSI_OUTPUT_RTSI_BRD(0) &&
- reg <= NI_RTSI_OUTPUT_RTSI_BRD(3)) {
- const int i = reg - NI_RTSI_OUTPUT_RTSI_BRD(0);
-
- dest = NI_RTSI_BRD(i); /* prepare for lookup */
- reg = get_ith_rtsi_brd_reg(i, dev);
- }
- }
- } else if (dest >= NI_CtrOut(0) && dest <= NI_CtrOut(-1)) {
- /*
- * not handled by ni_tio. Only available for GPFO registers in
- * e/m series.
- */
- dest -= NI_CtrOut(0);
- if (dest > 1)
- /* there are only two g_out outputs. */
- return -EINVAL;
- reg = ni_get_gout_routing(dest, dev);
- } else if (channel_is_ctr(dest)) {
- reg = ni_tio_get_routing(devpriv->counter_dev, dest);
- } else {
- dev_dbg(dev->class_dev, "%s: unhandled destination (%d) queried\n",
- __func__, dest);
- }
-
- if (reg >= 0)
- return ni_find_route_source(CR_CHAN(reg), dest,
- &devpriv->routing_tables);
- return -EINVAL;
-}
-
-/*
- * Test a route:
- *
- * Return: -1 if not connectible;
- * 0 if connectible and not connected;
- * 1 if connectible and connected.
- */
-static int test_route(unsigned int src, unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- s8 reg = ni_route_to_register(CR_CHAN(src), dest,
- &devpriv->routing_tables);
-
- if (reg < 0)
- return -1;
- if (get_output_select_source(dest, dev) != CR_CHAN(src))
- return 0;
- return 1;
-}
-
-/* Connect the actual route. */
-static int connect_route(unsigned int src, unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- s8 reg = ni_route_to_register(CR_CHAN(src), dest,
- &devpriv->routing_tables);
- s8 current_src;
-
- if (reg < 0)
- /* route is not valid */
- return -EINVAL;
-
- current_src = get_output_select_source(dest, dev);
- if (current_src == CR_CHAN(src))
- return -EALREADY;
- if (current_src >= 0)
- /* destination mux is already busy. complain, don't overwrite */
- return -EBUSY;
-
- /* The route is valid and available. Now connect... */
- if (channel_is_pfi(dest)) {
- /* set routing source, then open output */
- ni_set_pfi_routing(dev, dest, reg);
- ni_set_pfi_direction(dev, dest, COMEDI_OUTPUT);
- } else if (channel_is_rtsi(dest)) {
- if (reg == NI_RTSI_OUTPUT_RGOUT0) {
- int ret = incr_rgout0_src_use(src, dev);
-
- if (ret < 0)
- return ret;
- } else if (ni_rtsi_route_requires_mux(reg)) {
- /* Attempt to allocate and route (src->brd) */
- int brd = incr_rtsi_brd_src_use(src, dev);
-
- if (brd < 0)
- return brd;
-
- /* Now lookup the register value for (brd->dest) */
- reg = ni_lookup_route_register(
- brd, dest, &devpriv->routing_tables);
- }
-
- ni_set_rtsi_direction(dev, dest, COMEDI_OUTPUT);
- ni_set_rtsi_routing(dev, dest, reg);
- } else if (dest >= NI_CtrOut(0) && dest <= NI_CtrOut(-1)) {
- /*
- * not handled by ni_tio. Only available for GPFO registers in
- * e/m series.
- */
- dest -= NI_CtrOut(0);
- if (dest > 1)
- /* there are only two g_out outputs. */
- return -EINVAL;
- if (ni_set_gout_routing(src, dest, dev))
- return -EINVAL;
- } else if (channel_is_ctr(dest)) {
- /*
- * we are adding back the channel modifier info to set
- * invert/edge info passed by the user
- */
- ni_tio_set_routing(devpriv->counter_dev, dest,
- reg | (src & ~CR_CHAN(-1)));
- } else {
- return -EINVAL;
- }
- return 0;
-}
-
-static int disconnect_route(unsigned int src, unsigned int dest,
- struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- s8 reg = ni_route_to_register(CR_CHAN(src), dest,
- &devpriv->routing_tables);
-
- if (reg < 0)
- /* route is not valid */
- return -EINVAL;
- if (get_output_select_source(dest, dev) != src)
- /* cannot disconnect something not connected */
- return -EINVAL;
-
- /* The route is valid and is connected. Now disconnect... */
- if (channel_is_pfi(dest)) {
- /* set the pfi to high impedance, and disconnect */
- ni_set_pfi_direction(dev, dest, COMEDI_INPUT);
- ni_set_pfi_routing(dev, dest, NI_PFI_OUTPUT_PFI_DEFAULT);
- } else if (channel_is_rtsi(dest)) {
- if (reg == NI_RTSI_OUTPUT_RGOUT0) {
- int ret = decr_rgout0_src_use(src, dev);
-
- if (ret < 0)
- return ret;
- } else if (ni_rtsi_route_requires_mux(reg)) {
- /* find which RTSI_BRD line is source for rtsi pin */
- int brd = ni_find_route_source(
- ni_get_rtsi_routing(dev, dest), dest,
- &devpriv->routing_tables);
-
- if (brd < 0)
- return brd;
-
- /* decrement/disconnect RTSI_BRD line from source */
- decr_rtsi_brd_src_use(src, brd, dev);
- }
-
- /* set rtsi output selector to default state */
- reg = default_rtsi_routing[dest - TRIGGER_LINE(0)];
- ni_set_rtsi_direction(dev, dest, COMEDI_INPUT);
- ni_set_rtsi_routing(dev, dest, reg);
- } else if (dest >= NI_CtrOut(0) && dest <= NI_CtrOut(-1)) {
- /*
- * not handled by ni_tio. Only available for GPFO registers in
- * e/m series.
- */
- dest -= NI_CtrOut(0);
- if (dest > 1)
- /* there are only two g_out outputs. */
- return -EINVAL;
- reg = ni_disable_gout_routing(dest, dev);
- } else if (channel_is_ctr(dest)) {
- ni_tio_unset_routing(devpriv->counter_dev, dest);
- } else {
- return -EINVAL;
- }
- return 0;
-}
-
-static int ni_global_insn_config(struct comedi_device *dev,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- switch (data[0]) {
- case INSN_DEVICE_CONFIG_TEST_ROUTE:
- data[0] = test_route(data[1], data[2], dev);
- return 2;
- case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
- return connect_route(data[1], data[2], dev);
- case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
- return disconnect_route(data[1], data[2], dev);
- /*
- * This case is already handled one level up.
- * case INSN_DEVICE_CONFIG_GET_ROUTES:
- */
- default:
- return -EINVAL;
- }
- return 1;
-}
-
-#ifdef PCIDMA
-static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
- int retval;
-
- retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
- COMEDI_INPUT);
- if (retval) {
- dev_err(dev->class_dev,
- "no dma channel available for use by counter\n");
- return retval;
- }
- ni_tio_acknowledge(counter);
- ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
-
- return ni_tio_cmd(dev, s);
-}
-
-static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
- int retval;
-
- retval = ni_tio_cancel(counter);
- ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
- ni_release_gpct_mite_channel(dev, counter->counter_index);
- return retval;
-}
-#endif
-
-static irqreturn_t ni_E_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s_ai = dev->read_subdev;
- struct comedi_subdevice *s_ao = dev->write_subdev;
- unsigned short a_status;
- unsigned short b_status;
- unsigned long flags;
-#ifdef PCIDMA
- struct ni_private *devpriv = dev->private;
-#endif
-
- if (!dev->attached)
- return IRQ_NONE;
- smp_mb(); /* make sure dev->attached is checked */
-
- /* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&dev->spinlock, flags);
- a_status = ni_stc_readw(dev, NISTC_AI_STATUS1_REG);
- b_status = ni_stc_readw(dev, NISTC_AO_STATUS1_REG);
-#ifdef PCIDMA
- if (devpriv->mite) {
- unsigned long flags_too;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
- if (s_ai && devpriv->ai_mite_chan)
- mite_ack_linkc(devpriv->ai_mite_chan, s_ai, false);
- if (s_ao && devpriv->ao_mite_chan)
- mite_ack_linkc(devpriv->ao_mite_chan, s_ao, false);
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
- }
-#endif
- ack_a_interrupt(dev, a_status);
- ack_b_interrupt(dev, b_status);
- if (s_ai) {
- if (a_status & NISTC_AI_STATUS1_INTA)
- handle_a_interrupt(dev, s_ai, a_status);
- /* handle any interrupt or dma events */
- comedi_handle_events(dev, s_ai);
- }
- if (s_ao) {
- if (b_status & NISTC_AO_STATUS1_INTB)
- handle_b_interrupt(dev, s_ao, b_status);
- /* handle any interrupt or dma events */
- comedi_handle_events(dev, s_ao);
- }
- handle_gpct_interrupt(dev, 0);
- handle_gpct_interrupt(dev, 1);
-#ifdef PCIDMA
- if (devpriv->is_m_series)
- handle_cdio_interrupt(dev);
-#endif
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return IRQ_HANDLED;
-}
-
-static int ni_alloc_private(struct comedi_device *dev)
-{
- struct ni_private *devpriv;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- spin_lock_init(&devpriv->window_lock);
- spin_lock_init(&devpriv->soft_reg_copy_lock);
- spin_lock_init(&devpriv->mite_channel_lock);
-
- return 0;
-}
-
-static unsigned int _ni_get_valid_routes(struct comedi_device *dev,
- unsigned int n_pairs,
- unsigned int *pair_data)
-{
- struct ni_private *devpriv = dev->private;
-
- return ni_get_valid_routes(&devpriv->routing_tables, n_pairs,
- pair_data);
-}
-
-static int ni_E_init(struct comedi_device *dev,
- unsigned int interrupt_pin, unsigned int irq_polarity)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- int ret;
- int i;
- const char *dev_family = devpriv->is_m_series ? "ni_mseries"
- : "ni_eseries";
-
- /* prepare the device for globally-named routes. */
- if (ni_assign_device_routes(dev_family, board->name,
- board->alt_route_name,
- &devpriv->routing_tables) < 0) {
- dev_warn(dev->class_dev, "%s: %s device has no signal routing table.\n",
- __func__, board->name);
- dev_warn(dev->class_dev, "%s: High level NI signal names will not be available for this %s board.\n",
- __func__, board->name);
- } else {
- /*
- * only(?) assign insn_device_config if we have global names for
- * this device.
- */
- dev->insn_device_config = ni_global_insn_config;
- dev->get_valid_routes = _ni_get_valid_routes;
- }
-
- if (board->n_aochan > MAX_N_AO_CHAN) {
- dev_err(dev->class_dev, "bug! n_aochan > MAX_N_AO_CHAN\n");
- return -EINVAL;
- }
-
- /* initialize clock dividers */
- devpriv->clock_and_fout = NISTC_CLK_FOUT_SLOW_DIV2 |
- NISTC_CLK_FOUT_SLOW_TIMEBASE |
- NISTC_CLK_FOUT_TO_BOARD_DIV2 |
- NISTC_CLK_FOUT_TO_BOARD;
- if (!devpriv->is_6xxx) {
- /* BEAM is this needed for PCI-6143 ?? */
- devpriv->clock_and_fout |= (NISTC_CLK_FOUT_AI_OUT_DIV2 |
- NISTC_CLK_FOUT_AO_OUT_DIV2);
- }
- ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
-
- ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[NI_AI_SUBDEV];
- if (board->n_adchan) {
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_DITHER;
- if (!devpriv->is_611x)
- s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
- if (board->ai_maxdata > 0xffff)
- s->subdev_flags |= SDF_LSAMPL;
- if (devpriv->is_m_series)
- s->subdev_flags |= SDF_SOFT_CALIBRATED;
- s->n_chan = board->n_adchan;
- s->maxdata = board->ai_maxdata;
- s->range_table = ni_range_lkup[board->gainlkup];
- s->insn_read = ni_ai_insn_read;
- s->insn_config = ni_ai_insn_config;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 512;
- s->do_cmdtest = ni_ai_cmdtest;
- s->do_cmd = ni_ai_cmd;
- s->cancel = ni_ai_reset;
- s->poll = ni_ai_poll;
- s->munge = ni_ai_munge;
-
- if (devpriv->mite)
- s->async_dma_dir = DMA_FROM_DEVICE;
- }
-
- /* reset the analog input configuration */
- ni_ai_reset(dev, s);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[NI_AO_SUBDEV];
- if (board->n_aochan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
- if (devpriv->is_m_series)
- s->subdev_flags |= SDF_SOFT_CALIBRATED;
- s->n_chan = board->n_aochan;
- s->maxdata = board->ao_maxdata;
- s->range_table = board->ao_range_table;
- s->insn_config = ni_ao_insn_config;
- s->insn_write = ni_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /*
- * Along with the IRQ we need either a FIFO or DMA for
- * async command support.
- */
- if (dev->irq && (board->ao_fifo_depth || devpriv->mite)) {
- dev->write_subdev = s;
- s->subdev_flags |= SDF_CMD_WRITE;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = ni_ao_cmdtest;
- s->do_cmd = ni_ao_cmd;
- s->cancel = ni_ao_reset;
- if (!devpriv->is_m_series)
- s->munge = ni_ao_munge;
-
- if (devpriv->mite)
- s->async_dma_dir = DMA_TO_DEVICE;
- }
-
- if (devpriv->is_67xx)
- init_ao_67xx(dev, s);
-
- /* reset the analog output configuration */
- ni_ao_reset(dev, s);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[NI_DIO_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = board->has_32dio_chan ? 32 : 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- if (devpriv->is_m_series) {
-#ifdef PCIDMA
- s->subdev_flags |= SDF_LSAMPL;
- s->insn_bits = ni_m_series_dio_insn_bits;
- s->insn_config = ni_m_series_dio_insn_config;
- if (dev->irq) {
- s->subdev_flags |= SDF_CMD_WRITE /* | SDF_CMD_READ */;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = ni_cdio_cmdtest;
- s->do_cmd = ni_cdio_cmd;
- s->cancel = ni_cdio_cancel;
-
- /* M-series boards use DMA */
- s->async_dma_dir = DMA_BIDIRECTIONAL;
- }
-
- /* reset DIO and set all channels to inputs */
- ni_writel(dev, NI_M_CDO_CMD_RESET |
- NI_M_CDI_CMD_RESET,
- NI_M_CDIO_CMD_REG);
- ni_writel(dev, s->io_bits, NI_M_DIO_DIR_REG);
-#endif /* PCIDMA */
- } else {
- s->insn_bits = ni_dio_insn_bits;
- s->insn_config = ni_dio_insn_config;
-
- /* set all channels to inputs */
- devpriv->dio_control = NISTC_DIO_CTRL_DIR(s->io_bits);
- ni_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
- }
-
- /* 8255 device */
- s = &dev->subdevices[NI_8255_DIO_SUBDEV];
- if (board->has_8255) {
- ret = subdev_8255_init(dev, s, ni_8255_callback,
- NI_E_8255_BASE);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* formerly general purpose counter/timer device, but no longer used */
- s = &dev->subdevices[NI_UNUSED_SUBDEV];
- s->type = COMEDI_SUBD_UNUSED;
-
- /* Calibration subdevice */
- s = &dev->subdevices[NI_CALIBRATION_SUBDEV];
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_INTERNAL;
- s->n_chan = 1;
- s->maxdata = 0;
- if (devpriv->is_m_series) {
- /* internal PWM output used for AI nonlinearity calibration */
- s->insn_config = ni_m_series_pwm_config;
-
- ni_writel(dev, 0x0, NI_M_CAL_PWM_REG);
- } else if (devpriv->is_6143) {
- /* internal PWM output used for AI nonlinearity calibration */
- s->insn_config = ni_6143_pwm_config;
- } else {
- s->subdev_flags |= SDF_WRITABLE;
- s->insn_read = ni_calib_insn_read;
- s->insn_write = ni_calib_insn_write;
-
- /* setup the caldacs and find the real n_chan and maxdata */
- caldac_setup(dev, s);
- }
-
- /* EEPROM subdevice */
- s = &dev->subdevices[NI_EEPROM_SUBDEV];
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->maxdata = 0xff;
- if (devpriv->is_m_series) {
- s->n_chan = M_SERIES_EEPROM_SIZE;
- s->insn_read = ni_m_series_eeprom_insn_read;
- } else {
- s->n_chan = 512;
- s->insn_read = ni_eeprom_insn_read;
- }
-
- /* Digital I/O (PFI) subdevice */
- s = &dev->subdevices[NI_PFI_DIO_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->maxdata = 1;
- if (devpriv->is_m_series) {
- s->n_chan = 16;
- s->insn_bits = ni_pfi_insn_bits;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
-
- ni_writew(dev, s->state, NI_M_PFI_DO_REG);
- for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
- ni_writew(dev, devpriv->pfi_output_select_reg[i],
- NI_M_PFI_OUT_SEL_REG(i));
- }
- } else {
- s->n_chan = 10;
- s->subdev_flags = SDF_INTERNAL;
- }
- s->insn_config = ni_pfi_insn_config;
-
- ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, ~0, 0);
-
- /* cs5529 calibration adc */
- s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV];
- if (devpriv->is_67xx) {
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
- /* one channel for each analog output channel */
- s->n_chan = board->n_aochan;
- s->maxdata = BIT(16) - 1;
- s->range_table = &range_unknown; /* XXX */
- s->insn_read = cs5529_ai_insn_read;
- s->insn_config = NULL;
- init_cs5529(dev);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Serial */
- s = &dev->subdevices[NI_SERIAL_SUBDEV];
- s->type = COMEDI_SUBD_SERIAL;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 1;
- s->maxdata = 0xff;
- s->insn_config = ni_serial_insn_config;
- devpriv->serial_interval_ns = 0;
- devpriv->serial_hw_mode = 0;
-
- /* RTSI */
- s = &dev->subdevices[NI_RTSI_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 8;
- s->maxdata = 1;
- s->insn_bits = ni_rtsi_insn_bits;
- s->insn_config = ni_rtsi_insn_config;
- ni_rtsi_init(dev);
-
- /* allocate and initialize the gpct counter device */
- devpriv->counter_dev = ni_gpct_device_construct(dev,
- ni_gpct_write_register,
- ni_gpct_read_register,
- (devpriv->is_m_series)
- ? ni_gpct_variant_m_series
- : ni_gpct_variant_e_series,
- NUM_GPCT,
- NUM_GPCT,
- &devpriv->routing_tables);
- if (!devpriv->counter_dev)
- return -ENOMEM;
-
- /* Counter (gpct) subdevices */
- for (i = 0; i < NUM_GPCT; ++i) {
- struct ni_gpct *gpct = &devpriv->counter_dev->counters[i];
-
- /* setup and initialize the counter */
- ni_tio_init_counter(gpct);
-
- s = &dev->subdevices[NI_GPCT_SUBDEV(i)];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
- s->n_chan = 3;
- s->maxdata = (devpriv->is_m_series) ? 0xffffffff
- : 0x00ffffff;
- s->insn_read = ni_tio_insn_read;
- s->insn_write = ni_tio_insn_write;
- s->insn_config = ni_tio_insn_config;
-#ifdef PCIDMA
- if (dev->irq && devpriv->mite) {
- s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
- s->len_chanlist = 1;
- s->do_cmdtest = ni_tio_cmdtest;
- s->do_cmd = ni_gpct_cmd;
- s->cancel = ni_gpct_cancel;
-
- s->async_dma_dir = DMA_BIDIRECTIONAL;
- }
-#endif
- s->private = gpct;
- }
-
- /* Initialize GPFO_{0,1} to produce output of counters */
- ni_set_gout_routing(0, 0, dev); /* output of counter 0; DAQ STC, p338 */
- ni_set_gout_routing(0, 1, dev); /* output of counter 1; DAQ STC, p338 */
-
- /* Frequency output subdevice */
- s = &dev->subdevices[NI_FREQ_OUT_SUBDEV];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 1;
- s->maxdata = 0xf;
- s->insn_read = ni_freq_out_insn_read;
- s->insn_write = ni_freq_out_insn_write;
- s->insn_config = ni_freq_out_insn_config;
-
- if (dev->irq) {
- ni_stc_writew(dev,
- (irq_polarity ? NISTC_INT_CTRL_INT_POL : 0) |
- (NISTC_INT_CTRL_3PIN_INT & 0) |
- NISTC_INT_CTRL_INTA_ENA |
- NISTC_INT_CTRL_INTB_ENA |
- NISTC_INT_CTRL_INTA_SEL(interrupt_pin) |
- NISTC_INT_CTRL_INTB_SEL(interrupt_pin),
- NISTC_INT_CTRL_REG);
- }
-
- /* DMA setup */
- ni_writeb(dev, devpriv->ai_ao_select_reg, NI_E_DMA_AI_AO_SEL_REG);
- ni_writeb(dev, devpriv->g0_g1_select_reg, NI_E_DMA_G0_G1_SEL_REG);
-
- if (devpriv->is_6xxx) {
- ni_writeb(dev, 0, NI611X_MAGIC_REG);
- } else if (devpriv->is_m_series) {
- int channel;
-
- for (channel = 0; channel < board->n_aochan; ++channel) {
- ni_writeb(dev, 0xf,
- NI_M_AO_WAVEFORM_ORDER_REG(channel));
- ni_writeb(dev, 0x0,
- NI_M_AO_REF_ATTENUATION_REG(channel));
- }
- ni_writeb(dev, 0x0, NI_M_AO_CALIB_REG);
- }
-
- return 0;
-}
-
-static void mio_common_detach(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv)
- ni_gpct_device_destroy(devpriv->counter_dev);
-}
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
deleted file mode 100644
index 4f37b4e58f09..000000000000
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ /dev/null
@@ -1,218 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for NI PCMCIA MIO E series cards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_mio_cs
- * Description: National Instruments DAQCard E series
- * Author: ds
- * Status: works
- * Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
- * DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
- * Updated: Thu Oct 23 19:43:17 CDT 2003
- *
- * See the notes in the ni_atmio.o driver.
- */
-
-/*
- * The real guts of the driver is in ni_mio_common.c, which is
- * included by all the E series drivers.
- *
- * References for specifications:
- * 341080a.pdf DAQCard E Series Register Level Programmer Manual
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedi_pcmcia.h"
-#include "ni_stc.h"
-#include "8255.h"
-
-/*
- * AT specific setup
- */
-
-static const struct ni_board_struct ni_boards[] = {
- {
- .name = "DAQCard-ai-16xe-50",
- .device_id = 0x010d,
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 1024,
- .gainlkup = ai_gain_8,
- .ai_speed = 5000,
- .caldac = { dac8800, dac8043 },
- }, {
- .name = "DAQCard-ai-16e-4",
- .device_id = 0x010c,
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 1024,
- .gainlkup = ai_gain_16,
- .ai_speed = 4000,
- .caldac = { mb88341 }, /* verified */
- }, {
- .name = "DAQCard-6062E",
- .device_id = 0x02c4,
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 8192,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1176,
- .caldac = { ad8804_debug }, /* verified */
- }, {
- /* specs incorrect! */
- .name = "DAQCard-6024E",
- .device_id = 0x075e,
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 1024,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000000,
- .caldac = { ad8804_debug },
- }, {
- /* specs incorrect! */
- .name = "DAQCard-6036E",
- .device_id = 0x0245,
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 1024,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000000,
- .caldac = { ad8804_debug },
- },
-#if 0
- {
- .name = "DAQCard-6715",
- .device_id = 0x0000, /* unknown */
- .n_aochan = 8,
- .ao_maxdata = 0x0fff,
- .ao_671x = 8192,
- .caldac = { mb88341, mb88341 },
- },
-#endif
-};
-
-#include "ni_mio_common.c"
-
-static const void *ni_getboardtype(struct comedi_device *dev,
- struct pcmcia_device *link)
-{
- static const struct ni_board_struct *board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
- board = &ni_boards[i];
- if (board->device_id == link->card_id)
- return board;
- }
- return NULL;
-}
-
-static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
-{
- int base, ret;
-
- p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
- p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
-
- for (base = 0x000; base < 0x400; base += 0x20) {
- p_dev->resource[0]->start = base;
- ret = pcmcia_request_io(p_dev);
- if (!ret)
- return 0;
- }
- return -ENODEV;
-}
-
-static int mio_cs_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- static const struct ni_board_struct *board;
- int ret;
-
- board = ni_getboardtype(dev, link);
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
- ret = comedi_pcmcia_enable(dev, mio_pcmcia_config_loop);
- if (ret)
- return ret;
- dev->iobase = link->resource[0]->start;
-
- link->priv = dev;
- ret = pcmcia_request_irq(link, ni_E_interrupt);
- if (ret)
- return ret;
- dev->irq = link->irq;
-
- ret = ni_alloc_private(dev);
- if (ret)
- return ret;
-
- return ni_E_init(dev, 0, 1);
-}
-
-static void mio_cs_detach(struct comedi_device *dev)
-{
- mio_common_detach(dev);
- comedi_pcmcia_disable(dev);
-}
-
-static struct comedi_driver driver_ni_mio_cs = {
- .driver_name = "ni_mio_cs",
- .module = THIS_MODULE,
- .auto_attach = mio_cs_auto_attach,
- .detach = mio_cs_detach,
-};
-
-static int cs_attach(struct pcmcia_device *link)
-{
- return comedi_pcmcia_auto_config(link, &driver_ni_mio_cs);
-}
-
-static const struct pcmcia_device_id ni_mio_cs_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d), /* DAQCard-ai-16xe-50 */
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c), /* DAQCard-ai-16e-4 */
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4), /* DAQCard-6062E */
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x075e), /* DAQCard-6024E */
- PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0245), /* DAQCard-6036E */
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids);
-
-static struct pcmcia_driver ni_mio_cs_driver = {
- .name = "ni_mio_cs",
- .owner = THIS_MODULE,
- .id_table = ni_mio_cs_ids,
- .probe = cs_attach,
- .remove = comedi_pcmcia_auto_unconfig,
-};
-module_comedi_pcmcia_driver(driver_ni_mio_cs, ni_mio_cs_driver);
-
-MODULE_DESCRIPTION("Comedi driver for National Instruments DAQCard E series");
-MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
deleted file mode 100644
index 623f8d08d13a..000000000000
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for National Instruments PCI-DIO-32HS
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_pcidio
- * Description: National Instruments PCI-DIO32HS, PCI-6533
- * Author: ds
- * Status: works
- * Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio)
- * [National Instruments] PXI-6533, PCI-6533 (pxi-6533)
- * [National Instruments] PCI-6534 (pci-6534)
- * Updated: Mon, 09 Jan 2012 14:27:23 +0000
- *
- * The DIO32HS board appears as one subdevice, with 32 channels. Each
- * channel is individually I/O configurable. The channel order is 0=A0,
- * 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only supports simple
- * digital I/O; no handshaking is supported.
- *
- * DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
- *
- * The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
- * scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
- * scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
- * trailing edge.
- *
- * This driver could be easily modified to support AT-MIO32HS and AT-MIO96.
- *
- * The PCI-6534 requires a firmware upload after power-up to work, the
- * firmware data and instructions for loading it with comedi_config
- * it are contained in the comedi_nonfree_firmware tarball available from
- * https://www.comedi.org
- */
-
-#define USE_DMA
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-
-#include "../comedi_pci.h"
-
-#include "mite.h"
-
-/* defines for the PCI-DIO-32HS */
-
-#define WINDOW_ADDRESS 4 /* W */
-#define INTERRUPT_AND_WINDOW_STATUS 4 /* R */
-#define INT_STATUS_1 BIT(0)
-#define INT_STATUS_2 BIT(1)
-#define WINDOW_ADDRESS_STATUS_MASK 0x7c
-
-#define MASTER_DMA_AND_INTERRUPT_CONTROL 5 /* W */
-#define INTERRUPT_LINE(x) ((x) & 3)
-#define OPEN_INT BIT(2)
-#define GROUP_STATUS 5 /* R */
-#define DATA_LEFT BIT(0)
-#define REQ BIT(2)
-#define STOP_TRIG BIT(3)
-
-#define GROUP_1_FLAGS 6 /* R */
-#define GROUP_2_FLAGS 7 /* R */
-#define TRANSFER_READY BIT(0)
-#define COUNT_EXPIRED BIT(1)
-#define WAITED BIT(5)
-#define PRIMARY_TC BIT(6)
-#define SECONDARY_TC BIT(7)
- /* #define SerialRose */
- /* #define ReqRose */
- /* #define Paused */
-
-#define GROUP_1_FIRST_CLEAR 6 /* W */
-#define GROUP_2_FIRST_CLEAR 7 /* W */
-#define CLEAR_WAITED BIT(3)
-#define CLEAR_PRIMARY_TC BIT(4)
-#define CLEAR_SECONDARY_TC BIT(5)
-#define DMA_RESET BIT(6)
-#define FIFO_RESET BIT(7)
-#define CLEAR_ALL 0xf8
-
-#define GROUP_1_FIFO 8 /* W */
-#define GROUP_2_FIFO 12 /* W */
-
-#define TRANSFER_COUNT 20
-#define CHIP_ID_D 24
-#define CHIP_ID_I 25
-#define CHIP_ID_O 26
-#define CHIP_VERSION 27
-#define PORT_IO(x) (28 + (x))
-#define PORT_PIN_DIRECTIONS(x) (32 + (x))
-#define PORT_PIN_MASK(x) (36 + (x))
-#define PORT_PIN_POLARITIES(x) (40 + (x))
-
-#define MASTER_CLOCK_ROUTING 45
-#define RTSI_CLOCKING(x) (((x) & 3) << 4)
-
-#define GROUP_1_SECOND_CLEAR 46 /* W */
-#define GROUP_2_SECOND_CLEAR 47 /* W */
-#define CLEAR_EXPIRED BIT(0)
-
-#define PORT_PATTERN(x) (48 + (x))
-
-#define DATA_PATH 64
-#define FIFO_ENABLE_A BIT(0)
-#define FIFO_ENABLE_B BIT(1)
-#define FIFO_ENABLE_C BIT(2)
-#define FIFO_ENABLE_D BIT(3)
-#define FUNNELING(x) (((x) & 3) << 4)
-#define GROUP_DIRECTION BIT(7)
-
-#define PROTOCOL_REGISTER_1 65
-#define OP_MODE PROTOCOL_REGISTER_1
-#define RUN_MODE(x) ((x) & 7)
-#define NUMBERED BIT(3)
-
-#define PROTOCOL_REGISTER_2 66
-#define CLOCK_REG PROTOCOL_REGISTER_2
-#define CLOCK_LINE(x) (((x) & 3) << 5)
-#define INVERT_STOP_TRIG BIT(7)
-#define DATA_LATCHING(x) (((x) & 3) << 5)
-
-#define PROTOCOL_REGISTER_3 67
-#define SEQUENCE PROTOCOL_REGISTER_3
-
-#define PROTOCOL_REGISTER_14 68 /* 16 bit */
-#define CLOCK_SPEED PROTOCOL_REGISTER_14
-
-#define PROTOCOL_REGISTER_4 70
-#define REQ_REG PROTOCOL_REGISTER_4
-#define REQ_CONDITIONING(x) (((x) & 7) << 3)
-
-#define PROTOCOL_REGISTER_5 71
-#define BLOCK_MODE PROTOCOL_REGISTER_5
-
-#define FIFO_Control 72
-#define READY_LEVEL(x) ((x) & 7)
-
-#define PROTOCOL_REGISTER_6 73
-#define LINE_POLARITIES PROTOCOL_REGISTER_6
-#define INVERT_ACK BIT(0)
-#define INVERT_REQ BIT(1)
-#define INVERT_CLOCK BIT(2)
-#define INVERT_SERIAL BIT(3)
-#define OPEN_ACK BIT(4)
-#define OPEN_CLOCK BIT(5)
-
-#define PROTOCOL_REGISTER_7 74
-#define ACK_SER PROTOCOL_REGISTER_7
-#define ACK_LINE(x) (((x) & 3) << 2)
-#define EXCHANGE_PINS BIT(7)
-
-#define INTERRUPT_CONTROL 75
-/* bits same as flags */
-
-#define DMA_LINE_CONTROL_GROUP1 76
-#define DMA_LINE_CONTROL_GROUP2 108
-
-/* channel zero is none */
-static inline unsigned int primary_DMAChannel_bits(unsigned int channel)
-{
- return channel & 0x3;
-}
-
-static inline unsigned int secondary_DMAChannel_bits(unsigned int channel)
-{
- return (channel << 2) & 0xc;
-}
-
-#define TRANSFER_SIZE_CONTROL 77
-#define TRANSFER_WIDTH(x) ((x) & 3)
-#define TRANSFER_LENGTH(x) (((x) & 3) << 3)
-#define REQUIRE_R_LEVEL BIT(5)
-
-#define PROTOCOL_REGISTER_15 79
-#define DAQ_OPTIONS PROTOCOL_REGISTER_15
-#define START_SOURCE(x) ((x) & 0x3)
-#define INVERT_START BIT(2)
-#define STOP_SOURCE(x) (((x) & 0x3) << 3)
-#define REQ_START BIT(6)
-#define PRE_START BIT(7)
-
-#define PATTERN_DETECTION 81
-#define DETECTION_METHOD BIT(0)
-#define INVERT_MATCH BIT(1)
-#define IE_PATTERN_DETECTION BIT(2)
-
-#define PROTOCOL_REGISTER_9 82
-#define REQ_DELAY PROTOCOL_REGISTER_9
-
-#define PROTOCOL_REGISTER_10 83
-#define REQ_NOT_DELAY PROTOCOL_REGISTER_10
-
-#define PROTOCOL_REGISTER_11 84
-#define ACK_DELAY PROTOCOL_REGISTER_11
-
-#define PROTOCOL_REGISTER_12 85
-#define ACK_NOT_DELAY PROTOCOL_REGISTER_12
-
-#define PROTOCOL_REGISTER_13 86
-#define DATA_1_DELAY PROTOCOL_REGISTER_13
-
-#define PROTOCOL_REGISTER_8 88 /* 32 bit */
-#define START_DELAY PROTOCOL_REGISTER_8
-
-/* Firmware files for PCI-6524 */
-#define FW_PCI_6534_MAIN "ni6534a.bin"
-#define FW_PCI_6534_SCARAB_DI "niscrb01.bin"
-#define FW_PCI_6534_SCARAB_DO "niscrb02.bin"
-MODULE_FIRMWARE(FW_PCI_6534_MAIN);
-MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DI);
-MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DO);
-
-enum pci_6534_firmware_registers { /* 16 bit */
- Firmware_Control_Register = 0x100,
- Firmware_Status_Register = 0x104,
- Firmware_Data_Register = 0x108,
- Firmware_Mask_Register = 0x10c,
- Firmware_Debug_Register = 0x110,
-};
-
-/* main fpga registers (32 bit)*/
-enum pci_6534_fpga_registers {
- FPGA_Control1_Register = 0x200,
- FPGA_Control2_Register = 0x204,
- FPGA_Irq_Mask_Register = 0x208,
- FPGA_Status_Register = 0x20c,
- FPGA_Signature_Register = 0x210,
- FPGA_SCALS_Counter_Register = 0x280, /*write-clear */
- FPGA_SCAMS_Counter_Register = 0x284, /*write-clear */
- FPGA_SCBLS_Counter_Register = 0x288, /*write-clear */
- FPGA_SCBMS_Counter_Register = 0x28c, /*write-clear */
- FPGA_Temp_Control_Register = 0x2a0,
- FPGA_DAR_Register = 0x2a8,
- FPGA_ELC_Read_Register = 0x2b8,
- FPGA_ELC_Write_Register = 0x2bc,
-};
-
-enum FPGA_Control_Bits {
- FPGA_Enable_Bit = 0x8000,
-};
-
-#define TIMER_BASE 50 /* nanoseconds */
-
-#ifdef USE_DMA
-#define INT_EN (COUNT_EXPIRED | WAITED | PRIMARY_TC | SECONDARY_TC)
-#else
-#define INT_EN (TRANSFER_READY | COUNT_EXPIRED | WAITED \
- | PRIMARY_TC | SECONDARY_TC)
-#endif
-
-enum nidio_boardid {
- BOARD_PCIDIO_32HS,
- BOARD_PXI6533,
- BOARD_PCI6534,
-};
-
-struct nidio_board {
- const char *name;
- unsigned int uses_firmware:1;
- unsigned int dio_speed;
-};
-
-static const struct nidio_board nidio_boards[] = {
- [BOARD_PCIDIO_32HS] = {
- .name = "pci-dio-32hs",
- .dio_speed = 50,
- },
- [BOARD_PXI6533] = {
- .name = "pxi-6533",
- .dio_speed = 50,
- },
- [BOARD_PCI6534] = {
- .name = "pci-6534",
- .uses_firmware = 1,
- .dio_speed = 50,
- },
-};
-
-struct nidio96_private {
- struct mite *mite;
- int boardtype;
- int dio;
- unsigned short OP_MODEBits;
- struct mite_channel *di_mite_chan;
- struct mite_ring *di_mite_ring;
- spinlock_t mite_channel_lock;
-};
-
-static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
-{
- struct nidio96_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- BUG_ON(devpriv->di_mite_chan);
- devpriv->di_mite_chan =
- mite_request_channel_in_range(devpriv->mite,
- devpriv->di_mite_ring, 1, 2);
- if (!devpriv->di_mite_chan) {
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- dev_err(dev->class_dev, "failed to reserve mite dma channel\n");
- return -EBUSY;
- }
- devpriv->di_mite_chan->dir = COMEDI_INPUT;
- writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
- secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
- dev->mmio + DMA_LINE_CONTROL_GROUP1);
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- return 0;
-}
-
-static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
-{
- struct nidio96_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->di_mite_chan) {
- mite_release_channel(devpriv->di_mite_chan);
- devpriv->di_mite_chan = NULL;
- writeb(primary_DMAChannel_bits(0) |
- secondary_DMAChannel_bits(0),
- dev->mmio + DMA_LINE_CONTROL_GROUP1);
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-}
-
-static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct nidio96_private *devpriv = dev->private;
- int retval;
- unsigned long flags;
-
- retval = ni_pcidio_request_di_mite_channel(dev);
- if (retval)
- return retval;
-
- /* write alloc the entire buffer */
- comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->di_mite_chan) {
- mite_prep_dma(devpriv->di_mite_chan, 32, 32);
- mite_dma_arm(devpriv->di_mite_chan);
- } else {
- retval = -EIO;
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- return retval;
-}
-
-static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct nidio96_private *devpriv = dev->private;
- unsigned long irq_flags;
- int count;
-
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- spin_lock(&devpriv->mite_channel_lock);
- if (devpriv->di_mite_chan)
- mite_sync_dma(devpriv->di_mite_chan, s);
- spin_unlock(&devpriv->mite_channel_lock);
- count = comedi_buf_n_bytes_ready(s);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- return count;
-}
-
-static irqreturn_t nidio_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct nidio96_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- unsigned int auxdata;
- int flags;
- int status;
- int work = 0;
-
- /* interrupcions parasites */
- if (!dev->attached) {
- /* assume it's from another card */
- return IRQ_NONE;
- }
-
- /* Lock to avoid race with comedi_poll */
- spin_lock(&dev->spinlock);
-
- status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS);
- flags = readb(dev->mmio + GROUP_1_FLAGS);
-
- spin_lock(&devpriv->mite_channel_lock);
- if (devpriv->di_mite_chan) {
- mite_ack_linkc(devpriv->di_mite_chan, s, false);
- /* XXX need to byteswap sync'ed dma */
- }
- spin_unlock(&devpriv->mite_channel_lock);
-
- while (status & DATA_LEFT) {
- work++;
- if (work > 20) {
- dev_dbg(dev->class_dev, "too much work in interrupt\n");
- writeb(0x00,
- dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL);
- break;
- }
-
- flags &= INT_EN;
-
- if (flags & TRANSFER_READY) {
- while (flags & TRANSFER_READY) {
- work++;
- if (work > 100) {
- dev_dbg(dev->class_dev,
- "too much work in interrupt\n");
- writeb(0x00, dev->mmio +
- MASTER_DMA_AND_INTERRUPT_CONTROL
- );
- goto out;
- }
- auxdata = readl(dev->mmio + GROUP_1_FIFO);
- comedi_buf_write_samples(s, &auxdata, 1);
- flags = readb(dev->mmio + GROUP_1_FLAGS);
- }
- }
-
- if (flags & COUNT_EXPIRED) {
- writeb(CLEAR_EXPIRED, dev->mmio + GROUP_1_SECOND_CLEAR);
- async->events |= COMEDI_CB_EOA;
-
- writeb(0x00, dev->mmio + OP_MODE);
- break;
- } else if (flags & WAITED) {
- writeb(CLEAR_WAITED, dev->mmio + GROUP_1_FIRST_CLEAR);
- async->events |= COMEDI_CB_ERROR;
- break;
- } else if (flags & PRIMARY_TC) {
- writeb(CLEAR_PRIMARY_TC,
- dev->mmio + GROUP_1_FIRST_CLEAR);
- async->events |= COMEDI_CB_EOA;
- } else if (flags & SECONDARY_TC) {
- writeb(CLEAR_SECONDARY_TC,
- dev->mmio + GROUP_1_FIRST_CLEAR);
- async->events |= COMEDI_CB_EOA;
- }
-
- flags = readb(dev->mmio + GROUP_1_FLAGS);
- status = readb(dev->mmio + INTERRUPT_AND_WINDOW_STATUS);
- }
-
-out:
- comedi_handle_events(dev, s);
-#if 0
- if (!tag)
- writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL);
-#endif
-
- spin_unlock(&dev->spinlock);
- return IRQ_HANDLED;
-}
-
-static int ni_pcidio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- if (data[0] == INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS) {
- const struct nidio_board *board = dev->board_ptr;
-
- /* we don't care about actual channels */
- data[1] = board->dio_speed;
- data[2] = 0;
- return 0;
- }
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- writel(s->io_bits, dev->mmio + PORT_PIN_DIRECTIONS(0));
-
- return insn->n;
-}
-
-static int ni_pcidio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- writel(s->state, dev->mmio + PORT_IO(0));
-
- data[1] = readl(dev->mmio + PORT_IO(0));
-
- return insn->n;
-}
-
-static int ni_pcidio_ns_to_timer(int *nanosec, unsigned int flags)
-{
- int divider, base;
-
- base = TIMER_BASE;
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- divider = DIV_ROUND_CLOSEST(*nanosec, base);
- break;
- case CMDF_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case CMDF_ROUND_UP:
- divider = DIV_ROUND_UP(*nanosec, base);
- break;
- }
-
- *nanosec = base * divider;
- return divider;
-}
-
-static int ni_pcidio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
-#define MAX_SPEED (TIMER_BASE) /* in nanoseconds */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- MAX_SPEED);
- /* no minimum speed */
- } else {
- /* TRIG_EXT */
- /* should be level/edge, hi/lo specification here */
- if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) {
- cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
- err |= -EINVAL;
- }
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- ni_pcidio_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int ni_pcidio_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct nidio96_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE);
- s->async->inttrig = NULL;
-
- return 1;
-}
-
-static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct nidio96_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- /* XXX configure ports for input */
- writel(0x0000, dev->mmio + PORT_PIN_DIRECTIONS(0));
-
- if (1) {
- /* enable fifos A B C D */
- writeb(0x0f, dev->mmio + DATA_PATH);
-
- /* set transfer width a 32 bits */
- writeb(TRANSFER_WIDTH(0) | TRANSFER_LENGTH(0),
- dev->mmio + TRANSFER_SIZE_CONTROL);
- } else {
- writeb(0x03, dev->mmio + DATA_PATH);
- writeb(TRANSFER_WIDTH(3) | TRANSFER_LENGTH(0),
- dev->mmio + TRANSFER_SIZE_CONTROL);
- }
-
- /* protocol configuration */
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* page 4-5, "input with internal REQs" */
- writeb(0, dev->mmio + OP_MODE);
- writeb(0x00, dev->mmio + CLOCK_REG);
- writeb(1, dev->mmio + SEQUENCE);
- writeb(0x04, dev->mmio + REQ_REG);
- writeb(4, dev->mmio + BLOCK_MODE);
- writeb(3, dev->mmio + LINE_POLARITIES);
- writeb(0xc0, dev->mmio + ACK_SER);
- writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
- CMDF_ROUND_NEAREST),
- dev->mmio + START_DELAY);
- writeb(1, dev->mmio + REQ_DELAY);
- writeb(1, dev->mmio + REQ_NOT_DELAY);
- writeb(1, dev->mmio + ACK_DELAY);
- writeb(0x0b, dev->mmio + ACK_NOT_DELAY);
- writeb(0x01, dev->mmio + DATA_1_DELAY);
- /*
- * manual, page 4-5:
- * CLOCK_SPEED comment is incorrectly listed on DAQ_OPTIONS
- */
- writew(0, dev->mmio + CLOCK_SPEED);
- writeb(0, dev->mmio + DAQ_OPTIONS);
- } else {
- /* TRIG_EXT */
- /* page 4-5, "input with external REQs" */
- writeb(0, dev->mmio + OP_MODE);
- writeb(0x00, dev->mmio + CLOCK_REG);
- writeb(0, dev->mmio + SEQUENCE);
- writeb(0x00, dev->mmio + REQ_REG);
- writeb(4, dev->mmio + BLOCK_MODE);
- if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */
- writeb(0, dev->mmio + LINE_POLARITIES);
- else /* Trailing Edge */
- writeb(2, dev->mmio + LINE_POLARITIES);
- writeb(0x00, dev->mmio + ACK_SER);
- writel(1, dev->mmio + START_DELAY);
- writeb(1, dev->mmio + REQ_DELAY);
- writeb(1, dev->mmio + REQ_NOT_DELAY);
- writeb(1, dev->mmio + ACK_DELAY);
- writeb(0x0C, dev->mmio + ACK_NOT_DELAY);
- writeb(0x10, dev->mmio + DATA_1_DELAY);
- writew(0, dev->mmio + CLOCK_SPEED);
- writeb(0x60, dev->mmio + DAQ_OPTIONS);
- }
-
- if (cmd->stop_src == TRIG_COUNT) {
- writel(cmd->stop_arg,
- dev->mmio + TRANSFER_COUNT);
- } else {
- /* XXX */
- }
-
-#ifdef USE_DMA
- writeb(CLEAR_PRIMARY_TC | CLEAR_SECONDARY_TC,
- dev->mmio + GROUP_1_FIRST_CLEAR);
-
- {
- int retval = setup_mite_dma(dev, s);
-
- if (retval)
- return retval;
- }
-#else
- writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP1);
-#endif
- writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP2);
-
- /* clear and enable interrupts */
- writeb(0xff, dev->mmio + GROUP_1_FIRST_CLEAR);
- /* writeb(CLEAR_EXPIRED, dev->mmio+GROUP_1_SECOND_CLEAR); */
-
- writeb(INT_EN, dev->mmio + INTERRUPT_CONTROL);
- writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL);
-
- if (cmd->stop_src == TRIG_NONE) {
- devpriv->OP_MODEBits = DATA_LATCHING(0) | RUN_MODE(7);
- } else { /* TRIG_TIMER */
- devpriv->OP_MODEBits = NUMBERED | RUN_MODE(7);
- }
- if (cmd->start_src == TRIG_NOW) {
- /* start */
- writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE);
- s->async->inttrig = NULL;
- } else {
- /* TRIG_INT */
- s->async->inttrig = ni_pcidio_inttrig;
- }
-
- return 0;
-}
-
-static int ni_pcidio_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- writeb(0x00, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL);
- ni_pcidio_release_di_mite_channel(dev);
-
- return 0;
-}
-
-static int ni_pcidio_change(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct nidio96_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->di_mite_ring, s);
- if (ret < 0)
- return ret;
-
- memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
-
- return 0;
-}
-
-static int pci_6534_load_fpga(struct comedi_device *dev,
- const u8 *data, size_t data_len,
- unsigned long context)
-{
- static const int timeout = 1000;
- int fpga_index = context;
- int i;
- size_t j;
-
- writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
- writew(0xc0 | fpga_index, dev->mmio + Firmware_Control_Register);
- for (i = 0;
- (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0 &&
- i < timeout; ++i) {
- udelay(1);
- }
- if (i == timeout) {
- dev_warn(dev->class_dev,
- "ni_pcidio: failed to load fpga %i, waiting for status 0x2\n",
- fpga_index);
- return -EIO;
- }
- writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
- for (i = 0;
- readw(dev->mmio + Firmware_Status_Register) != 0x3 &&
- i < timeout; ++i) {
- udelay(1);
- }
- if (i == timeout) {
- dev_warn(dev->class_dev,
- "ni_pcidio: failed to load fpga %i, waiting for status 0x3\n",
- fpga_index);
- return -EIO;
- }
- for (j = 0; j + 1 < data_len;) {
- unsigned int value = data[j++];
-
- value |= data[j++] << 8;
- writew(value, dev->mmio + Firmware_Data_Register);
- for (i = 0;
- (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0
- && i < timeout; ++i) {
- udelay(1);
- }
- if (i == timeout) {
- dev_warn(dev->class_dev,
- "ni_pcidio: failed to load word into fpga %i\n",
- fpga_index);
- return -EIO;
- }
- if (need_resched())
- schedule();
- }
- writew(0x0, dev->mmio + Firmware_Control_Register);
- return 0;
-}
-
-static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
-{
- return pci_6534_load_fpga(dev, NULL, 0, fpga_index);
-}
-
-static int pci_6534_reset_fpgas(struct comedi_device *dev)
-{
- int ret;
- int i;
-
- writew(0x0, dev->mmio + Firmware_Control_Register);
- for (i = 0; i < 3; ++i) {
- ret = pci_6534_reset_fpga(dev, i);
- if (ret < 0)
- break;
- }
- writew(0x0, dev->mmio + Firmware_Mask_Register);
- return ret;
-}
-
-static void pci_6534_init_main_fpga(struct comedi_device *dev)
-{
- writel(0, dev->mmio + FPGA_Control1_Register);
- writel(0, dev->mmio + FPGA_Control2_Register);
- writel(0, dev->mmio + FPGA_SCALS_Counter_Register);
- writel(0, dev->mmio + FPGA_SCAMS_Counter_Register);
- writel(0, dev->mmio + FPGA_SCBLS_Counter_Register);
- writel(0, dev->mmio + FPGA_SCBMS_Counter_Register);
-}
-
-static int pci_6534_upload_firmware(struct comedi_device *dev)
-{
- struct nidio96_private *devpriv = dev->private;
- static const char *const fw_file[3] = {
- FW_PCI_6534_SCARAB_DI, /* loaded into scarab A for DI */
- FW_PCI_6534_SCARAB_DO, /* loaded into scarab B for DO */
- FW_PCI_6534_MAIN, /* loaded into main FPGA */
- };
- int ret;
- int n;
-
- ret = pci_6534_reset_fpgas(dev);
- if (ret < 0)
- return ret;
- /* load main FPGA first, then the two scarabs */
- for (n = 2; n >= 0; n--) {
- ret = comedi_load_firmware(dev, &devpriv->mite->pcidev->dev,
- fw_file[n],
- pci_6534_load_fpga, n);
- if (ret == 0 && n == 2)
- pci_6534_init_main_fpga(dev);
- if (ret < 0)
- break;
- }
- return ret;
-}
-
-static void nidio_reset_board(struct comedi_device *dev)
-{
- writel(0, dev->mmio + PORT_IO(0));
- writel(0, dev->mmio + PORT_PIN_DIRECTIONS(0));
- writel(0, dev->mmio + PORT_PIN_MASK(0));
-
- /* disable interrupts on board */
- writeb(0, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL);
-}
-
-static int nidio_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct nidio_board *board = NULL;
- struct nidio96_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
- unsigned int irq;
-
- if (context < ARRAY_SIZE(nidio_boards))
- board = &nidio_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- spin_lock_init(&devpriv->mite_channel_lock);
-
- devpriv->mite = mite_attach(dev, false); /* use win0 */
- if (!devpriv->mite)
- return -ENOMEM;
-
- devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
- if (!devpriv->di_mite_ring)
- return -ENOMEM;
-
- if (board->uses_firmware) {
- ret = pci_6534_upload_firmware(dev);
- if (ret < 0)
- return ret;
- }
-
- nidio_reset_board(dev);
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name,
- readb(dev->mmio + CHIP_VERSION));
-
- s = &dev->subdevices[0];
-
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags =
- SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
- SDF_CMD_READ;
- s->n_chan = 32;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_config = &ni_pcidio_insn_config;
- s->insn_bits = &ni_pcidio_insn_bits;
- s->do_cmd = &ni_pcidio_cmd;
- s->do_cmdtest = &ni_pcidio_cmdtest;
- s->cancel = &ni_pcidio_cancel;
- s->len_chanlist = 32; /* XXX */
- s->buf_change = &ni_pcidio_change;
- s->async_dma_dir = DMA_BIDIRECTIONAL;
- s->poll = &ni_pcidio_poll;
-
- irq = pcidev->irq;
- if (irq) {
- ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = irq;
- }
-
- return 0;
-}
-
-static void nidio_detach(struct comedi_device *dev)
-{
- struct nidio96_private *devpriv = dev->private;
-
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (devpriv) {
- if (devpriv->di_mite_ring) {
- mite_free_ring(devpriv->di_mite_ring);
- devpriv->di_mite_ring = NULL;
- }
- mite_detach(devpriv->mite);
- }
- if (dev->mmio)
- iounmap(dev->mmio);
- comedi_pci_disable(dev);
-}
-
-static struct comedi_driver ni_pcidio_driver = {
- .driver_name = "ni_pcidio",
- .module = THIS_MODULE,
- .auto_attach = nidio_auto_attach,
- .detach = nidio_detach,
-};
-
-static int ni_pcidio_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data);
-}
-
-static const struct pci_device_id ni_pcidio_pci_table[] = {
- { PCI_VDEVICE(NI, 0x1150), BOARD_PCIDIO_32HS },
- { PCI_VDEVICE(NI, 0x12b0), BOARD_PCI6534 },
- { PCI_VDEVICE(NI, 0x1320), BOARD_PXI6533 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
-
-static struct pci_driver ni_pcidio_pci_driver = {
- .name = "ni_pcidio",
- .id_table = ni_pcidio_pci_table,
- .probe = ni_pcidio_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
deleted file mode 100644
index 6c813a490ba5..000000000000
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ /dev/null
@@ -1,1477 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Comedi driver for NI PCI-MIO E series cards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ni_pcimio
- * Description: National Instruments PCI-MIO-E series and M series (all boards)
- * Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans,
- * Herman Bruyninckx, Terry Barnaby
- * Status: works
- * Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
- * PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014,
- * PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E,
- * PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E,
- * PCI-6035E, PCI-6052E, PCI-6110, PCI-6111, PCI-6220, PXI-6220,
- * PCI-6221, PXI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225,
- * PCI-6229, PXI-6229, PCI-6250, PXI-6250, PCI-6251, PXI-6251,
- * PCIe-6251, PXIe-6251, PCI-6254, PXI-6254, PCI-6259, PXI-6259,
- * PCIe-6259, PXIe-6259, PCI-6280, PXI-6280, PCI-6281, PXI-6281,
- * PCI-6284, PXI-6284, PCI-6289, PXI-6289, PCI-6711, PXI-6711,
- * PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E,
- * PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
- * PCI-6143, PXI-6143
- * Updated: Mon, 16 Jan 2017 12:56:04 +0000
- *
- * These boards are almost identical to the AT-MIO E series, except that
- * they use the PCI bus instead of ISA (i.e., AT). See the notes for the
- * ni_atmio.o driver for additional information about these boards.
- *
- * Autocalibration is supported on many of the devices, using the
- * comedi_calibrate (or comedi_soft_calibrate for m-series) utility.
- * M-Series boards do analog input and analog output calibration entirely
- * in software. The software calibration corrects the analog input for
- * offset, gain and nonlinearity. The analog outputs are corrected for
- * offset and gain. See the comedilib documentation on
- * comedi_get_softcal_converter() for more information.
- *
- * By default, the driver uses DMA to transfer analog input data to
- * memory. When DMA is enabled, not all triggering features are
- * supported.
- *
- * Digital I/O may not work on 673x.
- *
- * Note that the PCI-6143 is a simultaineous sampling device with 8
- * convertors. With this board all of the convertors perform one
- * simultaineous sample during a scan interval. The period for a scan
- * is used for the convert time in a Comedi cmd. The convert trigger
- * source is normally set to TRIG_NOW by default.
- *
- * The RTSI trigger bus is supported on these cards on subdevice 10.
- * See the comedilib documentation for details.
- *
- * Information (number of channels, bits, etc.) for some devices may be
- * incorrect. Please check this and submit a bug if there are problems
- * for your device.
- *
- * SCXI is probably broken for m-series boards.
- *
- * Bugs:
- * - When DMA is enabled, COMEDI_EV_CONVERT does not work correctly.
- */
-
-/*
- * The PCI-MIO E series driver was originally written by
- * Tomasz Motylewski <...>, and ported to comedi by ds.
- *
- * References:
- * 341079b.pdf PCI E Series Register-Level Programmer Manual
- * 340934b.pdf DAQ-STC reference manual
- *
- * 322080b.pdf 6711/6713/6715 User Manual
- *
- * 320945c.pdf PCI E Series User Manual
- * 322138a.pdf PCI-6052E and DAQPad-6052E User Manual
- *
- * ISSUES:
- * - need to deal with external reference for DAC, and other DAC
- * properties in board properties
- * - deal with at-mio-16de-10 revision D to N changes, etc.
- * - need to add other CALDAC type
- * - need to slow down DAC loading. I don't trust NI's claim that
- * two writes to the PCI bus slows IO enough. I would prefer to
- * use udelay().
- * Timing specs: (clock)
- * AD8522 30ns
- * DAC8043 120ns
- * DAC8800 60ns
- * MB88341 ?
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-
-#include "../comedi_pci.h"
-
-#include <asm/byteorder.h>
-
-#include "ni_stc.h"
-#include "mite.h"
-
-#define PCIDMA
-
-/*
- * These are not all the possible ao ranges for 628x boards.
- * They can do OFFSET +- REFERENCE where OFFSET can be
- * 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
- * be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>. That's
- * 63 different possibilities. An AO channel
- * can not act as it's own OFFSET or REFERENCE.
- */
-static const struct comedi_lrange range_ni_M_628x_ao = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2),
- BIP_RANGE(1),
- RANGE(-5, 15),
- UNI_RANGE(10),
- RANGE(3, 7),
- RANGE(4, 6),
- RANGE_ext(-1, 1)
- }
-};
-
-static const struct comedi_lrange range_ni_M_625x_ao = {
- 3, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- RANGE_ext(-1, 1)
- }
-};
-
-enum ni_pcimio_boardid {
- BOARD_PCIMIO_16XE_50,
- BOARD_PCIMIO_16XE_10,
- BOARD_PCI6014,
- BOARD_PXI6030E,
- BOARD_PCIMIO_16E_1,
- BOARD_PCIMIO_16E_4,
- BOARD_PXI6040E,
- BOARD_PCI6031E,
- BOARD_PCI6032E,
- BOARD_PCI6033E,
- BOARD_PCI6071E,
- BOARD_PCI6023E,
- BOARD_PCI6024E,
- BOARD_PCI6025E,
- BOARD_PXI6025E,
- BOARD_PCI6034E,
- BOARD_PCI6035E,
- BOARD_PCI6052E,
- BOARD_PCI6110,
- BOARD_PCI6111,
- /* BOARD_PCI6115, */
- /* BOARD_PXI6115, */
- BOARD_PCI6711,
- BOARD_PXI6711,
- BOARD_PCI6713,
- BOARD_PXI6713,
- BOARD_PCI6731,
- /* BOARD_PXI6731, */
- BOARD_PCI6733,
- BOARD_PXI6733,
- BOARD_PXI6071E,
- BOARD_PXI6070E,
- BOARD_PXI6052E,
- BOARD_PXI6031E,
- BOARD_PCI6036E,
- BOARD_PCI6220,
- BOARD_PXI6220,
- BOARD_PCI6221,
- BOARD_PCI6221_37PIN,
- BOARD_PXI6221,
- BOARD_PCI6224,
- BOARD_PXI6224,
- BOARD_PCI6225,
- BOARD_PXI6225,
- BOARD_PCI6229,
- BOARD_PXI6229,
- BOARD_PCI6250,
- BOARD_PXI6250,
- BOARD_PCI6251,
- BOARD_PXI6251,
- BOARD_PCIE6251,
- BOARD_PXIE6251,
- BOARD_PCI6254,
- BOARD_PXI6254,
- BOARD_PCI6259,
- BOARD_PXI6259,
- BOARD_PCIE6259,
- BOARD_PXIE6259,
- BOARD_PCI6280,
- BOARD_PXI6280,
- BOARD_PCI6281,
- BOARD_PXI6281,
- BOARD_PCI6284,
- BOARD_PXI6284,
- BOARD_PCI6289,
- BOARD_PXI6289,
- BOARD_PCI6143,
- BOARD_PXI6143,
-};
-
-static const struct ni_board_struct ni_boards[] = {
- [BOARD_PCIMIO_16XE_50] = {
- .name = "pci-mio-16xe-50",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 2048,
- .alwaysdither = 1,
- .gainlkup = ai_gain_8,
- .ai_speed = 50000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 50000,
- .caldac = { dac8800, dac8043 },
- },
- [BOARD_PCIMIO_16XE_10] = {
- .name = "pci-mio-16xe-10", /* aka pci-6030E */
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 10000,
- .caldac = { dac8800, dac8043, ad8522 },
- },
- [BOARD_PCI6014] = {
- .name = "pci-6014",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 100000,
- .caldac = { ad8804_debug },
- },
- [BOARD_PXI6030E] = {
- .name = "pxi-6030e",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 10000,
- .caldac = { dac8800, dac8043, ad8522 },
- },
- [BOARD_PCIMIO_16E_1] = {
- .name = "pci-mio-16e-1", /* aka pci-6070e */
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { mb88341 },
- },
- [BOARD_PCIMIO_16E_4] = {
- .name = "pci-mio-16e-4", /* aka pci-6040e */
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_16,
- /*
- * there have been reported problems with
- * full speed on this board
- */
- .ai_speed = 2000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 512,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { ad8804_debug }, /* doc says mb88341 */
- },
- [BOARD_PXI6040E] = {
- .name = "pxi-6040e",
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 512,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { mb88341 },
- },
- [BOARD_PCI6031E] = {
- .name = "pci-6031e",
- .n_adchan = 64,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 10000,
- .caldac = { dac8800, dac8043, ad8522 },
- },
- [BOARD_PCI6032E] = {
- .name = "pci-6032e",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .caldac = { dac8800, dac8043, ad8522 },
- },
- [BOARD_PCI6033E] = {
- .name = "pci-6033e",
- .n_adchan = 64,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .caldac = { dac8800, dac8043, ad8522 },
- },
- [BOARD_PCI6071E] = {
- .name = "pci-6071e",
- .n_adchan = 64,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { ad8804_debug },
- },
- [BOARD_PCI6023E] = {
- .name = "pci-6023e",
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .caldac = { ad8804_debug }, /* manual is wrong */
- },
- [BOARD_PCI6024E] = {
- .name = "pci-6024e",
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 100000,
- .caldac = { ad8804_debug }, /* manual is wrong */
- },
- [BOARD_PCI6025E] = {
- .name = "pci-6025e",
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 100000,
- .caldac = { ad8804_debug }, /* manual is wrong */
- .has_8255 = 1,
- },
- [BOARD_PXI6025E] = {
- .name = "pxi-6025e",
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 100000,
- .caldac = { ad8804_debug }, /* manual is wrong */
- .has_8255 = 1,
- },
- [BOARD_PCI6034E] = {
- .name = "pci-6034e",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .caldac = { ad8804_debug },
- },
- [BOARD_PCI6035E] = {
- .name = "pci-6035e",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 100000,
- .caldac = { ad8804_debug },
- },
- [BOARD_PCI6052E] = {
- .name = "pci-6052e",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 3000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 3000,
- /* manual is wrong */
- .caldac = { ad8804_debug, ad8804_debug, ad8522 },
- },
- [BOARD_PCI6110] = {
- .name = "pci-6110",
- .n_adchan = 4,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 8192,
- .alwaysdither = 0,
- .gainlkup = ai_gain_611x,
- .ai_speed = 200,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .reg_type = ni_reg_611x,
- .ao_range_table = &range_bipolar10,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .caldac = { ad8804, ad8804 },
- },
- [BOARD_PCI6111] = {
- .name = "pci-6111",
- .n_adchan = 2,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 8192,
- .gainlkup = ai_gain_611x,
- .ai_speed = 200,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .reg_type = ni_reg_611x,
- .ao_range_table = &range_bipolar10,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .caldac = { ad8804, ad8804 },
- },
-#if 0
- /* The 6115 boards probably need their own driver */
- [BOARD_PCI6115] = { /* .device_id = 0x2ed0, */
- .name = "pci-6115",
- .n_adchan = 4,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 8192,
- .gainlkup = ai_gain_611x,
- .ai_speed = 100,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_671x = 1,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .reg_611x = 1,
- /* XXX */
- .caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
- },
-#endif
-#if 0
- [BOARD_PXI6115] = { /* .device_id = ????, */
- .name = "pxi-6115",
- .n_adchan = 4,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 8192,
- .gainlkup = ai_gain_611x,
- .ai_speed = 100,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_671x = 1,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .reg_611x = 1,
- /* XXX */
- .caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
- },
-#endif
- [BOARD_PCI6711] = {
- .name = "pci-6711",
- .n_aochan = 4,
- .ao_maxdata = 0x0fff,
- /* data sheet says 8192, but fifo really holds 16384 samples */
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .reg_type = ni_reg_6711,
- .caldac = { ad8804_debug },
- },
- [BOARD_PXI6711] = {
- .name = "pxi-6711",
- .n_aochan = 4,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .reg_type = ni_reg_6711,
- .caldac = { ad8804_debug },
- },
- [BOARD_PCI6713] = {
- .name = "pci-6713",
- .n_aochan = 8,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .reg_type = ni_reg_6713,
- .caldac = { ad8804_debug, ad8804_debug },
- },
- [BOARD_PXI6713] = {
- .name = "pxi-6713",
- .n_aochan = 8,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .reg_type = ni_reg_6713,
- .caldac = { ad8804_debug, ad8804_debug },
- },
- [BOARD_PCI6731] = {
- .name = "pci-6731",
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8192,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .reg_type = ni_reg_6711,
- .caldac = { ad8804_debug },
- },
-#if 0
- [BOARD_PXI6731] = { /* .device_id = ????, */
- .name = "pxi-6731",
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8192,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_6711,
- .caldac = { ad8804_debug },
- },
-#endif
- [BOARD_PCI6733] = {
- .name = "pci-6733",
- .n_aochan = 8,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .reg_type = ni_reg_6713,
- .caldac = { ad8804_debug, ad8804_debug },
- },
- [BOARD_PXI6733] = {
- .name = "pxi-6733",
- .n_aochan = 8,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .reg_type = ni_reg_6713,
- .caldac = { ad8804_debug, ad8804_debug },
- },
- [BOARD_PXI6071E] = {
- .name = "pxi-6071e",
- .n_adchan = 64,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { ad8804_debug },
- },
- [BOARD_PXI6070E] = {
- .name = "pxi-6070e",
- .n_adchan = 16,
- .ai_maxdata = 0x0fff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0x0fff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 1000,
- .caldac = { ad8804_debug },
- },
- [BOARD_PXI6052E] = {
- .name = "pxi-6052e",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 3000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 3000,
- .caldac = { mb88341, mb88341, ad8522 },
- },
- [BOARD_PXI6031E] = {
- .name = "pxi-6031e",
- .n_adchan = 64,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 10000,
- .caldac = { dac8800, dac8043, ad8522 },
- },
- [BOARD_PCI6036E] = {
- .name = "pci-6036e",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 100000,
- .caldac = { ad8804_debug },
- },
- [BOARD_PCI6220] = {
- .name = "pci-6220",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512, /* FIXME: guess */
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .reg_type = ni_reg_622x,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6220] = {
- .name = "pxi-6220",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 512, /* FIXME: guess */
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .reg_type = ni_reg_622x,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PCI6221] = {
- .name = "pci-6221",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_622x,
- .ao_speed = 1200,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PCI6221_37PIN] = {
- .name = "pci-6221_37pin",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_622x,
- .ao_speed = 1200,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6221] = {
- .name = "pxi-6221",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_622x,
- .ao_speed = 1200,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PCI6224] = {
- .name = "pci-6224",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .reg_type = ni_reg_622x,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PXI6224] = {
- .name = "pxi-6224",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .reg_type = ni_reg_622x,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PCI6225] = {
- .name = "pci-6225",
- .n_adchan = 80,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_622x,
- .ao_speed = 1200,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PXI6225] = {
- .name = "pxi-6225",
- .n_adchan = 80,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_622x,
- .ao_speed = 1200,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PCI6229] = {
- .name = "pci-6229",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_622x,
- .ao_speed = 1200,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6229] = {
- .name = "pxi-6229",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_bipolar10,
- .reg_type = ni_reg_622x,
- .ao_speed = 1200,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 1000,
- },
- [BOARD_PCI6250] = {
- .name = "pci-6250",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .reg_type = ni_reg_625x,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6250] = {
- .name = "pxi-6250",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .reg_type = ni_reg_625x,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6251] = {
- .name = "pci-6251",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PXI6251] = {
- .name = "pxi-6251",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCIE6251] = {
- .name = "pcie-6251",
- .alt_route_name = "pci-6251",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PXIE6251] = {
- .name = "pxie-6251",
- .n_adchan = 16,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6254] = {
- .name = "pci-6254",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .reg_type = ni_reg_625x,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6254] = {
- .name = "pxi-6254",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .reg_type = ni_reg_625x,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6259] = {
- .name = "pci-6259",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6259] = {
- .name = "pxi-6259",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCIE6259] = {
- .name = "pcie-6259",
- .alt_route_name = "pci-6259",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- },
- [BOARD_PXIE6259] = {
- .name = "pxie-6259",
- .n_adchan = 32,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_speed = 350,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6280] = {
- .name = "pci-6280",
- .n_adchan = 16,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .ao_fifo_depth = 8191,
- .reg_type = ni_reg_628x,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6280] = {
- .name = "pxi-6280",
- .n_adchan = 16,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .ao_fifo_depth = 8191,
- .reg_type = ni_reg_628x,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6281] = {
- .name = "pci-6281",
- .n_adchan = 16,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_628x_ao,
- .reg_type = ni_reg_628x,
- .ao_speed = 350,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PXI6281] = {
- .name = "pxi-6281",
- .n_adchan = 16,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 2,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_628x_ao,
- .reg_type = ni_reg_628x,
- .ao_speed = 350,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6284] = {
- .name = "pci-6284",
- .n_adchan = 32,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .reg_type = ni_reg_628x,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6284] = {
- .name = "pxi-6284",
- .n_adchan = 32,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .reg_type = ni_reg_628x,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6289] = {
- .name = "pci-6289",
- .n_adchan = 32,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_628x_ao,
- .reg_type = ni_reg_628x,
- .ao_speed = 350,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- },
- [BOARD_PXI6289] = {
- .name = "pxi-6289",
- .n_adchan = 32,
- .ai_maxdata = 0x3ffff,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 4,
- .ao_maxdata = 0xffff,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_628x_ao,
- .reg_type = ni_reg_628x,
- .ao_speed = 350,
- .has_32dio_chan = 1,
- .caldac = { caldac_none },
- .dio_speed = 100,
- },
- [BOARD_PCI6143] = {
- .name = "pci-6143",
- .n_adchan = 8,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 1024,
- .gainlkup = ai_gain_6143,
- .ai_speed = 4000,
- .reg_type = ni_reg_6143,
- .caldac = { ad8804_debug, ad8804_debug },
- },
- [BOARD_PXI6143] = {
- .name = "pxi-6143",
- .n_adchan = 8,
- .ai_maxdata = 0xffff,
- .ai_fifo_depth = 1024,
- .gainlkup = ai_gain_6143,
- .ai_speed = 4000,
- .reg_type = ni_reg_6143,
- .caldac = { ad8804_debug, ad8804_debug },
- },
-};
-
-#include "ni_mio_common.c"
-
-static int pcimio_ai_change(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->ai_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_ao_change(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->ao_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_gpct0_change(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->gpct_mite_ring[0], s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_gpct1_change(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->gpct_mite_ring[1], s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_dio_change(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->cdo_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static void m_series_init_eeprom_buffer(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- struct mite *mite = devpriv->mite;
- resource_size_t daq_phys_addr;
- static const int start_cal_eeprom = 0x400;
- static const unsigned int window_size = 10;
- unsigned int old_iodwbsr_bits;
- unsigned int old_iodwbsr1_bits;
- unsigned int old_iodwcr1_bits;
- int i;
-
- /* IO Window 1 needs to be temporarily mapped to read the eeprom */
- daq_phys_addr = pci_resource_start(mite->pcidev, 1);
-
- old_iodwbsr_bits = readl(mite->mmio + MITE_IODWBSR);
- old_iodwbsr1_bits = readl(mite->mmio + MITE_IODWBSR_1);
- old_iodwcr1_bits = readl(mite->mmio + MITE_IODWCR_1);
- writel(0x0, mite->mmio + MITE_IODWBSR);
- writel(((0x80 | window_size) | daq_phys_addr),
- mite->mmio + MITE_IODWBSR_1);
- writel(0x1 | old_iodwcr1_bits, mite->mmio + MITE_IODWCR_1);
- writel(0xf, mite->mmio + 0x30);
-
- for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i)
- devpriv->eeprom_buffer[i] = ni_readb(dev, start_cal_eeprom + i);
-
- writel(old_iodwbsr1_bits, mite->mmio + MITE_IODWBSR_1);
- writel(old_iodwbsr_bits, mite->mmio + MITE_IODWBSR);
- writel(old_iodwcr1_bits, mite->mmio + MITE_IODWCR_1);
- writel(0x0, mite->mmio + 0x30);
-}
-
-static void init_6143(struct comedi_device *dev)
-{
- const struct ni_board_struct *board = dev->board_ptr;
- struct ni_private *devpriv = dev->private;
-
- /* Disable interrupts */
- ni_stc_writew(dev, 0, NISTC_INT_CTRL_REG);
-
- /* Initialise 6143 AI specific bits */
-
- /* Set G0,G1 DMA mode to E series version */
- ni_writeb(dev, 0x00, NI6143_MAGIC_REG);
- /* Set EOCMode, ADCMode and pipelinedelay */
- ni_writeb(dev, 0x80, NI6143_PIPELINE_DELAY_REG);
- /* Set EOC Delay */
- ni_writeb(dev, 0x00, NI6143_EOC_SET_REG);
-
- /* Set the FIFO half full level */
- ni_writel(dev, board->ai_fifo_depth / 2, NI6143_AI_FIFO_FLAG_REG);
-
- /* Strobe Relay disable bit */
- devpriv->ai_calib_source_enabled = 0;
- ni_writew(dev, devpriv->ai_calib_source | NI6143_CALIB_CHAN_RELAY_OFF,
- NI6143_CALIB_CHAN_REG);
- ni_writew(dev, devpriv->ai_calib_source, NI6143_CALIB_CHAN_REG);
-}
-
-static void pcimio_detach(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
-
- mio_common_detach(dev);
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (devpriv) {
- mite_free_ring(devpriv->ai_mite_ring);
- mite_free_ring(devpriv->ao_mite_ring);
- mite_free_ring(devpriv->cdo_mite_ring);
- mite_free_ring(devpriv->gpct_mite_ring[0]);
- mite_free_ring(devpriv->gpct_mite_ring[1]);
- mite_detach(devpriv->mite);
- }
- if (dev->mmio)
- iounmap(dev->mmio);
- comedi_pci_disable(dev);
-}
-
-static int pcimio_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct ni_board_struct *board = NULL;
- struct ni_private *devpriv;
- unsigned int irq;
- int ret;
-
- if (context < ARRAY_SIZE(ni_boards))
- board = &ni_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- ret = ni_alloc_private(dev);
- if (ret)
- return ret;
- devpriv = dev->private;
-
- devpriv->mite = mite_attach(dev, false); /* use win0 */
- if (!devpriv->mite)
- return -ENOMEM;
-
- if (board->reg_type & ni_reg_m_series_mask)
- devpriv->is_m_series = 1;
- if (board->reg_type & ni_reg_6xxx_mask)
- devpriv->is_6xxx = 1;
- if (board->reg_type == ni_reg_611x)
- devpriv->is_611x = 1;
- if (board->reg_type == ni_reg_6143)
- devpriv->is_6143 = 1;
- if (board->reg_type == ni_reg_622x)
- devpriv->is_622x = 1;
- if (board->reg_type == ni_reg_625x)
- devpriv->is_625x = 1;
- if (board->reg_type == ni_reg_628x)
- devpriv->is_628x = 1;
- if (board->reg_type & ni_reg_67xx_mask)
- devpriv->is_67xx = 1;
- if (board->reg_type == ni_reg_6711)
- devpriv->is_6711 = 1;
- if (board->reg_type == ni_reg_6713)
- devpriv->is_6713 = 1;
-
- devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
- if (!devpriv->ai_mite_ring)
- return -ENOMEM;
- devpriv->ao_mite_ring = mite_alloc_ring(devpriv->mite);
- if (!devpriv->ao_mite_ring)
- return -ENOMEM;
- devpriv->cdo_mite_ring = mite_alloc_ring(devpriv->mite);
- if (!devpriv->cdo_mite_ring)
- return -ENOMEM;
- devpriv->gpct_mite_ring[0] = mite_alloc_ring(devpriv->mite);
- if (!devpriv->gpct_mite_ring[0])
- return -ENOMEM;
- devpriv->gpct_mite_ring[1] = mite_alloc_ring(devpriv->mite);
- if (!devpriv->gpct_mite_ring[1])
- return -ENOMEM;
-
- if (devpriv->is_m_series)
- m_series_init_eeprom_buffer(dev);
- if (devpriv->is_6143)
- init_6143(dev);
-
- irq = pcidev->irq;
- if (irq) {
- ret = request_irq(irq, ni_E_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = irq;
- }
-
- ret = ni_E_init(dev, 0, 1);
- if (ret < 0)
- return ret;
-
- dev->subdevices[NI_AI_SUBDEV].buf_change = &pcimio_ai_change;
- dev->subdevices[NI_AO_SUBDEV].buf_change = &pcimio_ao_change;
- dev->subdevices[NI_GPCT_SUBDEV(0)].buf_change = &pcimio_gpct0_change;
- dev->subdevices[NI_GPCT_SUBDEV(1)].buf_change = &pcimio_gpct1_change;
- dev->subdevices[NI_DIO_SUBDEV].buf_change = &pcimio_dio_change;
-
- return 0;
-}
-
-static struct comedi_driver ni_pcimio_driver = {
- .driver_name = "ni_pcimio",
- .module = THIS_MODULE,
- .auto_attach = pcimio_auto_attach,
- .detach = pcimio_detach,
-};
-
-static int ni_pcimio_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &ni_pcimio_driver, id->driver_data);
-}
-
-static const struct pci_device_id ni_pcimio_pci_table[] = {
- { PCI_VDEVICE(NI, 0x0162), BOARD_PCIMIO_16XE_50 }, /* 0x1620? */
- { PCI_VDEVICE(NI, 0x1170), BOARD_PCIMIO_16XE_10 },
- { PCI_VDEVICE(NI, 0x1180), BOARD_PCIMIO_16E_1 },
- { PCI_VDEVICE(NI, 0x1190), BOARD_PCIMIO_16E_4 },
- { PCI_VDEVICE(NI, 0x11b0), BOARD_PXI6070E },
- { PCI_VDEVICE(NI, 0x11c0), BOARD_PXI6040E },
- { PCI_VDEVICE(NI, 0x11d0), BOARD_PXI6030E },
- { PCI_VDEVICE(NI, 0x1270), BOARD_PCI6032E },
- { PCI_VDEVICE(NI, 0x1330), BOARD_PCI6031E },
- { PCI_VDEVICE(NI, 0x1340), BOARD_PCI6033E },
- { PCI_VDEVICE(NI, 0x1350), BOARD_PCI6071E },
- { PCI_VDEVICE(NI, 0x14e0), BOARD_PCI6110 },
- { PCI_VDEVICE(NI, 0x14f0), BOARD_PCI6111 },
- { PCI_VDEVICE(NI, 0x1580), BOARD_PXI6031E },
- { PCI_VDEVICE(NI, 0x15b0), BOARD_PXI6071E },
- { PCI_VDEVICE(NI, 0x1880), BOARD_PCI6711 },
- { PCI_VDEVICE(NI, 0x1870), BOARD_PCI6713 },
- { PCI_VDEVICE(NI, 0x18b0), BOARD_PCI6052E },
- { PCI_VDEVICE(NI, 0x18c0), BOARD_PXI6052E },
- { PCI_VDEVICE(NI, 0x2410), BOARD_PCI6733 },
- { PCI_VDEVICE(NI, 0x2420), BOARD_PXI6733 },
- { PCI_VDEVICE(NI, 0x2430), BOARD_PCI6731 },
- { PCI_VDEVICE(NI, 0x2890), BOARD_PCI6036E },
- { PCI_VDEVICE(NI, 0x28c0), BOARD_PCI6014 },
- { PCI_VDEVICE(NI, 0x2a60), BOARD_PCI6023E },
- { PCI_VDEVICE(NI, 0x2a70), BOARD_PCI6024E },
- { PCI_VDEVICE(NI, 0x2a80), BOARD_PCI6025E },
- { PCI_VDEVICE(NI, 0x2ab0), BOARD_PXI6025E },
- { PCI_VDEVICE(NI, 0x2b80), BOARD_PXI6713 },
- { PCI_VDEVICE(NI, 0x2b90), BOARD_PXI6711 },
- { PCI_VDEVICE(NI, 0x2c80), BOARD_PCI6035E },
- { PCI_VDEVICE(NI, 0x2ca0), BOARD_PCI6034E },
- { PCI_VDEVICE(NI, 0x70aa), BOARD_PCI6229 },
- { PCI_VDEVICE(NI, 0x70ab), BOARD_PCI6259 },
- { PCI_VDEVICE(NI, 0x70ac), BOARD_PCI6289 },
- { PCI_VDEVICE(NI, 0x70ad), BOARD_PXI6251 },
- { PCI_VDEVICE(NI, 0x70ae), BOARD_PXI6220 },
- { PCI_VDEVICE(NI, 0x70af), BOARD_PCI6221 },
- { PCI_VDEVICE(NI, 0x70b0), BOARD_PCI6220 },
- { PCI_VDEVICE(NI, 0x70b1), BOARD_PXI6229 },
- { PCI_VDEVICE(NI, 0x70b2), BOARD_PXI6259 },
- { PCI_VDEVICE(NI, 0x70b3), BOARD_PXI6289 },
- { PCI_VDEVICE(NI, 0x70b4), BOARD_PCI6250 },
- { PCI_VDEVICE(NI, 0x70b5), BOARD_PXI6221 },
- { PCI_VDEVICE(NI, 0x70b6), BOARD_PCI6280 },
- { PCI_VDEVICE(NI, 0x70b7), BOARD_PCI6254 },
- { PCI_VDEVICE(NI, 0x70b8), BOARD_PCI6251 },
- { PCI_VDEVICE(NI, 0x70b9), BOARD_PXI6250 },
- { PCI_VDEVICE(NI, 0x70ba), BOARD_PXI6254 },
- { PCI_VDEVICE(NI, 0x70bb), BOARD_PXI6280 },
- { PCI_VDEVICE(NI, 0x70bc), BOARD_PCI6284 },
- { PCI_VDEVICE(NI, 0x70bd), BOARD_PCI6281 },
- { PCI_VDEVICE(NI, 0x70be), BOARD_PXI6284 },
- { PCI_VDEVICE(NI, 0x70bf), BOARD_PXI6281 },
- { PCI_VDEVICE(NI, 0x70c0), BOARD_PCI6143 },
- { PCI_VDEVICE(NI, 0x70f2), BOARD_PCI6224 },
- { PCI_VDEVICE(NI, 0x70f3), BOARD_PXI6224 },
- { PCI_VDEVICE(NI, 0x710d), BOARD_PXI6143 },
- { PCI_VDEVICE(NI, 0x716c), BOARD_PCI6225 },
- { PCI_VDEVICE(NI, 0x716d), BOARD_PXI6225 },
- { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 },
- { PCI_VDEVICE(NI, 0x717f), BOARD_PCIE6259 },
- { PCI_VDEVICE(NI, 0x71bc), BOARD_PCI6221_37PIN },
- { PCI_VDEVICE(NI, 0x72e8), BOARD_PXIE6251 },
- { PCI_VDEVICE(NI, 0x72e9), BOARD_PXIE6259 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ni_pcimio_pci_table);
-
-static struct pci_driver ni_pcimio_pci_driver = {
- .name = "ni_pcimio",
- .id_table = ni_pcimio_pci_table,
- .probe = ni_pcimio_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_routes.c b/drivers/staging/comedi/drivers/ni_routes.c
deleted file mode 100644
index c426a9286f15..000000000000
--- a/drivers/staging/comedi/drivers/ni_routes.c
+++ /dev/null
@@ -1,562 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routes.c
- * Route information for NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/bsearch.h>
-#include <linux/sort.h>
-
-#include "../comedi.h"
-
-#include "ni_routes.h"
-#include "ni_routing/ni_route_values.h"
-#include "ni_routing/ni_device_routes.h"
-
-/*
- * This is defined in ni_routing/ni_route_values.h:
- * #define B(x) ((x) - NI_NAMES_BASE)
- */
-
-/*
- * These are defined in ni_routing/ni_route_values.h to identify clearly
- * elements of the table that were set. In other words, entries that are zero
- * are invalid. To get the value to use for the register, one must mask out the
- * high bit.
- *
- * #define V(x) ((x) | 0x80)
- *
- * #define UNMARK(x) ((x) & (~(0x80)))
- *
- */
-
-/* Helper for accessing data. */
-#define RVi(table, src, dest) ((table)[(dest) * NI_NUM_NAMES + (src)])
-
-/*
- * Find the route values for a device family.
- */
-static const u8 *ni_find_route_values(const char *device_family)
-{
- const u8 *rv = NULL;
- int i;
-
- for (i = 0; ni_all_route_values[i]; ++i) {
- if (memcmp(ni_all_route_values[i]->family, device_family,
- strnlen(device_family, 30)) == 0) {
- rv = &ni_all_route_values[i]->register_values[0][0];
- break;
- }
- }
- return rv;
-}
-
-/*
- * Find the valid routes for a board.
- */
-static const struct ni_device_routes *
-ni_find_valid_routes(const char *board_name)
-{
- const struct ni_device_routes *dr = NULL;
- int i;
-
- for (i = 0; ni_device_routes_list[i]; ++i) {
- if (memcmp(ni_device_routes_list[i]->device, board_name,
- strnlen(board_name, 30)) == 0) {
- dr = ni_device_routes_list[i];
- break;
- }
- }
- return dr;
-}
-
-/*
- * Find the proper route_values and ni_device_routes tables for this particular
- * device. Possibly try an alternate board name if device routes not found
- * for the actual board name.
- *
- * Return: -ENODATA if either was not found; 0 if both were found.
- */
-static int ni_find_device_routes(const char *device_family,
- const char *board_name,
- const char *alt_board_name,
- struct ni_route_tables *tables)
-{
- const struct ni_device_routes *dr;
- const u8 *rv;
-
- /* First, find the register_values table for this device family */
- rv = ni_find_route_values(device_family);
-
- /* Second, find the set of routes valid for this device. */
- dr = ni_find_valid_routes(board_name);
- if (!dr && alt_board_name)
- dr = ni_find_valid_routes(alt_board_name);
-
- tables->route_values = rv;
- tables->valid_routes = dr;
-
- if (!rv || !dr)
- return -ENODATA;
-
- return 0;
-}
-
-/**
- * ni_assign_device_routes() - Assign the proper lookup table for NI signal
- * routing to the specified NI device.
- * @device_family: Device family name (determines route values).
- * @board_name: Board name (determines set of routes).
- * @alt_board_name: Optional alternate board name to try on failure.
- * @tables: Pointer to assigned routing information.
- *
- * Finds the route values for the device family and the set of valid routes
- * for the board. If valid routes could not be found for the actual board
- * name and an alternate board name has been specified, try that one.
- *
- * On failure, the assigned routing information may be partially filled
- * (for example, with the route values but not the set of valid routes).
- *
- * Return: -ENODATA if assignment was not successful; 0 if successful.
- */
-int ni_assign_device_routes(const char *device_family,
- const char *board_name,
- const char *alt_board_name,
- struct ni_route_tables *tables)
-{
- memset(tables, 0, sizeof(struct ni_route_tables));
- return ni_find_device_routes(device_family, board_name, alt_board_name,
- tables);
-}
-EXPORT_SYMBOL_GPL(ni_assign_device_routes);
-
-/**
- * ni_count_valid_routes() - Count the number of valid routes.
- * @tables: Routing tables for which to count all valid routes.
- */
-unsigned int ni_count_valid_routes(const struct ni_route_tables *tables)
-{
- int total = 0;
- int i;
-
- for (i = 0; i < tables->valid_routes->n_route_sets; ++i) {
- const struct ni_route_set *R = &tables->valid_routes->routes[i];
- int j;
-
- for (j = 0; j < R->n_src; ++j) {
- const int src = R->src[j];
- const int dest = R->dest;
- const u8 *rv = tables->route_values;
-
- if (RVi(rv, B(src), B(dest)))
- /* direct routing is valid */
- ++total;
- else if (channel_is_rtsi(dest) &&
- (RVi(rv, B(src), B(NI_RGOUT0)) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(0))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(1))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(2))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(3))))) {
- ++total;
- }
- }
- }
- return total;
-}
-EXPORT_SYMBOL_GPL(ni_count_valid_routes);
-
-/**
- * ni_get_valid_routes() - Implements INSN_DEVICE_CONFIG_GET_ROUTES.
- * @tables: pointer to relevant set of routing tables.
- * @n_pairs: Number of pairs for which memory is allocated by the user. If
- * the user specifies '0', only the number of available pairs is
- * returned.
- * @pair_data: Pointer to memory allocated to return pairs back to user. Each
- * even, odd indexed member of this array will hold source,
- * destination of a route pair respectively.
- *
- * Return: the number of valid routes if n_pairs == 0; otherwise, the number of
- * valid routes copied.
- */
-unsigned int ni_get_valid_routes(const struct ni_route_tables *tables,
- unsigned int n_pairs,
- unsigned int *pair_data)
-{
- unsigned int n_valid = ni_count_valid_routes(tables);
- int i;
-
- if (n_pairs == 0 || n_valid == 0)
- return n_valid;
-
- if (!pair_data)
- return 0;
-
- n_valid = 0;
-
- for (i = 0; i < tables->valid_routes->n_route_sets; ++i) {
- const struct ni_route_set *R = &tables->valid_routes->routes[i];
- int j;
-
- for (j = 0; j < R->n_src; ++j) {
- const int src = R->src[j];
- const int dest = R->dest;
- bool valid = false;
- const u8 *rv = tables->route_values;
-
- if (RVi(rv, B(src), B(dest)))
- /* direct routing is valid */
- valid = true;
- else if (channel_is_rtsi(dest) &&
- (RVi(rv, B(src), B(NI_RGOUT0)) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(0))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(1))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(2))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(3))))) {
- /* indirect routing also valid */
- valid = true;
- }
-
- if (valid) {
- pair_data[2 * n_valid] = src;
- pair_data[2 * n_valid + 1] = dest;
- ++n_valid;
- }
-
- if (n_valid >= n_pairs)
- return n_valid;
- }
- }
- return n_valid;
-}
-EXPORT_SYMBOL_GPL(ni_get_valid_routes);
-
-/**
- * List of NI global signal names that, as destinations, are only routeable
- * indirectly through the *_arg elements of the comedi_cmd structure.
- */
-static const int NI_CMD_DESTS[] = {
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
-};
-
-/**
- * ni_is_cmd_dest() - Determine whether the given destination is only
- * configurable via a comedi_cmd struct.
- * @dest: Destination to test.
- */
-bool ni_is_cmd_dest(int dest)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(NI_CMD_DESTS); ++i)
- if (NI_CMD_DESTS[i] == dest)
- return true;
- return false;
-}
-EXPORT_SYMBOL_GPL(ni_is_cmd_dest);
-
-/* **** BEGIN Routes sort routines **** */
-static int _ni_sort_destcmp(const void *va, const void *vb)
-{
- const struct ni_route_set *a = va;
- const struct ni_route_set *b = vb;
-
- if (a->dest < b->dest)
- return -1;
- else if (a->dest > b->dest)
- return 1;
- return 0;
-}
-
-static int _ni_sort_srccmp(const void *vsrc0, const void *vsrc1)
-{
- const int *src0 = vsrc0;
- const int *src1 = vsrc1;
-
- if (*src0 < *src1)
- return -1;
- else if (*src0 > *src1)
- return 1;
- return 0;
-}
-
-/**
- * ni_sort_device_routes() - Sort the list of valid device signal routes in
- * preparation for use.
- * @valid_routes: pointer to ni_device_routes struct to sort.
- */
-void ni_sort_device_routes(struct ni_device_routes *valid_routes)
-{
- unsigned int n;
-
- /* 1. Count and set the number of ni_route_set objects. */
- valid_routes->n_route_sets = 0;
- while (valid_routes->routes[valid_routes->n_route_sets].dest != 0)
- ++valid_routes->n_route_sets;
-
- /* 2. sort all ni_route_set objects by destination. */
- sort(valid_routes->routes, valid_routes->n_route_sets,
- sizeof(struct ni_route_set), _ni_sort_destcmp, NULL);
-
- /* 3. Loop through each route_set for sorting. */
- for (n = 0; n < valid_routes->n_route_sets; ++n) {
- struct ni_route_set *rs = &valid_routes->routes[n];
-
- /* 3a. Count and set the number of sources. */
- rs->n_src = 0;
- while (rs->src[rs->n_src])
- ++rs->n_src;
-
- /* 3a. Sort sources. */
- sort(valid_routes->routes[n].src, valid_routes->routes[n].n_src,
- sizeof(int), _ni_sort_srccmp, NULL);
- }
-}
-EXPORT_SYMBOL_GPL(ni_sort_device_routes);
-
-/* sort all valid device signal routes in prep for use */
-static void ni_sort_all_device_routes(void)
-{
- unsigned int i;
-
- for (i = 0; ni_device_routes_list[i]; ++i)
- ni_sort_device_routes(ni_device_routes_list[i]);
-}
-
-/* **** BEGIN Routes search routines **** */
-static int _ni_bsearch_destcmp(const void *vkey, const void *velt)
-{
- const int *key = vkey;
- const struct ni_route_set *elt = velt;
-
- if (*key < elt->dest)
- return -1;
- else if (*key > elt->dest)
- return 1;
- return 0;
-}
-
-static int _ni_bsearch_srccmp(const void *vkey, const void *velt)
-{
- const int *key = vkey;
- const int *elt = velt;
-
- if (*key < *elt)
- return -1;
- else if (*key > *elt)
- return 1;
- return 0;
-}
-
-/**
- * ni_find_route_set() - Finds the proper route set with the specified
- * destination.
- * @destination: Destination of which to search for the route set.
- * @valid_routes: Pointer to device routes within which to search.
- *
- * Return: NULL if no route_set is found with the specified @destination;
- * otherwise, a pointer to the route_set if found.
- */
-const struct ni_route_set *
-ni_find_route_set(const int destination,
- const struct ni_device_routes *valid_routes)
-{
- return bsearch(&destination, valid_routes->routes,
- valid_routes->n_route_sets, sizeof(struct ni_route_set),
- _ni_bsearch_destcmp);
-}
-EXPORT_SYMBOL_GPL(ni_find_route_set);
-
-/**
- * ni_route_set_has_source() - Determines whether the given source is in
- * included given route_set.
- *
- * Return: true if found; false otherwise.
- */
-bool ni_route_set_has_source(const struct ni_route_set *routes,
- const int source)
-{
- if (!bsearch(&source, routes->src, routes->n_src, sizeof(int),
- _ni_bsearch_srccmp))
- return false;
- return true;
-}
-EXPORT_SYMBOL_GPL(ni_route_set_has_source);
-
-/**
- * ni_lookup_route_register() - Look up a register value for a particular route
- * without checking whether the route is valid for
- * the particular device.
- * @src: global-identifier for route source
- * @dest: global-identifier for route destination
- * @tables: pointer to relevant set of routing tables.
- *
- * Return: -EINVAL if the specified route is not valid for this device family.
- */
-s8 ni_lookup_route_register(int src, int dest,
- const struct ni_route_tables *tables)
-{
- s8 regval;
-
- /*
- * Be sure to use the B() macro to subtract off the NI_NAMES_BASE before
- * indexing into the route_values array.
- */
- src = B(src);
- dest = B(dest);
- if (src < 0 || src >= NI_NUM_NAMES || dest < 0 || dest >= NI_NUM_NAMES)
- return -EINVAL;
- regval = RVi(tables->route_values, src, dest);
- if (!regval)
- return -EINVAL;
- /* mask out the valid-value marking bit */
- return UNMARK(regval);
-}
-EXPORT_SYMBOL_GPL(ni_lookup_route_register);
-
-/**
- * ni_route_to_register() - Validates and converts the specified signal route
- * (src-->dest) to the value used at the appropriate
- * register.
- * @src: global-identifier for route source
- * @dest: global-identifier for route destination
- * @tables: pointer to relevant set of routing tables.
- *
- * Generally speaking, most routes require the first six bits and a few require
- * 7 bits. Special handling is given for the return value when the route is to
- * be handled by the RTSI sub-device. In this case, the returned register may
- * not be sufficient to define the entire route path, but rather may only
- * indicate the intermediate route. For example, if the route must go through
- * the RGOUT0 pin, the (src->RGOUT0) register value will be returned.
- * Similarly, if the route must go through the NI_RTSI_BRD lines, the BIT(6)
- * will be set:
- *
- * if route does not need RTSI_BRD lines:
- * bits 0:7 : register value
- * for a route that must go through RGOUT0 pin, this will be equal
- * to the (src->RGOUT0) register value.
- * else: * route is (src->RTSI_BRD(x), RTSI_BRD(x)->TRIGGER_LINE(i)) *
- * bits 0:5 : zero
- * bits 6 : set to 1
- * bits 7:7 : zero
- *
- * Return: register value to be used for source at destination with special
- * cases given above; Otherwise, -1 if the specified route is not valid for
- * this particular device.
- */
-s8 ni_route_to_register(const int src, const int dest,
- const struct ni_route_tables *tables)
-{
- const struct ni_route_set *routes =
- ni_find_route_set(dest, tables->valid_routes);
- const u8 *rv;
- s8 regval;
-
- /* first check to see if source is listed with bunch of destinations. */
- if (!routes)
- return -1;
- /* 2nd, check to see if destination is in list of source's targets. */
- if (!ni_route_set_has_source(routes, src))
- return -1;
- /*
- * finally, check to see if we know how to route...
- * Be sure to use the B() macro to subtract off the NI_NAMES_BASE before
- * indexing into the route_values array.
- */
- rv = tables->route_values;
- regval = RVi(rv, B(src), B(dest));
-
- /*
- * if we did not validate the route, we'll see if we can route through
- * one of the muxes
- */
- if (!regval && channel_is_rtsi(dest)) {
- regval = RVi(rv, B(src), B(NI_RGOUT0));
- if (!regval && (RVi(rv, B(src), B(NI_RTSI_BRD(0))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(1))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(2))) ||
- RVi(rv, B(src), B(NI_RTSI_BRD(3)))))
- regval = BIT(6);
- }
-
- if (!regval)
- return -1;
- /* mask out the valid-value marking bit */
- return UNMARK(regval);
-}
-EXPORT_SYMBOL_GPL(ni_route_to_register);
-
-/**
- * ni_find_route_source() - Finds the signal source corresponding to a signal
- * route (src-->dest) of the specified routing register
- * value and the specified route destination on the
- * specified device.
- *
- * Note that this function does _not_ validate the source based on device
- * routes.
- *
- * Return: The NI signal value (e.g. NI_PFI(0) or PXI_Clk10) if found.
- * If the source was not found (i.e. the register value is not
- * valid for any routes to the destination), -EINVAL is returned.
- */
-int ni_find_route_source(const u8 src_sel_reg_value, int dest,
- const struct ni_route_tables *tables)
-{
- int src;
-
- if (!tables->route_values)
- return -EINVAL;
-
- dest = B(dest); /* subtract NI names offset */
- /* ensure we are not going to under/over run the route value table */
- if (dest < 0 || dest >= NI_NUM_NAMES)
- return -EINVAL;
- for (src = 0; src < NI_NUM_NAMES; ++src)
- if (RVi(tables->route_values, src, dest) ==
- V(src_sel_reg_value))
- return src + NI_NAMES_BASE;
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(ni_find_route_source);
-
-/* **** END Routes search routines **** */
-
-/* **** BEGIN simple module entry/exit functions **** */
-static int __init ni_routes_module_init(void)
-{
- ni_sort_all_device_routes();
- return 0;
-}
-
-static void __exit ni_routes_module_exit(void)
-{
-}
-
-module_init(ni_routes_module_init);
-module_exit(ni_routes_module_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi helper for routing signals-->terminals for NI");
-MODULE_LICENSE("GPL");
-/* **** END simple module entry/exit functions **** */
diff --git a/drivers/staging/comedi/drivers/ni_routes.h b/drivers/staging/comedi/drivers/ni_routes.h
deleted file mode 100644
index b7680fd2afe1..000000000000
--- a/drivers/staging/comedi/drivers/ni_routes.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routes.h
- * Route information for NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-#ifndef _COMEDI_DRIVERS_NI_ROUTES_H
-#define _COMEDI_DRIVERS_NI_ROUTES_H
-
-#include <linux/types.h>
-#include <linux/errno.h>
-
-#ifndef NI_ROUTE_VALUE_EXTERNAL_CONVERSION
-#include <linux/bitops.h>
-#endif
-
-#include "../comedi.h"
-
-/**
- * struct ni_route_set - Set of destinations with a common source.
- * @dest: Destination of all sources in this route set.
- * @n_src: Number of sources for this route set.
- * @src: List of sources that all map to the same destination.
- */
-struct ni_route_set {
- int dest;
- int n_src;
- int *src;
-};
-
-/**
- * struct ni_device_routes - List of all src->dest sets for a particular device.
- * @device: Name of board/device (e.g. pxi-6733).
- * @n_route_sets: Number of route sets that are valid for this device.
- * @routes: List of route sets that are valid for this device.
- */
-struct ni_device_routes {
- const char *device;
- int n_route_sets;
- struct ni_route_set *routes;
-};
-
-/**
- * struct ni_route_tables - Register values and valid routes for a device.
- * @valid_routes: Pointer to a all valid route sets for a single device.
- * @route_values: Pointer to register values for all routes for the family to
- * which the device belongs.
- *
- * Link to the valid src->dest routes and the register values used to assign
- * such routes for that particular device.
- */
-struct ni_route_tables {
- const struct ni_device_routes *valid_routes;
- const u8 *route_values;
-};
-
-/*
- * ni_assign_device_routes() - Assign the proper lookup table for NI signal
- * routing to the specified NI device.
- *
- * Return: -ENODATA if assignment was not successful; 0 if successful.
- */
-int ni_assign_device_routes(const char *device_family,
- const char *board_name,
- const char *alt_board_name,
- struct ni_route_tables *tables);
-
-/*
- * ni_find_route_set() - Finds the proper route set with the specified
- * destination.
- * @destination: Destination of which to search for the route set.
- * @valid_routes: Pointer to device routes within which to search.
- *
- * Return: NULL if no route_set is found with the specified @destination;
- * otherwise, a pointer to the route_set if found.
- */
-const struct ni_route_set *
-ni_find_route_set(const int destination,
- const struct ni_device_routes *valid_routes);
-
-/*
- * ni_route_set_has_source() - Determines whether the given source is in
- * included given route_set.
- *
- * Return: true if found; false otherwise.
- */
-bool ni_route_set_has_source(const struct ni_route_set *routes, const int src);
-
-/*
- * ni_route_to_register() - Validates and converts the specified signal route
- * (src-->dest) to the value used at the appropriate
- * register.
- * @src: global-identifier for route source
- * @dest: global-identifier for route destination
- * @tables: pointer to relevant set of routing tables.
- *
- * Generally speaking, most routes require the first six bits and a few require
- * 7 bits. Special handling is given for the return value when the route is to
- * be handled by the RTSI sub-device. In this case, the returned register may
- * not be sufficient to define the entire route path, but rather may only
- * indicate the intermediate route. For example, if the route must go through
- * the RGOUT0 pin, the (src->RGOUT0) register value will be returned.
- * Similarly, if the route must go through the NI_RTSI_BRD lines, the BIT(6)
- * will be set:
- *
- * if route does not need RTSI_BRD lines:
- * bits 0:7 : register value
- * for a route that must go through RGOUT0 pin, this will be equal
- * to the (src->RGOUT0) register value.
- * else: * route is (src->RTSI_BRD(x), RTSI_BRD(x)->TRIGGER_LINE(i)) *
- * bits 0:5 : zero
- * bits 6 : set to 1
- * bits 7:7 : zero
- *
- * Return: register value to be used for source at destination with special
- * cases given above; Otherwise, -1 if the specified route is not valid for
- * this particular device.
- */
-s8 ni_route_to_register(const int src, const int dest,
- const struct ni_route_tables *tables);
-
-static inline bool ni_rtsi_route_requires_mux(s8 value)
-{
- return value & BIT(6);
-}
-
-/*
- * ni_lookup_route_register() - Look up a register value for a particular route
- * without checking whether the route is valid for
- * the particular device.
- * @src: global-identifier for route source
- * @dest: global-identifier for route destination
- * @tables: pointer to relevant set of routing tables.
- *
- * Return: -EINVAL if the specified route is not valid for this device family.
- */
-s8 ni_lookup_route_register(int src, int dest,
- const struct ni_route_tables *tables);
-
-/**
- * route_is_valid() - Determines whether the specified signal route (src-->dest)
- * is valid for the given NI comedi_device.
- * @src: global-identifier for route source
- * @dest: global-identifier for route destination
- * @tables: pointer to relevant set of routing tables.
- *
- * Return: True if the route is valid, otherwise false.
- */
-static inline bool route_is_valid(const int src, const int dest,
- const struct ni_route_tables *tables)
-{
- return ni_route_to_register(src, dest, tables) >= 0;
-}
-
-/*
- * ni_is_cmd_dest() - Determine whether the given destination is only
- * configurable via a comedi_cmd struct.
- * @dest: Destination to test.
- */
-bool ni_is_cmd_dest(int dest);
-
-static inline bool channel_is_pfi(int channel)
-{
- return NI_PFI(0) <= channel && channel <= NI_PFI(-1);
-}
-
-static inline bool channel_is_rtsi(int channel)
-{
- return TRIGGER_LINE(0) <= channel && channel <= TRIGGER_LINE(-1);
-}
-
-static inline bool channel_is_ctr(int channel)
-{
- return channel >= NI_COUNTER_NAMES_BASE &&
- channel <= NI_COUNTER_NAMES_MAX;
-}
-
-/*
- * ni_count_valid_routes() - Count the number of valid routes.
- * @tables: Routing tables for which to count all valid routes.
- */
-unsigned int ni_count_valid_routes(const struct ni_route_tables *tables);
-
-/*
- * ni_get_valid_routes() - Implements INSN_DEVICE_CONFIG_GET_ROUTES.
- * @tables: pointer to relevant set of routing tables.
- * @n_pairs: Number of pairs for which memory is allocated by the user. If
- * the user specifies '0', only the number of available pairs is
- * returned.
- * @pair_data: Pointer to memory allocated to return pairs back to user. Each
- * even, odd indexed member of this array will hold source,
- * destination of a route pair respectively.
- *
- * Return: the number of valid routes if n_pairs == 0; otherwise, the number of
- * valid routes copied.
- */
-unsigned int ni_get_valid_routes(const struct ni_route_tables *tables,
- unsigned int n_pairs,
- unsigned int *pair_data);
-
-/*
- * ni_sort_device_routes() - Sort the list of valid device signal routes in
- * preparation for use.
- * @valid_routes: pointer to ni_device_routes struct to sort.
- */
-void ni_sort_device_routes(struct ni_device_routes *valid_routes);
-
-/*
- * ni_find_route_source() - Finds the signal source corresponding to a signal
- * route (src-->dest) of the specified routing register
- * value and the specified route destination on the
- * specified device.
- *
- * Note that this function does _not_ validate the source based on device
- * routes.
- *
- * Return: The NI signal value (e.g. NI_PFI(0) or PXI_Clk10) if found.
- * If the source was not found (i.e. the register value is not
- * valid for any routes to the destination), -EINVAL is returned.
- */
-int ni_find_route_source(const u8 src_sel_reg_value, const int dest,
- const struct ni_route_tables *tables);
-
-/**
- * route_register_is_valid() - Determines whether the register value for the
- * specified route destination on the specified
- * device is valid.
- */
-static inline bool route_register_is_valid(const u8 src_sel_reg_value,
- const int dest,
- const struct ni_route_tables *tables)
-{
- return ni_find_route_source(src_sel_reg_value, dest, tables) >= 0;
-}
-
-/**
- * ni_get_reg_value_roffs() - Determines the proper register value for a
- * particular valid NI signal/terminal route.
- * @src: Either a direct register value or one of NI_* signal names.
- * @dest: global-identifier for route destination
- * @tables: pointer to relevant set of routing tables.
- * @direct_reg_offset:
- * Compatibility compensation argument. This argument allows us to
- * arbitrarily apply an offset to src if src is a direct register
- * value reference. This is necessary to be compatible with
- * definitions of register values as previously exported directly
- * to user space.
- *
- * Return: the register value (>0) to be used at the destination if the src is
- * valid for the given destination; -1 otherwise.
- */
-static inline s8 ni_get_reg_value_roffs(int src, const int dest,
- const struct ni_route_tables *tables,
- const int direct_reg_offset)
-{
- if (src < NI_NAMES_BASE) {
- src += direct_reg_offset;
- /*
- * In this case, the src is expected to actually be a register
- * value.
- */
- if (route_register_is_valid(src, dest, tables))
- return src;
- return -1;
- }
-
- /*
- * Otherwise, the src is expected to be one of the abstracted NI
- * signal/terminal names.
- */
- return ni_route_to_register(src, dest, tables);
-}
-
-static inline int ni_get_reg_value(const int src, const int dest,
- const struct ni_route_tables *tables)
-{
- return ni_get_reg_value_roffs(src, dest, tables, 0);
-}
-
-/**
- * ni_check_trigger_arg_roffs() - Checks the trigger argument (*_arg) of an NI
- * device to ensure that the *_arg value
- * corresponds to _either_ a valid register value
- * to define a trigger source, _or_ a valid NI
- * signal/terminal name that has a valid route to
- * the destination on the particular device.
- * @src: Either a direct register value or one of NI_* signal names.
- * @dest: global-identifier for route destination
- * @tables: pointer to relevant set of routing tables.
- * @direct_reg_offset:
- * Compatibility compensation argument. This argument allows us to
- * arbitrarily apply an offset to src if src is a direct register
- * value reference. This is necessary to be compatible with
- * definitions of register values as previously exported directly
- * to user space.
- *
- * Return: 0 if the src (either register value or NI signal/terminal name) is
- * valid for the destination; -EINVAL otherwise.
- */
-static inline
-int ni_check_trigger_arg_roffs(int src, const int dest,
- const struct ni_route_tables *tables,
- const int direct_reg_offset)
-{
- if (ni_get_reg_value_roffs(src, dest, tables, direct_reg_offset) < 0)
- return -EINVAL;
- return 0;
-}
-
-static inline int ni_check_trigger_arg(const int src, const int dest,
- const struct ni_route_tables *tables)
-{
- return ni_check_trigger_arg_roffs(src, dest, tables, 0);
-}
-
-#endif /* _COMEDI_DRIVERS_NI_ROUTES_H */
diff --git a/drivers/staging/comedi/drivers/ni_routing/README b/drivers/staging/comedi/drivers/ni_routing/README
deleted file mode 100644
index b65c4ebedbc4..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/README
+++ /dev/null
@@ -1,240 +0,0 @@
-Framework for Maintaining Common National Instruments Terminal/Signal names
-
-The contents of this directory are primarily for maintaining and formatting all
-known valid signal routes for various National Instruments devices.
-
-Some background:
- There have been significant confusions over the past many years for users
- when trying to understand how to connect to/from signals and terminals on
- NI hardware using comedi. The major reason for this is that the actual
- register values were exposed and required to be used by users. Several
- major reasons exist why this caused major confusion for users:
-
- 1) The register values are _NOT_ in user documentation, but rather in
- arcane locations, such as a few register programming manuals that are
- increasingly hard to find and the NI-MHDDK (comments in in example code).
- There is no one place to find the various valid values of the registers.
-
- 2) The register values are _NOT_ completely consistent. There is no way to
- gain any sense of intuition of which values, or even enums one should use
- for various registers. There was some attempt in prior use of comedi to
- name enums such that a user might know which enums should be used for
- varying purposes, but the end-user had to gain a knowledge of register
- values to correctly wield this approach.
-
- 3) The names for signals and registers found in the various register level
- programming manuals and vendor-provided documentation are _not_ even
- close to the same names that are in the end-user documentation.
-
- 4) The sets of routes that are valid are not consistent from device to device.
- One additional major challenge is that this information does not seem to be
- obtainable in any programmatic fashion, neither through the proprietary
- NIDAQmx(-base) c-libraries, nor with register level programming, _nor_
- through any documentation. In fact, the only consistent source of this
- information is through the proprietary NI-MAX software, which currently only
- runs on Windows platforms. A further challenge is that this information
- cannot be exported from NI-MAX, except by screenshot.
-
-
-
-The content of this directory is part of an effort to greatly simplify the use
-of signal routing capabilities of National Instruments data-acquisition and
-control hardware. In order to facilitate the transfer of register-level
-information _and_ the knowledge of valid routes per device, a few specific
-choices were made:
-
-
-1) The names of the National Instruments signals/terminals that are used in this
- directory are chosen to be consistent with (a) the NI's user level
- documentation, (b) NI's user-level code, (c) the information as provided by
- the proprietary NI-MAX software, and (d) the user interface code provided by
- the user-land comedilib library.
-
- The impact of this choice implies that one allows the use of CamelScript names
- in the kernel. In short, the choice to use CamelScript and the exact names
- below is for maintainability, clarity, similarity to manufacturer's
- documentation, _and_ a mitigation for confusion that has plagued the use of
- these drivers for years!
-
-2) The bulk of the real content for this directory is stored in two separate
- collections (i.e. sub-directories) of tables stored in c source files:
-
- (a) ni_route_values/ni_[series-label]series.c
-
- This data represents all the various register values to use for the
- multiple different signal MUXes for the specific device families.
-
- The values are all wrapped in one of three macros to help document and
- track which values have been implemented and tested.
- These macros are:
- V(<value>) : register value is valid, tested, and implemented
- I(<value>) : register value is implemented but needs testing
- U(<value>) : register value is not implemented
-
- The actual function of these macros will depend on whether the code is
- compiled in the kernel or whether it is compiled into the conversion
- tools. For the conversion tools, it can be used to indicate the status
- of the register value. For the kernel, V() and I() both perform the
- same function and prepare data to be used; U() zeroes out the value to
- ensure that it cannot be used.
-
- *** It would be a great help for users to test these values such that
- these files can be correctly marked/documented ***
-
- (b) ni_device_routes/[board-name].c
-
- This data represents the known set of valid signal routes that are
- possible for each specific board. Although the family defines the
- register values to use for a particular signal MUX, not all possible
- signals are actually available on each board.
-
- In order for a particular board to take advantage of the effort to
- simplify/clarify signal routing on NI devices, a corresponding
- [board-name].c file must be created. This file should reflect the known
- valid _direct_ routing capabilities of the board.
-
- As noted above, the only known consistent source of information for
- valid device routes comes from the proprietary National Instruments
- Windows software, NI-MAX. Also, as noted above, this information can
- only be visually conveyed from NI-MAX to other media. To make this
- easier, the naming conventions used in the [board-name].c file are
- similar to the naming conventions as presented by NI-MAX.
-
-
-3) Two other files aggregate the above data to integrate it into comedi:
- ni_route_values.c
- ni_device_routes.c
-
- When adding a new [board-name].c file, be sure to also add in the line in
- ni_device_routes.c to include this information into comedi.
-
-
-4) Several tools have been included to convert from/to the c file formats.
- These tools are best used/demonstrated via the included Makefile targets:
- (a) `make csv-files`
- Creates new csv-files using content of c-files of existing
- ni_routing/* content. New csv files are placed in csv
- sub-directory.
-
- As noted above, the only consistent source of information of valid
- device routes comes from the proprietary National Instruments Windows
- software, NI-MAX. Also, as noted above, this information can only be
- visually conveyed from NI-MAX to other media. This make target creates
- spreadsheet representations of the routing data. The choice of using a
- spreadsheet (ala CSV) to copy this information allows for easy direct
- visual comparison to the NI-MAX "Valid Routes" tables.
-
- Furthermore, the register-level information is much easier to identify and
- correct when entire families of NI devices are shown side by side in table
- format. This is made easy by using a file-storage format that can be
- loaded into a spreadsheet application.
-
- Finally, .csv content is very easy to edit and read using a variety of
- tools, including spreadsheets or various other scripting languages. In
- fact, the tools provided here enable quick conversion of the
- spreadsheet-like .csv format to c-files that follow the kernel coding
- conventions.
-
-
- (b) `make c-files`
- Creates new c-files using content of csv sub-directory. These
- new c-files can be compared to the active content in the
- ni_routing directory.
- (c) `make csv-blank`
- Create a new blank csv file. This is useful for establishing a
- new data table for either a device family (less likely) or a
- specific board of an existing device family (more likely).
- (d) `make clean`
- Remove all generated files/directories.
- (e) `make everything`
- Build all csv-files, then all new c-files.
-
-
-
-
-In summary, similar confusion about signal routing configuration, albeit less,
-plagued NI's previous version of their own proprietary drivers. Earlier than
-2003, NI greatly simplified the situation for users by releasing a new API that
-abstracted the names of signals/terminals to a common and intuitive set of
-names. In addition, this new API provided a much more common interface to use
-for most of NI hardware.
-
-Comedi already provides such a common interface for data-acquisition and control
-hardware. This effort complements comedi's abstraction layers by further
-abstracting much more of the use cases for NI hardware, but allowing users _and_
-developers to directly refer to NI documentation (user-level, register-level,
-and the register-level examples of the NI-MHDDK).
-
-
-
---------------------------------------------------------------------------------
-Various naming conventions and relations:
---------------------------------------------------------------------------------
-These are various notes that help to relate the naming conventions used in the
-NI-STC with those naming conventions used here.
---------------------------------------------------------------------------------
-
- Signal sources for most signals-destinations are given a specific naming
- convention, although the register values are not consistent. This next table
- shows the mapping between the names used in comedi for NI and those names
- typically used within the NI-STC documentation.
-
- (comedi) (NI-STC input or output) (NOTE)
- ------------------------------------------------------------------------------
- TRIGGER_LINE(i) RTSI_Trig_i_Output_Select i in range [0..7]
- NI_AI_STOP AI_STOP
- NI_AI_SampleClock AI_START_Select
- NI_AI_SampleClockTimebase AI_SI If internal sample
- clock signal is used
- NI_AI_StartTrigger AI_START1_Select
- NI_AI_ReferenceTrigger AI_START2_Select for pre-triggered
- acquisition---not
- currently supported
- in comedi
- NI_AI_ConvertClock AI_CONVERT_Source_Select
- NI_AI_ConvertClockTimebase AI_SI2 If internal convert
- signal is used
- NI_AI_HoldCompleteEvent
- NI_AI_PauseTrigger AI_External_Gate
- NI_AO_SampleClock AO_UPDATE
- NI_AO_SampleClockTimebase AO_UI
- NI_AO_StartTrigger AO_START1
- NI_AO_PauseTrigger AO_External_Gate
- NI_DI_SampleClock
- NI_DO_SampleClock
- NI_MasterTimebase
- NI_20MHzTimebase TIMEBASE 1 && TIMEBASE 3 if no higher clock exists
- NI_80MHzTimebase TIMEBASE 3
- NI_100kHzTimebase TIMEBASE 2
- NI_10MHzRefClock
- PXI_Clk10
- NI_CtrOut(0) GPFO_0 external ctr0out pin
- NI_CtrOut(1) GPFO_1 external ctr1out pin
- NI_CtrSource(0)
- NI_CtrSource(1)
- NI_CtrGate(0)
- NI_CtrGate(1)
- NI_CtrInternalOutput(0) G_OUT0, G0_TC for Ctr1Source, Ctr1Gate
- NI_CtrInternalOutput(1) G_OUT1, G1_TC for Ctr0Source, Ctr0Gate
- NI_RGOUT0 RGOUT0 internal signal
- NI_FrequencyOutput
- #NI_FrequencyOutputTimebase
- NI_ChangeDetectionEvent
- NI_RTSI_BRD(0)
- NI_RTSI_BRD(1)
- NI_RTSI_BRD(2)
- NI_RTSI_BRD(3)
- #NI_SoftwareStrobe
- NI_LogicLow
- NI_CtrA(0) G0_A_Select see M-Series user
- manual (371022K-01)
- NI_CtrA(1) G1_A_Select see M-Series user
- manual (371022K-01)
- NI_CtrB(0) G0_B_Select, up/down see M-Series user
- manual (371022K-01)
- NI_CtrB(1) G1_B_Select, up/down see M-Series user
- manual (371022K-01)
- NI_CtrZ(0) see M-Series user
- manual (371022K-01)
- NI_CtrZ(1) see M-Series user
- manual (371022K-01)
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.c
deleted file mode 100644
index 7b6a74dfe48b..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.c
+++ /dev/null
@@ -1,51 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "ni_device_routes.h"
-#include "ni_device_routes/all.h"
-
-struct ni_device_routes *const ni_device_routes_list[] = {
- &ni_pxi_6030e_device_routes,
- &ni_pci_6070e_device_routes,
- &ni_pci_6220_device_routes,
- &ni_pci_6221_device_routes,
- &ni_pxi_6224_device_routes,
- &ni_pxi_6225_device_routes,
- &ni_pci_6229_device_routes,
- &ni_pci_6251_device_routes,
- &ni_pxi_6251_device_routes,
- &ni_pxie_6251_device_routes,
- &ni_pci_6254_device_routes,
- &ni_pci_6259_device_routes,
- &ni_pci_6534_device_routes,
- &ni_pci_6602_device_routes,
- &ni_pci_6713_device_routes,
- &ni_pci_6723_device_routes,
- &ni_pci_6733_device_routes,
- &ni_pxi_6733_device_routes,
- NULL,
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.h b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.h
deleted file mode 100644
index b9f1c47d19e1..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * This file is meant to be included by comedi/drivers/ni_routes.c
- */
-
-#ifndef _COMEDI_DRIVERS_NI_ROUTINT_NI_DEVICE_ROUTES_H
-#define _COMEDI_DRIVERS_NI_ROUTINT_NI_DEVICE_ROUTES_H
-
-#include "../ni_routes.h"
-
-extern struct ni_device_routes *const ni_device_routes_list[];
-
-#endif /* _COMEDI_DRIVERS_NI_ROUTINT_NI_DEVICE_ROUTES_H */
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/all.h b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/all.h
deleted file mode 100644
index 78b24138acb7..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/all.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/all.h
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
-#define _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
-
-#include "../ni_device_routes.h"
-
-extern struct ni_device_routes ni_pxi_6030e_device_routes;
-extern struct ni_device_routes ni_pci_6070e_device_routes;
-extern struct ni_device_routes ni_pci_6220_device_routes;
-extern struct ni_device_routes ni_pci_6221_device_routes;
-extern struct ni_device_routes ni_pxi_6224_device_routes;
-extern struct ni_device_routes ni_pxi_6225_device_routes;
-extern struct ni_device_routes ni_pci_6229_device_routes;
-extern struct ni_device_routes ni_pci_6251_device_routes;
-extern struct ni_device_routes ni_pxi_6251_device_routes;
-extern struct ni_device_routes ni_pxie_6251_device_routes;
-extern struct ni_device_routes ni_pci_6254_device_routes;
-extern struct ni_device_routes ni_pci_6259_device_routes;
-extern struct ni_device_routes ni_pci_6534_device_routes;
-extern struct ni_device_routes ni_pxie_6535_device_routes;
-extern struct ni_device_routes ni_pci_6602_device_routes;
-extern struct ni_device_routes ni_pci_6713_device_routes;
-extern struct ni_device_routes ni_pci_6723_device_routes;
-extern struct ni_device_routes ni_pci_6733_device_routes;
-extern struct ni_device_routes ni_pxi_6733_device_routes;
-extern struct ni_device_routes ni_pxie_6738_device_routes;
-
-#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c
deleted file mode 100644
index f1126a0cb285..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c
+++ /dev/null
@@ -1,639 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6070e.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6070e_device_routes = {
- .device = "pci-6070e",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- NI_AI_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- NI_AI_ConvertClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_CtrSource(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_CtrGate(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- NI_AI_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- NI_CtrSource(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- NI_CtrGate(0),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(1),
- .src = (int[]){
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_AI_SampleClockTimebase,
- NI_MasterTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_HoldComplete,
- .src = (int[]){
- NI_AI_HoldCompleteEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_AI_StartTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6220.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6220.c
deleted file mode 100644
index 74a59222963f..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6220.c
+++ /dev/null
@@ -1,1418 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6220.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6220_device_routes = {
- .device = "pci-6220",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(1),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6221.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6221.c
deleted file mode 100644
index 44dcbabf2a99..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6221.c
+++ /dev/null
@@ -1,1602 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6221.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6221_device_routes = {
- .device = "pci-6221",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(1),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AI_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6229.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6229.c
deleted file mode 100644
index fa5794e4e2b3..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6229.c
+++ /dev/null
@@ -1,1602 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6229.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6229_device_routes = {
- .device = "pci-6229",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(1),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AI_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6251.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6251.c
deleted file mode 100644
index 645fd1cd2de4..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6251.c
+++ /dev/null
@@ -1,1652 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6251.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6251_device_routes = {
- .device = "pci-6251",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(1),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AI_StartTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6254.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6254.c
deleted file mode 100644
index 056a240cd3a2..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6254.c
+++ /dev/null
@@ -1,1464 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6254.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6254_device_routes = {
- .device = "pci-6254",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(1),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6259.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6259.c
deleted file mode 100644
index e0b5fa78c3bc..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6259.c
+++ /dev/null
@@ -1,1652 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6259.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6259_device_routes = {
- .device = "pci-6259",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(1),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AI_StartTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6534.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6534.c
deleted file mode 100644
index a2472ed288cf..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6534.c
+++ /dev/null
@@ -1,290 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6534.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6534_device_routes = {
- .device = "pci-6534",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- TRIGGER_LINE(0),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6602.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6602.c
deleted file mode 100644
index 91de9dac2d6a..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6602.c
+++ /dev/null
@@ -1,3378 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6602.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6602_device_routes = {
- .device = "pci-6602",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- NI_80MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- NI_80MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- NI_PFI(7),
- NI_PFI(15),
- NI_PFI(23),
- NI_PFI(31),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- NI_PFI(7),
- NI_PFI(15),
- NI_PFI(23),
- NI_PFI(31),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- NI_CtrGate(7),
- NI_LogicLow,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- NI_CtrSource(7),
- NI_LogicLow,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- NI_PFI(6),
- NI_PFI(14),
- NI_PFI(22),
- NI_PFI(30),
- NI_PFI(38),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- NI_PFI(6),
- NI_PFI(14),
- NI_PFI(22),
- NI_PFI(30),
- NI_PFI(38),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- NI_CtrGate(6),
- NI_LogicLow,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- NI_CtrSource(6),
- NI_LogicLow,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(16),
- .src = (int[]){
- NI_PFI(5),
- NI_PFI(13),
- NI_PFI(21),
- NI_PFI(29),
- NI_PFI(37),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(17),
- .src = (int[]){
- NI_PFI(5),
- NI_PFI(13),
- NI_PFI(21),
- NI_PFI(29),
- NI_PFI(37),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(18),
- .src = (int[]){
- NI_CtrGate(5),
- NI_LogicLow,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(19),
- .src = (int[]){
- NI_CtrSource(5),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(20),
- .src = (int[]){
- NI_PFI(4),
- NI_PFI(12),
- NI_PFI(28),
- NI_PFI(36),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(21),
- .src = (int[]){
- NI_PFI(4),
- NI_PFI(12),
- NI_PFI(20),
- NI_PFI(28),
- NI_PFI(36),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(22),
- .src = (int[]){
- NI_CtrGate(4),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(23),
- .src = (int[]){
- NI_CtrSource(4),
- NI_LogicLow,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(24),
- .src = (int[]){
- NI_PFI(3),
- NI_PFI(11),
- NI_PFI(19),
- NI_PFI(27),
- NI_PFI(35),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(3),
- NI_CtrSource(7),
- NI_CtrGate(3),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(25),
- .src = (int[]){
- NI_PFI(3),
- NI_PFI(11),
- NI_PFI(19),
- NI_PFI(27),
- NI_PFI(35),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(3),
- NI_CtrSource(7),
- NI_CtrGate(3),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(26),
- .src = (int[]){
- NI_CtrGate(3),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(27),
- .src = (int[]){
- NI_CtrSource(3),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(28),
- .src = (int[]){
- NI_PFI(2),
- NI_PFI(10),
- NI_PFI(18),
- NI_PFI(26),
- NI_PFI(34),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(2),
- NI_CtrSource(6),
- NI_CtrGate(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(29),
- .src = (int[]){
- NI_PFI(2),
- NI_PFI(10),
- NI_PFI(18),
- NI_PFI(26),
- NI_PFI(34),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(2),
- NI_CtrSource(6),
- NI_CtrGate(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(30),
- .src = (int[]){
- NI_CtrGate(2),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(31),
- .src = (int[]){
- NI_CtrSource(2),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(32),
- .src = (int[]){
- NI_PFI(1),
- NI_PFI(9),
- NI_PFI(17),
- NI_PFI(25),
- NI_PFI(33),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(5),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(33),
- .src = (int[]){
- NI_PFI(1),
- NI_PFI(9),
- NI_PFI(17),
- NI_PFI(25),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(5),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(34),
- .src = (int[]){
- NI_CtrGate(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(35),
- .src = (int[]){
- NI_CtrSource(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(36),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(5),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(37),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(5),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(38),
- .src = (int[]){
- NI_CtrGate(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(39),
- .src = (int[]){
- NI_CtrSource(0),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(3),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(7),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(3),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(6),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(6),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(6),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(7),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(7),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(7),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- NI_PFI(16),
- NI_PFI(17),
- NI_PFI(18),
- NI_PFI(19),
- NI_PFI(20),
- NI_PFI(21),
- NI_PFI(22),
- NI_PFI(23),
- NI_PFI(24),
- NI_PFI(25),
- NI_PFI(26),
- NI_PFI(27),
- NI_PFI(28),
- NI_PFI(29),
- NI_PFI(30),
- NI_PFI(31),
- NI_PFI(32),
- NI_PFI(33),
- NI_PFI(34),
- NI_PFI(35),
- NI_PFI(36),
- NI_PFI(37),
- NI_PFI(38),
- NI_PFI(39),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(4),
- NI_CtrSource(5),
- NI_CtrSource(6),
- NI_CtrGate(4),
- NI_CtrGate(5),
- NI_CtrGate(6),
- NI_CtrInternalOutput(4),
- NI_CtrInternalOutput(5),
- NI_CtrInternalOutput(6),
- NI_LogicLow,
- NI_LogicHigh,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6713.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6713.c
deleted file mode 100644
index d378b36d2084..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6713.c
+++ /dev/null
@@ -1,400 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6713.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6713_device_routes = {
- .device = "pci-6713",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_CtrSource(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_CtrGate(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- NI_CtrSource(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- NI_CtrGate(0),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(1),
- .src = (int[]){
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6723.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6723.c
deleted file mode 100644
index e0cc57ab06e7..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6723.c
+++ /dev/null
@@ -1,400 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6723.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6723_device_routes = {
- .device = "pci-6723",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_CtrSource(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_CtrGate(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- NI_CtrSource(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- NI_CtrGate(0),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(1),
- .src = (int[]){
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6733.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6733.c
deleted file mode 100644
index f6e1e17ab854..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pci-6733.c
+++ /dev/null
@@ -1,428 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pci-6733.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pci_6733_device_routes = {
- .device = "pci-6733",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_CtrSource(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_CtrGate(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- NI_CtrSource(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- NI_CtrGate(0),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(1),
- .src = (int[]){
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c
deleted file mode 100644
index 9978d632117f..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c
+++ /dev/null
@@ -1,608 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxi-6030e.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxi_6030e_device_routes = {
- .device = "pxi-6030e",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- NI_AI_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- NI_AI_ReferenceTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- NI_AI_ConvertClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_CtrSource(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_CtrGate(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- NI_AI_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- NI_CtrSource(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- NI_CtrGate(0),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(1),
- .src = (int[]){
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(0),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(0),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(0),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_AI_SampleClockTimebase,
- NI_MasterTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_HoldComplete,
- .src = (int[]){
- NI_AI_HoldCompleteEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(7),
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_AI_StartTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c
deleted file mode 100644
index 1b89e27d7aa5..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c
+++ /dev/null
@@ -1,1432 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxi-6224.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxi_6224_device_routes = {
- .device = "pxi-6224",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c
deleted file mode 100644
index 10dfc34bc87c..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c
+++ /dev/null
@@ -1,1613 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxi-6225.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxi_6225_device_routes = {
- .device = "pxi-6225",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AI_StartTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c
deleted file mode 100644
index 25db4b7363de..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c
+++ /dev/null
@@ -1,1655 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxi-6251.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxi_6251_device_routes = {
- .device = "pxi-6251",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- PXI_Star,
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- PXI_Star,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- PXI_Star,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- PXI_Star,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AO_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AI_StartTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c
deleted file mode 100644
index 27da4433fc4a..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c
+++ /dev/null
@@ -1,428 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxi-6733.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxi_6733_device_routes = {
- .device = "pxi-6733",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_CtrSource(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_CtrGate(1),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- NI_CtrSource(0),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- NI_CtrGate(0),
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(1),
- PXI_Star,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(0),
- PXI_Star,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(0),
- PXI_Star,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrOut(1),
- .src = (int[]){
- NI_CtrInternalOutput(1),
- 0, /* Termination */
- }
- },
- {
- .dest = PXI_Star,
- .src = (int[]){
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrInternalOutput(0),
- NI_CtrOut(0),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_CtrInternalOutput(1),
- PXI_Star,
- NI_AO_SampleClockTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(7),
- PXI_Star,
- NI_MasterTimebase,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- PXI_Star,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- PXI_Star,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- PXI_Star,
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- PXI_Star,
- NI_AO_SampleClock,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_MasterTimebase,
- .src = (int[]){
- TRIGGER_LINE(7),
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c
deleted file mode 100644
index 8354fe971d59..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c
+++ /dev/null
@@ -1,1656 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxie-6251.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxie_6251_device_routes = {
- .device = "pxie-6251",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(8),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(9),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(10),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(11),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(12),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(13),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(14),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(15),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_DI_SampleClock,
- NI_DO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AI_ConvertClock,
- NI_AI_PauseTrigger,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_10MHzRefClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(1),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrGate(0),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_80MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(1),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_AI_StartTrigger,
- NI_AI_ReferenceTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_ConvertClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_ConvertClockTimebase,
- .src = (int[]){
- NI_AI_SampleClockTimebase,
- NI_20MHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AO_SampleClockTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100kHzTimebase,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AI_StartTrigger,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_PFI(8),
- NI_PFI(9),
- NI_PFI(10),
- NI_PFI(11),
- NI_PFI(12),
- NI_PFI(13),
- NI_PFI(14),
- NI_PFI(15),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_AI_SampleClock,
- NI_AI_ConvertClock,
- NI_AO_SampleClock,
- NI_FrequencyOutput,
- NI_ChangeDetectionEvent,
- NI_AnalogComparisonEvent,
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c
deleted file mode 100644
index 2ebb679e0129..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c
+++ /dev/null
@@ -1,575 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxie-6535.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxie_6535_device_routes = {
- .device = "pxie-6535",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_InputBufferFull,
- NI_DI_ReadyForStartEvent,
- NI_DI_ReadyForTransferEventBurst,
- NI_DI_ReadyForTransferEventPipelined,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_OutputBufferFull,
- NI_DO_DataActiveEvent,
- NI_DO_ReadyForStartEvent,
- NI_DO_ReadyForTransferEvent,
- NI_ChangeDetectionEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(5),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(4),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c b/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c
deleted file mode 100644
index d88504314d7f..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c
+++ /dev/null
@@ -1,3083 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_device_routes/pxie-6738.c
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "all.h"
-
-struct ni_device_routes ni_pxie_6738_device_routes = {
- .device = "pxie-6738",
- .routes = (struct ni_route_set[]){
- {
- .dest = NI_PFI(0),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(1),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(2),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(3),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(4),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(5),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(6),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_PFI(7),
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(4),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(5),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(6),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = TRIGGER_LINE(7),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrZ(0),
- NI_CtrZ(1),
- NI_CtrZ(2),
- NI_CtrZ(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- PXI_Clk10,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_20MHzTimebase,
- NI_100MHzTimebase,
- NI_100kHzTimebase,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- PXI_Clk10,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_20MHzTimebase,
- NI_100MHzTimebase,
- NI_100kHzTimebase,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- PXI_Clk10,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_20MHzTimebase,
- NI_100MHzTimebase,
- NI_100kHzTimebase,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSource(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- PXI_Clk10,
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_20MHzTimebase,
- NI_100MHzTimebase,
- NI_100kHzTimebase,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrGate(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrAux(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrA(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrB(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrZ(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrArmStartTrigger(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSampleClock(0),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSampleClock(1),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSampleClock(2),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_CtrSampleClock(3),
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClockTimebase,
- NI_DI_SampleClock,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_AO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_DI_SampleClockTimebase,
- NI_20MHzTimebase,
- NI_100MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_ReferenceTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DI_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DO_SampleClock,
- NI_DO_StartTrigger,
- NI_DO_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClock,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_DO_SampleClockTimebase,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_SampleClockTimebase,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- PXI_Clk10,
- NI_20MHzTimebase,
- NI_100MHzTimebase,
- NI_100kHzTimebase,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_StartTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_DO_PauseTrigger,
- .src = (int[]){
- NI_PFI(0),
- NI_PFI(1),
- NI_PFI(2),
- NI_PFI(3),
- NI_PFI(4),
- NI_PFI(5),
- NI_PFI(6),
- NI_PFI(7),
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- NI_CtrSource(0),
- NI_CtrSource(1),
- NI_CtrSource(2),
- NI_CtrSource(3),
- NI_CtrGate(0),
- NI_CtrGate(1),
- NI_CtrGate(2),
- NI_CtrGate(3),
- NI_CtrArmStartTrigger(0),
- NI_CtrArmStartTrigger(1),
- NI_CtrArmStartTrigger(2),
- NI_CtrArmStartTrigger(3),
- NI_CtrInternalOutput(0),
- NI_CtrInternalOutput(1),
- NI_CtrInternalOutput(2),
- NI_CtrInternalOutput(3),
- NI_CtrSampleClock(0),
- NI_CtrSampleClock(1),
- NI_CtrSampleClock(2),
- NI_CtrSampleClock(3),
- NI_AO_SampleClock,
- NI_AO_StartTrigger,
- NI_AO_PauseTrigger,
- NI_DI_SampleClock,
- NI_DI_StartTrigger,
- NI_DI_ReferenceTrigger,
- NI_DI_PauseTrigger,
- NI_10MHzRefClock,
- NI_ChangeDetectionEvent,
- NI_WatchdogExpiredEvent,
- 0, /* Termination */
- }
- },
- {
- .dest = NI_WatchdogExpirationTrigger,
- .src = (int[]){
- TRIGGER_LINE(0),
- TRIGGER_LINE(1),
- TRIGGER_LINE(2),
- TRIGGER_LINE(3),
- TRIGGER_LINE(4),
- TRIGGER_LINE(5),
- TRIGGER_LINE(6),
- TRIGGER_LINE(7),
- 0, /* Termination */
- }
- },
- { /* Termination of list */
- .dest = 0,
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values.c
deleted file mode 100644
index 5901762734ed..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_route_values.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_route_values.c
- * Route information for NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * This file includes the tables that are a list of all the values of various
- * signals routes available on NI hardware. In many cases, one does not
- * explicitly make these routes, rather one might indicate that something is
- * used as the source of one particular trigger or another (using
- * *_src=TRIG_EXT).
- *
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "ni_route_values.h"
-#include "ni_route_values/all.h"
-
-const struct family_route_values *const ni_all_route_values[] = {
- &ni_660x_route_values,
- &ni_eseries_route_values,
- &ni_mseries_route_values,
- NULL,
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values.h b/drivers/staging/comedi/drivers/ni_routing/ni_route_values.h
deleted file mode 100644
index 80e0145fb82b..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_route_values.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_route_values.h
- * Route information for NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-#ifndef _COMEDI_DRIVERS_NI_ROUTINT_NI_ROUTE_VALUES_H
-#define _COMEDI_DRIVERS_NI_ROUTINT_NI_ROUTE_VALUES_H
-
-#include "../../comedi.h"
-#include <linux/types.h>
-
-/*
- * This file includes the tables that are a list of all the values of various
- * signals routes available on NI hardware. In many cases, one does not
- * explicitly make these routes, rather one might indicate that something is
- * used as the source of one particular trigger or another (using
- * *_src=TRIG_EXT).
- *
- * This file is meant to be included by comedi/drivers/ni_routes.c
- */
-
-#define B(x) ((x) - NI_NAMES_BASE)
-
-/** Marks a register value as valid, implemented, and tested. */
-#define V(x) (((x) & 0x7f) | 0x80)
-
-#ifndef NI_ROUTE_VALUE_EXTERNAL_CONVERSION
- /** Marks a register value as implemented but needing testing. */
- #define I(x) V(x)
- /** Marks a register value as not implemented. */
- #define U(x) 0x0
-
- typedef u8 register_type;
-#else
- /** Marks a register value as implemented but needing testing. */
- #define I(x) (((x) & 0x7f) | 0x100)
- /** Marks a register value as not implemented. */
- #define U(x) (((x) & 0x7f) | 0x200)
-
- /** Tests whether a register is marked as valid/implemented/tested */
- #define MARKED_V(x) (((x) & 0x80) != 0)
- /** Tests whether a register is implemented but not tested */
- #define MARKED_I(x) (((x) & 0x100) != 0)
- /** Tests whether a register is not implemented */
- #define MARKED_U(x) (((x) & 0x200) != 0)
-
- /* need more space to store extra marks */
- typedef u16 register_type;
-#endif
-
-/* Mask out the marking bit(s). */
-#define UNMARK(x) ((x) & 0x7f)
-
-/*
- * Gi_SRC(x,1) implements Gi_Src_SubSelect = 1
- *
- * This appears to only really be a valid MUX for m-series devices.
- */
-#define Gi_SRC(val, subsel) ((val) | ((subsel) << 6))
-
-/**
- * struct family_route_values - Register values for all routes for a particular
- * family.
- * @family: lower-case string representation of a specific series or family of
- * devices from National Instruments where each member of this family
- * shares the same register values for the various signal MUXes. It
- * should be noted that not all devices of any family have access to
- * all routes defined.
- * @register_values: Table of all register values for various signal MUXes on
- * National Instruments devices. The first index of this table is the
- * signal destination (i.e. identification of the signal MUX). The
- * second index of this table is the signal source (i.e. input of the
- * signal MUX).
- */
-struct family_route_values {
- const char *family;
- const register_type register_values[NI_NUM_NAMES][NI_NUM_NAMES];
-
-};
-
-extern const struct family_route_values *const ni_all_route_values[];
-
-#endif /* _COMEDI_DRIVERS_NI_ROUTINT_NI_ROUTE_VALUES_H */
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/all.h b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/all.h
deleted file mode 100644
index 7227461500b5..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/all.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_route_values/all.h
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
-#define _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
-
-#include "../ni_route_values.h"
-
-extern const struct family_route_values ni_660x_route_values;
-extern const struct family_route_values ni_eseries_route_values;
-extern const struct family_route_values ni_mseries_route_values;
-
-#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_660x.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_660x.c
deleted file mode 100644
index f1c7e6646261..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_660x.c
+++ /dev/null
@@ -1,650 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_route_values/ni_660x.c
- * Route information for NI_660X boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * This file includes a list of all the values of various signals routes
- * available on NI 660x hardware. In many cases, one does not explicitly make
- * these routes, rather one might indicate that something is used as the source
- * of one particular trigger or another (using *_src=TRIG_EXT).
- *
- * The contents of this file can be generated using the tools in
- * comedi/drivers/ni_routing/tools. This file also contains specific notes to
- * this family of devices.
- *
- * Please use those tools to help maintain the contents of this file, but be
- * mindful to not lose the notes already made in this file, since these notes
- * are critical to a complete undertsanding of the register values of this
- * family.
- */
-
-#include "../ni_route_values.h"
-#include "all.h"
-
-const struct family_route_values ni_660x_route_values = {
- .family = "ni_660x",
- .register_values = {
- /*
- * destination = {
- * source = register value,
- * ...
- * }
- */
- [B(NI_PFI(8))] = {
- [B(NI_CtrInternalOutput(7))] = I(1),
- },
- [B(NI_PFI(10))] = {
- [B(NI_CtrGate(7))] = I(1),
- },
- [B(NI_PFI(11))] = {
- [B(NI_CtrSource(7))] = I(1),
- },
- [B(NI_PFI(12))] = {
- [B(NI_CtrInternalOutput(6))] = I(1),
- },
- [B(NI_PFI(14))] = {
- [B(NI_CtrGate(6))] = I(1),
- },
- [B(NI_PFI(15))] = {
- [B(NI_CtrSource(6))] = I(1),
- },
- [B(NI_PFI(16))] = {
- [B(NI_CtrInternalOutput(5))] = I(1),
- },
- [B(NI_PFI(18))] = {
- [B(NI_CtrGate(5))] = I(1),
- },
- [B(NI_PFI(19))] = {
- [B(NI_CtrSource(5))] = I(1),
- },
- [B(NI_PFI(20))] = {
- [B(NI_CtrInternalOutput(4))] = I(1),
- },
- [B(NI_PFI(22))] = {
- [B(NI_CtrGate(4))] = I(1),
- },
- [B(NI_PFI(23))] = {
- [B(NI_CtrSource(4))] = I(1),
- },
- [B(NI_PFI(24))] = {
- [B(NI_CtrInternalOutput(3))] = I(1),
- },
- [B(NI_PFI(26))] = {
- [B(NI_CtrGate(3))] = I(1),
- },
- [B(NI_PFI(27))] = {
- [B(NI_CtrSource(3))] = I(1),
- },
- [B(NI_PFI(28))] = {
- [B(NI_CtrInternalOutput(2))] = I(1),
- },
- [B(NI_PFI(30))] = {
- [B(NI_CtrGate(2))] = I(1),
- },
- [B(NI_PFI(31))] = {
- [B(NI_CtrSource(2))] = I(1),
- },
- [B(NI_PFI(32))] = {
- [B(NI_CtrInternalOutput(1))] = I(1),
- },
- [B(NI_PFI(34))] = {
- [B(NI_CtrGate(1))] = I(1),
- },
- [B(NI_PFI(35))] = {
- [B(NI_CtrSource(1))] = I(1),
- },
- [B(NI_PFI(36))] = {
- [B(NI_CtrInternalOutput(0))] = I(1),
- },
- [B(NI_PFI(38))] = {
- [B(NI_CtrGate(0))] = I(1),
- },
- [B(NI_PFI(39))] = {
- [B(NI_CtrSource(0))] = I(1),
- },
- [B(NI_CtrSource(0))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9),
- [B(NI_PFI(15))] = U(8),
- [B(NI_PFI(19))] = U(7),
- [B(NI_PFI(23))] = U(6),
- [B(NI_PFI(27))] = U(5),
- [B(NI_PFI(31))] = U(4),
- [B(NI_PFI(35))] = U(3),
- [B(NI_PFI(39))] = U(2 /* or 1 */),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(1))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(1))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9),
- [B(NI_PFI(15))] = U(8),
- [B(NI_PFI(19))] = U(7),
- [B(NI_PFI(23))] = U(6),
- [B(NI_PFI(27))] = U(5),
- [B(NI_PFI(31))] = U(4),
- [B(NI_PFI(35))] = U(3 /* or 1 */),
- [B(NI_PFI(39))] = U(2),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(2))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(2))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9),
- [B(NI_PFI(15))] = U(8),
- [B(NI_PFI(19))] = U(7),
- [B(NI_PFI(23))] = U(6),
- [B(NI_PFI(27))] = U(5),
- [B(NI_PFI(31))] = U(4 /* or 1 */),
- [B(NI_PFI(35))] = U(3),
- [B(NI_PFI(39))] = U(2),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(3))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(3))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9),
- [B(NI_PFI(15))] = U(8),
- [B(NI_PFI(19))] = U(7),
- [B(NI_PFI(23))] = U(6),
- [B(NI_PFI(27))] = U(5 /* or 1 */),
- [B(NI_PFI(31))] = U(4),
- [B(NI_PFI(35))] = U(3),
- [B(NI_PFI(39))] = U(2),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(4))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(4))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9),
- [B(NI_PFI(15))] = U(8),
- [B(NI_PFI(19))] = U(7),
- [B(NI_PFI(23))] = U(6 /* or 1 */),
- [B(NI_PFI(27))] = U(5),
- [B(NI_PFI(31))] = U(4),
- [B(NI_PFI(35))] = U(3),
- [B(NI_PFI(39))] = U(2),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(5))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(5))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9),
- [B(NI_PFI(15))] = U(8),
- [B(NI_PFI(19))] = U(7 /* or 1 */),
- [B(NI_PFI(23))] = U(6),
- [B(NI_PFI(27))] = U(5),
- [B(NI_PFI(31))] = U(4),
- [B(NI_PFI(35))] = U(3),
- [B(NI_PFI(39))] = U(2),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(6))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(6))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9),
- [B(NI_PFI(15))] = U(8 /* or 1 */),
- [B(NI_PFI(19))] = U(7),
- [B(NI_PFI(23))] = U(6),
- [B(NI_PFI(27))] = U(5),
- [B(NI_PFI(31))] = U(4),
- [B(NI_PFI(35))] = U(3),
- [B(NI_PFI(39))] = U(2),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(7))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(7))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(11))] = U(9 /* or 1 */),
- [B(NI_PFI(15))] = U(8),
- [B(NI_PFI(19))] = U(7),
- [B(NI_PFI(23))] = U(6),
- [B(NI_PFI(27))] = U(5),
- [B(NI_PFI(31))] = U(4),
- [B(NI_PFI(35))] = U(3),
- [B(NI_PFI(39))] = U(2),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrGate(0))] = U(10),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(30),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrGate(0))] = {
- [B(NI_PFI(10))] = I(9),
- [B(NI_PFI(14))] = I(8),
- [B(NI_PFI(18))] = I(7),
- [B(NI_PFI(22))] = I(6),
- [B(NI_PFI(26))] = I(5),
- [B(NI_PFI(30))] = I(4),
- [B(NI_PFI(34))] = I(3),
- [B(NI_PFI(38))] = I(2 /* or 1 */),
- [B(NI_PFI(39))] = I(0),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(1))] = I(10),
- [B(NI_CtrInternalOutput(1))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrGate(1))] = {
- [B(NI_PFI(10))] = I(9),
- [B(NI_PFI(14))] = I(8),
- [B(NI_PFI(18))] = I(7),
- [B(NI_PFI(22))] = I(6),
- [B(NI_PFI(26))] = I(5),
- [B(NI_PFI(30))] = I(4),
- [B(NI_PFI(34))] = I(3 /* or 1 */),
- [B(NI_PFI(35))] = I(0),
- [B(NI_PFI(38))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(2))] = I(10),
- [B(NI_CtrInternalOutput(2))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrGate(2))] = {
- [B(NI_PFI(10))] = I(9),
- [B(NI_PFI(14))] = I(8),
- [B(NI_PFI(18))] = I(7),
- [B(NI_PFI(22))] = I(6),
- [B(NI_PFI(26))] = I(5),
- [B(NI_PFI(30))] = I(4 /* or 1 */),
- [B(NI_PFI(31))] = I(0),
- [B(NI_PFI(34))] = I(3),
- [B(NI_PFI(38))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(3))] = I(10),
- [B(NI_CtrInternalOutput(3))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrGate(3))] = {
- [B(NI_PFI(10))] = I(9),
- [B(NI_PFI(14))] = I(8),
- [B(NI_PFI(18))] = I(7),
- [B(NI_PFI(22))] = I(6),
- [B(NI_PFI(26))] = I(5 /* or 1 */),
- [B(NI_PFI(27))] = I(0),
- [B(NI_PFI(30))] = I(4),
- [B(NI_PFI(34))] = I(3),
- [B(NI_PFI(38))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(4))] = I(10),
- [B(NI_CtrInternalOutput(4))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrGate(4))] = {
- [B(NI_PFI(10))] = I(9),
- [B(NI_PFI(14))] = I(8),
- [B(NI_PFI(18))] = I(7),
- [B(NI_PFI(22))] = I(6 /* or 1 */),
- [B(NI_PFI(23))] = I(0),
- [B(NI_PFI(26))] = I(5),
- [B(NI_PFI(30))] = I(4),
- [B(NI_PFI(34))] = I(3),
- [B(NI_PFI(38))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(5))] = I(10),
- [B(NI_CtrInternalOutput(5))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrGate(5))] = {
- [B(NI_PFI(10))] = I(9),
- [B(NI_PFI(14))] = I(8),
- [B(NI_PFI(18))] = I(7 /* or 1 */),
- [B(NI_PFI(19))] = I(0),
- [B(NI_PFI(22))] = I(6),
- [B(NI_PFI(26))] = I(5),
- [B(NI_PFI(30))] = I(4),
- [B(NI_PFI(34))] = I(3),
- [B(NI_PFI(38))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(6))] = I(10),
- [B(NI_CtrInternalOutput(6))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrGate(6))] = {
- [B(NI_PFI(10))] = I(9),
- [B(NI_PFI(14))] = I(8 /* or 1 */),
- [B(NI_PFI(15))] = I(0),
- [B(NI_PFI(18))] = I(7),
- [B(NI_PFI(22))] = I(6),
- [B(NI_PFI(26))] = I(5),
- [B(NI_PFI(30))] = I(4),
- [B(NI_PFI(34))] = I(3),
- [B(NI_PFI(38))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(7))] = I(10),
- [B(NI_CtrInternalOutput(7))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrGate(7))] = {
- [B(NI_PFI(10))] = I(9 /* or 1 */),
- [B(NI_PFI(11))] = I(0),
- [B(NI_PFI(14))] = I(8),
- [B(NI_PFI(18))] = I(7),
- [B(NI_PFI(22))] = I(6),
- [B(NI_PFI(26))] = I(5),
- [B(NI_PFI(30))] = I(4),
- [B(NI_PFI(34))] = I(3),
- [B(NI_PFI(38))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(0))] = I(10),
- [B(NI_CtrInternalOutput(0))] = I(20),
- [B(NI_LogicLow)] = I(31 /* or 30 */),
- },
- [B(NI_CtrAux(0))] = {
- [B(NI_PFI(9))] = I(9),
- [B(NI_PFI(13))] = I(8),
- [B(NI_PFI(17))] = I(7),
- [B(NI_PFI(21))] = I(6),
- [B(NI_PFI(25))] = I(5),
- [B(NI_PFI(29))] = I(4),
- [B(NI_PFI(33))] = I(3),
- [B(NI_PFI(37))] = I(2 /* or 1 */),
- [B(NI_PFI(39))] = I(0),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(1))] = I(10),
- [B(NI_CtrGate(1))] = I(30),
- [B(NI_CtrInternalOutput(1))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(1))] = {
- [B(NI_PFI(9))] = I(9),
- [B(NI_PFI(13))] = I(8),
- [B(NI_PFI(17))] = I(7),
- [B(NI_PFI(21))] = I(6),
- [B(NI_PFI(25))] = I(5),
- [B(NI_PFI(29))] = I(4),
- [B(NI_PFI(33))] = I(3 /* or 1 */),
- [B(NI_PFI(35))] = I(0),
- [B(NI_PFI(37))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(2))] = I(10),
- [B(NI_CtrGate(2))] = I(30),
- [B(NI_CtrInternalOutput(2))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(2))] = {
- [B(NI_PFI(9))] = I(9),
- [B(NI_PFI(13))] = I(8),
- [B(NI_PFI(17))] = I(7),
- [B(NI_PFI(21))] = I(6),
- [B(NI_PFI(25))] = I(5),
- [B(NI_PFI(29))] = I(4 /* or 1 */),
- [B(NI_PFI(31))] = I(0),
- [B(NI_PFI(33))] = I(3),
- [B(NI_PFI(37))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(3))] = I(10),
- [B(NI_CtrGate(3))] = I(30),
- [B(NI_CtrInternalOutput(3))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(3))] = {
- [B(NI_PFI(9))] = I(9),
- [B(NI_PFI(13))] = I(8),
- [B(NI_PFI(17))] = I(7),
- [B(NI_PFI(21))] = I(6),
- [B(NI_PFI(25))] = I(5 /* or 1 */),
- [B(NI_PFI(27))] = I(0),
- [B(NI_PFI(29))] = I(4),
- [B(NI_PFI(33))] = I(3),
- [B(NI_PFI(37))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(4))] = I(10),
- [B(NI_CtrGate(4))] = I(30),
- [B(NI_CtrInternalOutput(4))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(4))] = {
- [B(NI_PFI(9))] = I(9),
- [B(NI_PFI(13))] = I(8),
- [B(NI_PFI(17))] = I(7),
- [B(NI_PFI(21))] = I(6 /* or 1 */),
- [B(NI_PFI(23))] = I(0),
- [B(NI_PFI(25))] = I(5),
- [B(NI_PFI(29))] = I(4),
- [B(NI_PFI(33))] = I(3),
- [B(NI_PFI(37))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(5))] = I(10),
- [B(NI_CtrGate(5))] = I(30),
- [B(NI_CtrInternalOutput(5))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(5))] = {
- [B(NI_PFI(9))] = I(9),
- [B(NI_PFI(13))] = I(8),
- [B(NI_PFI(17))] = I(7 /* or 1 */),
- [B(NI_PFI(19))] = I(0),
- [B(NI_PFI(21))] = I(6),
- [B(NI_PFI(25))] = I(5),
- [B(NI_PFI(29))] = I(4),
- [B(NI_PFI(33))] = I(3),
- [B(NI_PFI(37))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(6))] = I(10),
- [B(NI_CtrGate(6))] = I(30),
- [B(NI_CtrInternalOutput(6))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(6))] = {
- [B(NI_PFI(9))] = I(9),
- [B(NI_PFI(13))] = I(8 /* or 1 */),
- [B(NI_PFI(15))] = I(0),
- [B(NI_PFI(17))] = I(7),
- [B(NI_PFI(21))] = I(6),
- [B(NI_PFI(25))] = I(5),
- [B(NI_PFI(29))] = I(4),
- [B(NI_PFI(33))] = I(3),
- [B(NI_PFI(37))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(7))] = I(10),
- [B(NI_CtrGate(7))] = I(30),
- [B(NI_CtrInternalOutput(7))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(7))] = {
- [B(NI_PFI(9))] = I(9 /* or 1 */),
- [B(NI_PFI(11))] = I(0),
- [B(NI_PFI(13))] = I(8),
- [B(NI_PFI(17))] = I(7),
- [B(NI_PFI(21))] = I(6),
- [B(NI_PFI(25))] = I(5),
- [B(NI_PFI(29))] = I(4),
- [B(NI_PFI(33))] = I(3),
- [B(NI_PFI(37))] = I(2),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrSource(0))] = I(10),
- [B(NI_CtrGate(0))] = I(30),
- [B(NI_CtrInternalOutput(0))] = I(20),
- [B(NI_LogicLow)] = I(31),
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_eseries.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_eseries.c
deleted file mode 100644
index d1ab3c9ce585..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_eseries.c
+++ /dev/null
@@ -1,602 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_route_values/ni_eseries.c
- * Route information for NI_ESERIES boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * This file includes a list of all the values of various signals routes
- * available on NI 660x hardware. In many cases, one does not explicitly make
- * these routes, rather one might indicate that something is used as the source
- * of one particular trigger or another (using *_src=TRIG_EXT).
- *
- * The contents of this file can be generated using the tools in
- * comedi/drivers/ni_routing/tools. This file also contains specific notes to
- * this family of devices.
- *
- * Please use those tools to help maintain the contents of this file, but be
- * mindful to not lose the notes already made in this file, since these notes
- * are critical to a complete undertsanding of the register values of this
- * family.
- */
-
-#include "../ni_route_values.h"
-#include "all.h"
-
-/*
- * Note that for e-series devices, the backplane TRIGGER_LINE(6) is generally
- * not connected to RTSI(6).
- */
-
-const struct family_route_values ni_eseries_route_values = {
- .family = "ni_eseries",
- .register_values = {
- /*
- * destination = {
- * source = register value,
- * ...
- * }
- */
- [B(NI_PFI(0))] = {
- [B(NI_AI_StartTrigger)] = I(NI_PFI_OUTPUT_AI_START1),
- },
- [B(NI_PFI(1))] = {
- [B(NI_AI_ReferenceTrigger)] = I(NI_PFI_OUTPUT_AI_START2),
- },
- [B(NI_PFI(2))] = {
- [B(NI_AI_ConvertClock)] = I(NI_PFI_OUTPUT_AI_CONVERT),
- },
- [B(NI_PFI(3))] = {
- [B(NI_CtrSource(1))] = I(NI_PFI_OUTPUT_G_SRC1),
- },
- [B(NI_PFI(4))] = {
- [B(NI_CtrGate(1))] = I(NI_PFI_OUTPUT_G_GATE1),
- },
- [B(NI_PFI(5))] = {
- [B(NI_AO_SampleClock)] = I(NI_PFI_OUTPUT_AO_UPDATE_N),
- },
- [B(NI_PFI(6))] = {
- [B(NI_AO_StartTrigger)] = I(NI_PFI_OUTPUT_AO_START1),
- },
- [B(NI_PFI(7))] = {
- [B(NI_AI_SampleClock)] = I(NI_PFI_OUTPUT_AI_START_PULSE),
- },
- [B(NI_PFI(8))] = {
- [B(NI_CtrSource(0))] = I(NI_PFI_OUTPUT_G_SRC0),
- },
- [B(NI_PFI(9))] = {
- [B(NI_CtrGate(0))] = I(NI_PFI_OUTPUT_G_GATE0),
- },
- [B(TRIGGER_LINE(0))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(1))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(2))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(3))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(4))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(5))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(6))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(7))] = {
- [B(NI_20MHzTimebase)] = I(NI_RTSI_OUTPUT_RTSI_OSC),
- },
- [B(NI_RTSI_BRD(0))] = {
- [B(TRIGGER_LINE(0))] = I(0),
- [B(TRIGGER_LINE(1))] = I(1),
- [B(TRIGGER_LINE(2))] = I(2),
- [B(TRIGGER_LINE(3))] = I(3),
- [B(TRIGGER_LINE(4))] = I(4),
- [B(TRIGGER_LINE(5))] = I(5),
- [B(TRIGGER_LINE(6))] = I(6),
- [B(PXI_Star)] = I(6),
- [B(NI_AI_STOP)] = I(7),
- },
- [B(NI_RTSI_BRD(1))] = {
- [B(TRIGGER_LINE(0))] = I(0),
- [B(TRIGGER_LINE(1))] = I(1),
- [B(TRIGGER_LINE(2))] = I(2),
- [B(TRIGGER_LINE(3))] = I(3),
- [B(TRIGGER_LINE(4))] = I(4),
- [B(TRIGGER_LINE(5))] = I(5),
- [B(TRIGGER_LINE(6))] = I(6),
- [B(PXI_Star)] = I(6),
- [B(NI_AI_STOP)] = I(7),
- },
- [B(NI_RTSI_BRD(2))] = {
- [B(TRIGGER_LINE(0))] = I(0),
- [B(TRIGGER_LINE(1))] = I(1),
- [B(TRIGGER_LINE(2))] = I(2),
- [B(TRIGGER_LINE(3))] = I(3),
- [B(TRIGGER_LINE(4))] = I(4),
- [B(TRIGGER_LINE(5))] = I(5),
- [B(TRIGGER_LINE(6))] = I(6),
- [B(PXI_Star)] = I(6),
- [B(NI_AI_SampleClock)] = I(7),
- },
- [B(NI_RTSI_BRD(3))] = {
- [B(TRIGGER_LINE(0))] = I(0),
- [B(TRIGGER_LINE(1))] = I(1),
- [B(TRIGGER_LINE(2))] = I(2),
- [B(TRIGGER_LINE(3))] = I(3),
- [B(TRIGGER_LINE(4))] = I(4),
- [B(TRIGGER_LINE(5))] = I(5),
- [B(TRIGGER_LINE(6))] = I(6),
- [B(PXI_Star)] = I(6),
- [B(NI_AI_SampleClock)] = I(7),
- },
- [B(NI_CtrSource(0))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrInternalOutput(1))] = U(19),
- [B(PXI_Star)] = U(17),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(1))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(NI_CtrInternalOutput(0))] = U(19),
- [B(PXI_Star)] = U(17),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrGate(0))] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrInternalOutput(1))] = I(20),
- [B(PXI_Star)] = I(17),
- [B(NI_AI_StartTrigger)] = I(21),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrGate(1))] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrInternalOutput(0))] = I(20),
- [B(PXI_Star)] = I(17),
- [B(NI_AI_StartTrigger)] = I(21),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrOut(0))] = {
- [B(TRIGGER_LINE(0))] = I(1),
- [B(TRIGGER_LINE(1))] = I(2),
- [B(TRIGGER_LINE(2))] = I(3),
- [B(TRIGGER_LINE(3))] = I(4),
- [B(TRIGGER_LINE(4))] = I(5),
- [B(TRIGGER_LINE(5))] = I(6),
- [B(TRIGGER_LINE(6))] = I(7),
- [B(NI_CtrInternalOutput(0))] = I(0),
- [B(PXI_Star)] = I(7),
- },
- [B(NI_CtrOut(1))] = {
- [B(NI_CtrInternalOutput(1))] = I(0),
- },
- [B(NI_AI_SampleClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrInternalOutput(0))] = I(19),
- [B(PXI_Star)] = I(17),
- [B(NI_AI_SampleClockTimebase)] = I(0),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AI_SampleClockTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(PXI_Star)] = U(17),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_100kHzTimebase)] = U(19),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_AI_StartTrigger)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrInternalOutput(0))] = I(18),
- [B(PXI_Star)] = I(17),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AI_ReferenceTrigger)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(PXI_Star)] = U(17),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_AI_ConvertClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrInternalOutput(0))] = I(19),
- [B(PXI_Star)] = I(17),
- [B(NI_AI_ConvertClockTimebase)] = I(0),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AI_ConvertClockTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_AI_SampleClockTimebase)] = U(0),
- [B(NI_20MHzTimebase)] = U(1),
- },
- [B(NI_AI_PauseTrigger)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(PXI_Star)] = U(17),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_AO_SampleClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(NI_CtrInternalOutput(1))] = I(19),
- [B(PXI_Star)] = I(17),
- [B(NI_AO_SampleClockTimebase)] = I(0),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AO_SampleClockTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(PXI_Star)] = U(17),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_100kHzTimebase)] = U(19),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_AO_StartTrigger)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(PXI_Star)] = I(17),
- /*
- * for the signal route
- * (NI_AI_StartTrigger->NI_AO_StartTrigger), MHDDK says
- * used register value 18 and DAQ-STC says 19.
- * Hoping that the MHDDK is correct--being a "working"
- * example.
- */
- [B(NI_AI_StartTrigger)] = I(18),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AO_PauseTrigger)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(PXI_Star)] = U(17),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_MasterTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(TRIGGER_LINE(7))] = U(1),
- [B(PXI_Star)] = U(2),
- [B(PXI_Clk10)] = U(3),
- [B(NI_10MHzRefClock)] = U(0),
- },
- /*
- * This symbol is not defined and nothing for this is
- * implemented--just including this because data was found in
- * the NI-STC for it--can't remember where.
- * [B(NI_FrequencyOutTimebase)] = {
- * ** These are not currently implemented in ni modules **
- * [B(NI_20MHzTimebase)] = U(0),
- * [B(NI_100kHzTimebase)] = U(1),
- * },
- */
- [B(NI_RGOUT0)] = {
- [B(NI_CtrInternalOutput(0))] = I(0),
- [B(NI_CtrOut(0))] = I(1),
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_mseries.c b/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_mseries.c
deleted file mode 100644
index c59d8afe0ae9..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/ni_route_values/ni_mseries.c
+++ /dev/null
@@ -1,1752 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/ni_route_values/ni_mseries.c
- * Route information for NI_MSERIES boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * This file includes a list of all the values of various signals routes
- * available on NI 660x hardware. In many cases, one does not explicitly make
- * these routes, rather one might indicate that something is used as the source
- * of one particular trigger or another (using *_src=TRIG_EXT).
- *
- * The contents of this file can be generated using the tools in
- * comedi/drivers/ni_routing/tools. This file also contains specific notes to
- * this family of devices.
- *
- * Please use those tools to help maintain the contents of this file, but be
- * mindful to not lose the notes already made in this file, since these notes
- * are critical to a complete undertsanding of the register values of this
- * family.
- */
-
-#include "../ni_route_values.h"
-#include "all.h"
-
-/*
- * GATE SELECT NOTE:
- * CtrAux and CtrArmStartrigger register values are not documented in the
- * DAQ-STC. There is some evidence that using CtrGate values is valid (see
- * comedi.h). Some information and hints exist in the M-Series user manual
- * (ni-62xx user-manual 371022K-01).
- */
-
-const struct family_route_values ni_mseries_route_values = {
- .family = "ni_mseries",
- .register_values = {
- /*
- * destination = {
- * source = register value,
- * ...
- * }
- */
- [B(NI_PFI(0))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(1))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(2))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(3))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(4))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(5))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(6))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(7))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(8))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(9))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(10))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(11))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(12))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(13))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(14))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(NI_PFI(15))] = {
- [B(TRIGGER_LINE(0))] = I(18),
- [B(TRIGGER_LINE(1))] = I(19),
- [B(TRIGGER_LINE(2))] = I(20),
- [B(TRIGGER_LINE(3))] = I(21),
- [B(TRIGGER_LINE(4))] = I(22),
- [B(TRIGGER_LINE(5))] = I(23),
- [B(TRIGGER_LINE(6))] = I(24),
- [B(TRIGGER_LINE(7))] = I(25),
- [B(NI_CtrSource(0))] = I(9),
- [B(NI_CtrSource(1))] = I(4),
- [B(NI_CtrGate(0))] = I(10),
- [B(NI_CtrGate(1))] = I(5),
- [B(NI_CtrInternalOutput(0))] = I(13),
- [B(NI_CtrInternalOutput(1))] = I(14),
- [B(PXI_Star)] = I(26),
- [B(NI_AI_SampleClock)] = I(8),
- [B(NI_AI_StartTrigger)] = I(1),
- [B(NI_AI_ReferenceTrigger)] = I(2),
- [B(NI_AI_ConvertClock)] = I(3),
- [B(NI_AI_ExternalMUXClock)] = I(12),
- [B(NI_AO_SampleClock)] = I(6),
- [B(NI_AO_StartTrigger)] = I(7),
- [B(NI_DI_SampleClock)] = I(29),
- [B(NI_DO_SampleClock)] = I(30),
- [B(NI_FrequencyOutput)] = I(15),
- [B(NI_ChangeDetectionEvent)] = I(28),
- [B(NI_AnalogComparisonEvent)] = I(17),
- [B(NI_SCXI_Trig1)] = I(27),
- [B(NI_ExternalStrobe)] = I(11),
- [B(NI_PFI_DO)] = I(16),
- },
- [B(TRIGGER_LINE(0))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(1))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(2))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(3))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(4))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(5))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(6))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(TRIGGER_LINE(7))] = {
- [B(NI_RTSI_BRD(0))] = I(8),
- [B(NI_RTSI_BRD(1))] = I(9),
- [B(NI_RTSI_BRD(2))] = I(10),
- [B(NI_RTSI_BRD(3))] = I(11),
- [B(NI_CtrSource(0))] = I(5),
- [B(NI_CtrGate(0))] = I(6),
- [B(NI_AI_StartTrigger)] = I(0),
- [B(NI_AI_ReferenceTrigger)] = I(1),
- [B(NI_AI_ConvertClock)] = I(2),
- [B(NI_AO_SampleClock)] = I(3),
- [B(NI_AO_StartTrigger)] = I(4),
- /*
- * for (*->TRIGGER_LINE(*)) MUX, a value of 12 should be
- * RTSI_OSC according to MHDDK mseries source. There
- * are hints in comedi that show that this is actually a
- * 20MHz source for 628x cards(?)
- */
- [B(NI_10MHzRefClock)] = I(12),
- [B(NI_RGOUT0)] = I(7),
- },
- [B(NI_RTSI_BRD(0))] = {
- [B(NI_PFI(0))] = I(0),
- [B(NI_PFI(1))] = I(1),
- [B(NI_PFI(2))] = I(2),
- [B(NI_PFI(3))] = I(3),
- [B(NI_PFI(4))] = I(4),
- [B(NI_PFI(5))] = I(5),
- [B(NI_CtrSource(1))] = I(11),
- [B(NI_CtrGate(1))] = I(10),
- [B(NI_CtrZ(0))] = I(13),
- [B(NI_CtrZ(1))] = I(12),
- [B(NI_CtrOut(1))] = I(9),
- [B(NI_AI_SampleClock)] = I(15),
- [B(NI_AI_PauseTrigger)] = I(7),
- [B(NI_AO_PauseTrigger)] = I(6),
- [B(NI_FrequencyOutput)] = I(8),
- [B(NI_AnalogComparisonEvent)] = I(14),
- },
- [B(NI_RTSI_BRD(1))] = {
- [B(NI_PFI(0))] = I(0),
- [B(NI_PFI(1))] = I(1),
- [B(NI_PFI(2))] = I(2),
- [B(NI_PFI(3))] = I(3),
- [B(NI_PFI(4))] = I(4),
- [B(NI_PFI(5))] = I(5),
- [B(NI_CtrSource(1))] = I(11),
- [B(NI_CtrGate(1))] = I(10),
- [B(NI_CtrZ(0))] = I(13),
- [B(NI_CtrZ(1))] = I(12),
- [B(NI_CtrOut(1))] = I(9),
- [B(NI_AI_SampleClock)] = I(15),
- [B(NI_AI_PauseTrigger)] = I(7),
- [B(NI_AO_PauseTrigger)] = I(6),
- [B(NI_FrequencyOutput)] = I(8),
- [B(NI_AnalogComparisonEvent)] = I(14),
- },
- [B(NI_RTSI_BRD(2))] = {
- [B(NI_PFI(0))] = I(0),
- [B(NI_PFI(1))] = I(1),
- [B(NI_PFI(2))] = I(2),
- [B(NI_PFI(3))] = I(3),
- [B(NI_PFI(4))] = I(4),
- [B(NI_PFI(5))] = I(5),
- [B(NI_CtrSource(1))] = I(11),
- [B(NI_CtrGate(1))] = I(10),
- [B(NI_CtrZ(0))] = I(13),
- [B(NI_CtrZ(1))] = I(12),
- [B(NI_CtrOut(1))] = I(9),
- [B(NI_AI_SampleClock)] = I(15),
- [B(NI_AI_PauseTrigger)] = I(7),
- [B(NI_AO_PauseTrigger)] = I(6),
- [B(NI_FrequencyOutput)] = I(8),
- [B(NI_AnalogComparisonEvent)] = I(14),
- },
- [B(NI_RTSI_BRD(3))] = {
- [B(NI_PFI(0))] = I(0),
- [B(NI_PFI(1))] = I(1),
- [B(NI_PFI(2))] = I(2),
- [B(NI_PFI(3))] = I(3),
- [B(NI_PFI(4))] = I(4),
- [B(NI_PFI(5))] = I(5),
- [B(NI_CtrSource(1))] = I(11),
- [B(NI_CtrGate(1))] = I(10),
- [B(NI_CtrZ(0))] = I(13),
- [B(NI_CtrZ(1))] = I(12),
- [B(NI_CtrOut(1))] = I(9),
- [B(NI_AI_SampleClock)] = I(15),
- [B(NI_AI_PauseTrigger)] = I(7),
- [B(NI_AO_PauseTrigger)] = I(6),
- [B(NI_FrequencyOutput)] = I(8),
- [B(NI_AnalogComparisonEvent)] = I(14),
- },
- [B(NI_CtrSource(0))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(NI_PFI(10))] = U(21),
- [B(NI_PFI(11))] = U(22),
- [B(NI_PFI(12))] = U(23),
- [B(NI_PFI(13))] = U(24),
- [B(NI_PFI(14))] = U(25),
- [B(NI_PFI(15))] = U(26),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(NI_CtrGate(1))] = U(Gi_SRC(20, 0)),
- [B(NI_CtrInternalOutput(1))] = U(19),
- [B(PXI_Star)] = U(Gi_SRC(20, 1)),
- [B(PXI_Clk10)] = U(29),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(Gi_SRC(30, 0)),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_AnalogComparisonEvent)] = U(Gi_SRC(30, 1)),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrSource(1))] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(NI_PFI(10))] = U(21),
- [B(NI_PFI(11))] = U(22),
- [B(NI_PFI(12))] = U(23),
- [B(NI_PFI(13))] = U(24),
- [B(NI_PFI(14))] = U(25),
- [B(NI_PFI(15))] = U(26),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(NI_CtrGate(0))] = U(Gi_SRC(20, 0)),
- [B(NI_CtrInternalOutput(0))] = U(19),
- [B(PXI_Star)] = U(Gi_SRC(20, 1)),
- [B(PXI_Clk10)] = U(29),
- [B(NI_20MHzTimebase)] = U(0),
- [B(NI_80MHzTimebase)] = U(Gi_SRC(30, 0)),
- [B(NI_100kHzTimebase)] = U(18),
- [B(NI_AnalogComparisonEvent)] = U(Gi_SRC(30, 1)),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_CtrGate(0))] = {
- [B(NI_PFI(0))] = I(1 /* source: mhddk examples */),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrSource(1))] = I(29),
- /* source for following line: mhddk GP examples */
- [B(NI_CtrInternalOutput(1))] = I(20),
- [B(PXI_Star)] = I(19),
- [B(NI_AI_StartTrigger)] = I(28),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrGate(1))] = {
- /* source for following line: mhddk examples */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrSource(0))] = I(29),
- /* source for following line: mhddk GP examples */
- [B(NI_CtrInternalOutput(0))] = I(20),
- [B(PXI_Star)] = I(19),
- [B(NI_AI_StartTrigger)] = I(28),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(0))] = {
- /* these are just a guess; see GATE SELECT NOTE */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrSource(1))] = I(29),
- /* source for following line: mhddk GP examples */
- [B(NI_CtrInternalOutput(1))] = I(20),
- [B(PXI_Star)] = I(19),
- [B(NI_AI_StartTrigger)] = I(28),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrAux(1))] = {
- /* these are just a guess; see GATE SELECT NOTE */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrSource(0))] = I(29),
- /* source for following line: mhddk GP examples */
- [B(NI_CtrInternalOutput(0))] = I(20),
- [B(PXI_Star)] = I(19),
- [B(NI_AI_StartTrigger)] = I(28),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrA(0))] = {
- /*
- * See nimseries/Examples for outputs; inputs a guess
- * from device routes shown on NI-MAX.
- * see M-Series user manual (371022K-01)
- */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(PXI_Star)] = I(20),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrA(1))] = {
- /*
- * See nimseries/Examples for outputs; inputs a guess
- * from device routes shown on NI-MAX.
- * see M-Series user manual (371022K-01)
- */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(PXI_Star)] = I(20),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrB(0))] = {
- /*
- * See nimseries/Examples for outputs; inputs a guess
- * from device routes shown on NI-MAX.
- * see M-Series user manual (371022K-01)
- */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(PXI_Star)] = I(20),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrB(1))] = {
- /*
- * See nimseries/Examples for outputs; inputs a guess
- * from device routes shown on NI-MAX.
- * see M-Series user manual (371022K-01)
- */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(PXI_Star)] = I(20),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrZ(0))] = {
- /*
- * See nimseries/Examples for outputs; inputs a guess
- * from device routes shown on NI-MAX.
- * see M-Series user manual (371022K-01)
- */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(PXI_Star)] = I(20),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrZ(1))] = {
- /*
- * See nimseries/Examples for outputs; inputs a guess
- * from device routes shown on NI-MAX.
- * see M-Series user manual (371022K-01)
- */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(PXI_Star)] = I(20),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrArmStartTrigger(0))] = {
- /* these are just a guess; see GATE SELECT NOTE */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrSource(1))] = I(29),
- /* source for following line: mhddk GP examples */
- [B(NI_CtrInternalOutput(1))] = I(20),
- [B(PXI_Star)] = I(19),
- [B(NI_AI_StartTrigger)] = I(28),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrArmStartTrigger(1))] = {
- /* these are just a guess; see GATE SELECT NOTE */
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrSource(0))] = I(29),
- /* source for following line: mhddk GP examples */
- [B(NI_CtrInternalOutput(0))] = I(20),
- [B(PXI_Star)] = I(19),
- [B(NI_AI_StartTrigger)] = I(28),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_CtrOut(0))] = {
- [B(TRIGGER_LINE(0))] = I(1),
- [B(TRIGGER_LINE(1))] = I(2),
- [B(TRIGGER_LINE(2))] = I(3),
- [B(TRIGGER_LINE(3))] = I(4),
- [B(TRIGGER_LINE(4))] = I(5),
- [B(TRIGGER_LINE(5))] = I(6),
- [B(TRIGGER_LINE(6))] = I(7),
- [B(NI_CtrInternalOutput(0))] = I(0),
- },
- [B(NI_CtrOut(1))] = {
- [B(NI_CtrInternalOutput(1))] = I(0),
- },
- [B(NI_AI_SampleClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrInternalOutput(0))] = I(19),
- [B(NI_CtrInternalOutput(1))] = I(28),
- [B(PXI_Star)] = I(20),
- [B(NI_AI_SampleClockTimebase)] = I(0),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_SCXI_Trig1)] = I(29),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AI_SampleClockTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(NI_PFI(10))] = U(21),
- [B(NI_PFI(11))] = U(22),
- [B(NI_PFI(12))] = U(23),
- [B(NI_PFI(13))] = U(24),
- [B(NI_PFI(14))] = U(25),
- [B(NI_PFI(15))] = U(26),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(PXI_Star)] = U(20),
- [B(PXI_Clk10)] = U(29),
- /*
- * For routes (*->NI_AI_SampleClockTimebase) and
- * (*->NI_AO_SampleClockTimebase), tMSeries.h of MHDDK
- * shows 0 value as selecting ground (case ground?) and
- * 28 value selecting TIMEBASE 1.
- */
- [B(NI_20MHzTimebase)] = U(28),
- [B(NI_100kHzTimebase)] = U(19),
- [B(NI_AnalogComparisonEvent)] = U(30),
- [B(NI_LogicLow)] = U(31),
- [B(NI_CaseGround)] = U(0),
- },
- [B(NI_AI_StartTrigger)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrInternalOutput(0))] = I(18),
- [B(NI_CtrInternalOutput(1))] = I(19),
- [B(PXI_Star)] = I(20),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AI_ReferenceTrigger)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(NI_PFI(10))] = U(21),
- [B(NI_PFI(11))] = U(22),
- [B(NI_PFI(12))] = U(23),
- [B(NI_PFI(13))] = U(24),
- [B(NI_PFI(14))] = U(25),
- [B(NI_PFI(15))] = U(26),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(PXI_Star)] = U(20),
- [B(NI_AnalogComparisonEvent)] = U(30),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_AI_ConvertClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- /* source for following line: mhddk example headers */
- [B(NI_CtrInternalOutput(0))] = I(19),
- /* source for following line: mhddk example headers */
- [B(NI_CtrInternalOutput(1))] = I(18),
- [B(PXI_Star)] = I(20),
- [B(NI_AI_ConvertClockTimebase)] = I(0),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AI_ConvertClockTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_AI_SampleClockTimebase)] = U(0),
- [B(NI_20MHzTimebase)] = U(1),
- },
- [B(NI_AI_PauseTrigger)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(NI_PFI(10))] = U(21),
- [B(NI_PFI(11))] = U(22),
- [B(NI_PFI(12))] = U(23),
- [B(NI_PFI(13))] = U(24),
- [B(NI_PFI(14))] = U(25),
- [B(NI_PFI(15))] = U(26),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(PXI_Star)] = U(20),
- [B(NI_AnalogComparisonEvent)] = U(30),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_AO_SampleClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrInternalOutput(0))] = I(18),
- [B(NI_CtrInternalOutput(1))] = I(19),
- [B(PXI_Star)] = I(20),
- [B(NI_AO_SampleClockTimebase)] = I(0),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AO_SampleClockTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(NI_PFI(10))] = U(21),
- [B(NI_PFI(11))] = U(22),
- [B(NI_PFI(12))] = U(23),
- [B(NI_PFI(13))] = U(24),
- [B(NI_PFI(14))] = U(25),
- [B(NI_PFI(15))] = U(26),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(PXI_Star)] = U(20),
- [B(PXI_Clk10)] = U(29),
- /*
- * For routes (*->NI_AI_SampleClockTimebase) and
- * (*->NI_AO_SampleClockTimebase), tMSeries.h of MHDDK
- * shows 0 value as selecting ground (case ground?) and
- * 28 value selecting TIMEBASE 1.
- */
- [B(NI_20MHzTimebase)] = U(28),
- [B(NI_100kHzTimebase)] = U(19),
- [B(NI_AnalogComparisonEvent)] = U(30),
- [B(NI_LogicLow)] = U(31),
- [B(NI_CaseGround)] = U(0),
- },
- [B(NI_AO_StartTrigger)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(PXI_Star)] = I(20),
- /*
- * for the signal route
- * (NI_AI_StartTrigger->NI_AO_StartTrigger), DAQ-STC &
- * MHDDK disagreed for e-series. MHDDK for m-series
- * agrees with DAQ-STC description and uses the value 18
- * for the route
- * (NI_AI_ReferenceTrigger->NI_AO_StartTrigger). The
- * m-series devices are supposed to have DAQ-STC2.
- * There are no DAQ-STC2 docs to compare with.
- */
- [B(NI_AI_StartTrigger)] = I(19),
- [B(NI_AI_ReferenceTrigger)] = I(18),
- [B(NI_AnalogComparisonEvent)] = I(30),
- [B(NI_LogicLow)] = I(31),
- },
- [B(NI_AO_PauseTrigger)] = {
- /* These are not currently implemented in ni modules */
- [B(NI_PFI(0))] = U(1),
- [B(NI_PFI(1))] = U(2),
- [B(NI_PFI(2))] = U(3),
- [B(NI_PFI(3))] = U(4),
- [B(NI_PFI(4))] = U(5),
- [B(NI_PFI(5))] = U(6),
- [B(NI_PFI(6))] = U(7),
- [B(NI_PFI(7))] = U(8),
- [B(NI_PFI(8))] = U(9),
- [B(NI_PFI(9))] = U(10),
- [B(NI_PFI(10))] = U(21),
- [B(NI_PFI(11))] = U(22),
- [B(NI_PFI(12))] = U(23),
- [B(NI_PFI(13))] = U(24),
- [B(NI_PFI(14))] = U(25),
- [B(NI_PFI(15))] = U(26),
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(PXI_Star)] = U(20),
- [B(NI_AnalogComparisonEvent)] = U(30),
- [B(NI_LogicLow)] = U(31),
- },
- [B(NI_DI_SampleClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrInternalOutput(0))] = I(28),
- [B(NI_CtrInternalOutput(1))] = I(29),
- [B(PXI_Star)] = I(20),
- [B(NI_AI_SampleClock)] = I(18),
- [B(NI_AI_ConvertClock)] = I(19),
- [B(NI_AO_SampleClock)] = I(31),
- [B(NI_FrequencyOutput)] = I(32),
- [B(NI_ChangeDetectionEvent)] = I(33),
- [B(NI_CaseGround)] = I(0),
- },
- [B(NI_DO_SampleClock)] = {
- [B(NI_PFI(0))] = I(1),
- [B(NI_PFI(1))] = I(2),
- [B(NI_PFI(2))] = I(3),
- [B(NI_PFI(3))] = I(4),
- [B(NI_PFI(4))] = I(5),
- [B(NI_PFI(5))] = I(6),
- [B(NI_PFI(6))] = I(7),
- [B(NI_PFI(7))] = I(8),
- [B(NI_PFI(8))] = I(9),
- [B(NI_PFI(9))] = I(10),
- [B(NI_PFI(10))] = I(21),
- [B(NI_PFI(11))] = I(22),
- [B(NI_PFI(12))] = I(23),
- [B(NI_PFI(13))] = I(24),
- [B(NI_PFI(14))] = I(25),
- [B(NI_PFI(15))] = I(26),
- [B(TRIGGER_LINE(0))] = I(11),
- [B(TRIGGER_LINE(1))] = I(12),
- [B(TRIGGER_LINE(2))] = I(13),
- [B(TRIGGER_LINE(3))] = I(14),
- [B(TRIGGER_LINE(4))] = I(15),
- [B(TRIGGER_LINE(5))] = I(16),
- [B(TRIGGER_LINE(6))] = I(17),
- [B(TRIGGER_LINE(7))] = I(27),
- [B(NI_CtrInternalOutput(0))] = I(28),
- [B(NI_CtrInternalOutput(1))] = I(29),
- [B(PXI_Star)] = I(20),
- [B(NI_AI_SampleClock)] = I(18),
- [B(NI_AI_ConvertClock)] = I(19),
- [B(NI_AO_SampleClock)] = I(31),
- [B(NI_FrequencyOutput)] = I(32),
- [B(NI_ChangeDetectionEvent)] = I(33),
- [B(NI_CaseGround)] = I(0),
- },
- [B(NI_MasterTimebase)] = {
- /* These are not currently implemented in ni modules */
- [B(TRIGGER_LINE(0))] = U(11),
- [B(TRIGGER_LINE(1))] = U(12),
- [B(TRIGGER_LINE(2))] = U(13),
- [B(TRIGGER_LINE(3))] = U(14),
- [B(TRIGGER_LINE(4))] = U(15),
- [B(TRIGGER_LINE(5))] = U(16),
- [B(TRIGGER_LINE(6))] = U(17),
- [B(TRIGGER_LINE(7))] = U(27),
- [B(PXI_Star)] = U(20),
- [B(PXI_Clk10)] = U(29),
- [B(NI_10MHzRefClock)] = U(0),
- },
- /*
- * This symbol is not defined and nothing for this is
- * implemented--just including this because data was found in
- * the NI-STC for it--can't remember where.
- * [B(NI_FrequencyOutTimebase)] = {
- * ** These are not currently implemented in ni modules **
- * [B(NI_20MHzTimebase)] = U(0),
- * [B(NI_100kHzTimebase)] = U(1),
- * },
- */
- [B(NI_RGOUT0)] = {
- [B(NI_CtrInternalOutput(0))] = I(0),
- [B(NI_CtrOut(0))] = I(1),
- },
- },
-};
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/.gitignore b/drivers/staging/comedi/drivers/ni_routing/tools/.gitignore
deleted file mode 100644
index e3ebffcd900e..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-comedi_h.py
-*.pyc
-ni_values.py
-convert_c_to_py
-c/
-csv/
-all_cfiles.c
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/Makefile b/drivers/staging/comedi/drivers/ni_routing/tools/Makefile
deleted file mode 100644
index 6e92a06a44cb..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/Makefile
+++ /dev/null
@@ -1,80 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# this make file is simply to help autogenerate these files:
-# ni_route_values.h
-# ni_device_routes.h
-# in order to do this, we are also generating a python representation (using
-# ctypesgen) of ../../comedi.h.
-# This allows us to sort NI signal/terminal names numerically to use a binary
-# search through the device_routes tables to find valid routes.
-
-ALL:
- @echo Typical targets:
- @echo "\`make csv-files\`"
- @echo " Creates new csv-files using content of c-files of existing"
- @echo " ni_routing/* content. New csv files are placed in csv"
- @echo " sub-directory."
- @echo "\`make c-files\`"
- @echo " Creates new c-files using content of csv sub-directory. These"
- @echo " new c-files can be compared to the active content in the"
- @echo " ni_routing directory."
- @echo "\`make csv-blank\`"
- @echo " Create a new blank csv file. This is useful for establishing a"
- @echo " new data table for either a device family \(less likely\) or a"
- @echo " specific board of an existing device family \(more likely\)."
- @echo "\`make clean-partial\`"
- @echo " Remove all generated files/directories EXCEPT for csv/c files."
- @echo "\`make clean\`"
- @echo " Remove all generated files/directories."
- @echo "\`make everything\`"
- @echo " Build all csv-files, then all new c-files."
-
-everything : csv-files c-files csv-blank
-
-CPPFLAGS=-D"BIT(x)=(1UL<<(x))" -D__user=
-
-comedi_h.py : ../../../comedi.h
- ctypesgen $< --include "sys/ioctl.h" --cpp 'gcc -E $(CPPFLAGS)' -o $@
-
-convert_c_to_py: all_cfiles.c
- gcc -g convert_c_to_py.c -o convert_c_to_py -std=c99
-
-ni_values.py: convert_c_to_py
- ./convert_c_to_py
-
-csv-files : ni_values.py comedi_h.py
- ./convert_py_to_csv.py
-
-csv-blank :
- ./make_blank_csv.py
- @echo New blank csv signal table in csv/blank_route_table.csv
-
-c-files : comedi_h.py
- ./convert_csv_to_c.py --route_values --device_routes
-
-ROUTE_VALUES_SRC=$(wildcard ../ni_route_values/*.c)
-DEVICE_ROUTES_SRC=$(wildcard ../ni_device_routes/*.c)
-all_cfiles.c : $(DEVICE_ROUTES_SRC) $(ROUTE_VALUES_SRC)
- @for i in $(DEVICE_ROUTES_SRC) $(ROUTE_VALUES_SRC); do \
- echo "#include \"$$i\"" >> all_cfiles.c; \
- done
-
-clean-partial :
- $(RM) -rf comedi_h.py ni_values.py convert_c_to_py all_cfiles.c *.pyc \
- __pycache__/
-
-clean : partial_clean
- $(RM) -rf c/ csv/
-
-# Note: One could also use ctypeslib in order to generate these files. The
-# caveat is that ctypeslib does not do a great job at handling macro functions.
-# The make rules are as follows:
-# comedi.h.xml : ../../comedi.h
-# # note that we have to use PWD here to avoid h2xml finding a system
-# # installed version of the comedilib/comedi.h file
-# h2xml ${PWD}/../../comedi.h -c -D__user="" -D"BIT(x)=(1<<(x))" \
-# -o comedi.h.xml
-#
-# comedi_h.py : comedi.h.xml
-# xml2py ./comedi.h.xml -o comedi_h.py
-# clean :
-# rm -f comedi.h.xml comedi_h.py comedi_h.pyc
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/convert_c_to_py.c b/drivers/staging/comedi/drivers/ni_routing/tools/convert_c_to_py.c
deleted file mode 100644
index dedb6f2fc678..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/convert_c_to_py.c
+++ /dev/null
@@ -1,159 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <errno.h>
-#include <stdlib.h>
-
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef int8_t s8;
-#define __user
-#define BIT(x) (1UL << (x))
-
-#define NI_ROUTE_VALUE_EXTERNAL_CONVERSION 1
-
-#include "../ni_route_values.c"
-#include "../ni_device_routes.c"
-#include "all_cfiles.c"
-
-#include <stdio.h>
-
-#define RVij(rv, src, dest) ((rv)->register_values[(dest)][(src)])
-
-/*
- * write out
- * {
- * "family" : "<family-name>",
- * "register_values": {
- * <destination0>:[src0, src1, ...],
- * <destination0>:[src0, src1, ...],
- * ...
- * }
- * }
- */
-void family_write(const struct family_route_values *rv, FILE *fp)
-{
- fprintf(fp,
- " \"%s\" : {\n"
- " # dest -> {src0:val0, src1:val1, ...}\n"
- , rv->family);
- for (unsigned int dest = NI_NAMES_BASE;
- dest < (NI_NAMES_BASE + NI_NUM_NAMES);
- ++dest) {
- unsigned int src = NI_NAMES_BASE;
-
- for (; src < (NI_NAMES_BASE + NI_NUM_NAMES) &&
- RVij(rv, B(src), B(dest)) == 0; ++src)
- ;
-
- if (src >= (NI_NAMES_BASE + NI_NUM_NAMES))
- continue; /* no data here */
-
- fprintf(fp, " %u : {\n", dest);
- for (src = NI_NAMES_BASE; src < (NI_NAMES_BASE + NI_NUM_NAMES);
- ++src) {
- register_type r = RVij(rv, B(src), B(dest));
- const char *M;
-
- if (r == 0) {
- continue;
- } else if (MARKED_V(r)) {
- M = "V";
- } else if (MARKED_I(r)) {
- M = "I";
- } else if (MARKED_U(r)) {
- M = "U";
- } else {
- fprintf(stderr,
- "Invalid register marking %s[%u][%u] = %u\n",
- rv->family, dest, src, r);
- exit(1);
- }
-
- fprintf(fp, " %u : \"%s(%u)\",\n",
- src, M, UNMARK(r));
- }
- fprintf(fp, " },\n");
- }
- fprintf(fp, " },\n\n");
-}
-
-bool is_valid_ni_sig(unsigned int sig)
-{
- return (sig >= NI_NAMES_BASE) && (sig < (NI_NAMES_BASE + NI_NUM_NAMES));
-}
-
-/*
- * write out
- * {
- * "family" : "<family-name>",
- * "register_values": {
- * <destination0>:[src0, src1, ...],
- * <destination0>:[src0, src1, ...],
- * ...
- * }
- * }
- */
-void device_write(const struct ni_device_routes *dR, FILE *fp)
-{
- fprintf(fp,
- " \"%s\" : {\n"
- " # dest -> [src0, src1, ...]\n"
- , dR->device);
-
- unsigned int i = 0;
-
- while (dR->routes[i].dest != 0) {
- if (!is_valid_ni_sig(dR->routes[i].dest)) {
- fprintf(stderr,
- "Invalid NI signal value [%u] for destination %s.[%u]\n",
- dR->routes[i].dest, dR->device, i);
- exit(1);
- }
-
- fprintf(fp, " %u : [", dR->routes[i].dest);
-
- unsigned int j = 0;
-
- while (dR->routes[i].src[j] != 0) {
- if (!is_valid_ni_sig(dR->routes[i].src[j])) {
- fprintf(stderr,
- "Invalid NI signal value [%u] for source %s.[%u].[%u]\n",
- dR->routes[i].src[j], dR->device, i, j);
- exit(1);
- }
-
- fprintf(fp, "%u,", dR->routes[i].src[j]);
-
- ++j;
- }
- fprintf(fp, "],\n");
-
- ++i;
- }
- fprintf(fp, " },\n\n");
-}
-
-int main(void)
-{
- FILE *fp = fopen("ni_values.py", "w");
-
- /* write route register values */
- fprintf(fp, "ni_route_values = {\n");
- for (int i = 0; ni_all_route_values[i]; ++i)
- family_write(ni_all_route_values[i], fp);
- fprintf(fp, "}\n\n");
-
- /* write valid device routes */
- fprintf(fp, "ni_device_routes = {\n");
- for (int i = 0; ni_device_routes_list[i]; ++i)
- device_write(ni_device_routes_list[i], fp);
- fprintf(fp, "}\n");
-
- /* finish; close file */
- fclose(fp);
- return 0;
-}
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/convert_csv_to_c.py b/drivers/staging/comedi/drivers/ni_routing/tools/convert_csv_to_c.py
deleted file mode 100755
index 532eb6372a5a..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/convert_csv_to_c.py
+++ /dev/null
@@ -1,503 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0+
-# vim: ts=2:sw=2:et:tw=80:nowrap
-
-# This is simply to aide in creating the entries in the order of the value of
-# the device-global NI signal/terminal constants defined in comedi.h
-import comedi_h
-import os, sys, re
-from csv_collection import CSVCollection
-
-
-def c_to_o(filename, prefix='\t\t\t\t\t ni_routing/', suffix=' \\'):
- if not filename.endswith('.c'):
- return ''
- return prefix + filename.rpartition('.c')[0] + '.o' + suffix
-
-
-def routedict_to_structinit_single(name, D, return_name=False):
- Locals = dict()
- lines = [
- '\t.family = "{}",'.format(name),
- '\t.register_values = {',
- '\t\t/*',
- '\t\t * destination = {',
- '\t\t * source = register value,',
- '\t\t * ...',
- '\t\t * }',
- '\t\t */',
- ]
- if (False):
- # print table with index0:src, index1:dest
- D0 = D # (src-> dest->reg_value)
- #D1 : destD
- else:
- D0 = dict()
- for src, destD in D.items():
- for dest, val in destD.items():
- D0.setdefault(dest, {})[src] = val
-
-
- D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
-
- for D0_sig, D1_D in D0:
- D1 = sorted(D1_D.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
-
- lines.append('\t\t[B({})] = {{'.format(D0_sig))
- for D1_sig, value in D1:
- if not re.match('[VIU]\([^)]*\)', value):
- sys.stderr.write('Invalid register format: {}\n'.format(repr(value)))
- sys.stderr.write(
- 'Register values should be formatted with V(),I(),or U()\n')
- raise RuntimeError('Invalid register values format')
- lines.append('\t\t\t[B({})]\t= {},'.format(D1_sig, value))
- lines.append('\t\t},')
- lines.append('\t},')
-
- lines = '\n'.join(lines)
- if return_name:
- return N, lines
- else:
- return lines
-
-
-def routedict_to_routelist_single(name, D, indent=1):
- Locals = dict()
-
- indents = dict(
- I0 = '\t'*(indent),
- I1 = '\t'*(indent+1),
- I2 = '\t'*(indent+2),
- I3 = '\t'*(indent+3),
- I4 = '\t'*(indent+4),
- )
-
- if (False):
- # data is src -> dest-list
- D0 = D
- keyname = 'src'
- valname = 'dest'
- else:
- # data is dest -> src-list
- keyname = 'dest'
- valname = 'src'
- D0 = dict()
- for src, destD in D.items():
- for dest, val in destD.items():
- D0.setdefault(dest, {})[src] = val
-
- # Sort by order of device-global names (numerically)
- D0 = sorted(D0.items(), key=lambda i: eval(i[0], comedi_h.__dict__, Locals))
-
- lines = [ '{I0}.device = "{name}",\n'
- '{I0}.routes = (struct ni_route_set[]){{'
- .format(name=name, **indents) ]
- for D0_sig, D1_D in D0:
- D1 = [ k for k,v in D1_D.items() if v ]
- D1.sort(key=lambda i: eval(i, comedi_h.__dict__, Locals))
-
- lines.append('{I1}{{\n{I2}.{keyname} = {D0_sig},\n'
- '{I2}.{valname} = (int[]){{'
- .format(keyname=keyname, valname=valname, D0_sig=D0_sig, **indents)
- )
- for D1_sig in D1:
- lines.append( '{I3}{D1_sig},'.format(D1_sig=D1_sig, **indents) )
- lines.append( '{I3}0, /* Termination */'.format(**indents) )
-
- lines.append('{I2}}}\n{I1}}},'.format(**indents))
-
- lines.append('{I1}{{ /* Termination of list */\n{I2}.{keyname} = 0,\n{I1}}},'
- .format(keyname=keyname, **indents))
-
- lines.append('{I0}}},'.format(**indents))
-
- return '\n'.join(lines)
-
-
-class DeviceRoutes(CSVCollection):
- MKFILE_SEGMENTS = 'device-route.mk'
- SET_C = 'ni_device_routes.c'
- ITEMS_DIR = 'ni_device_routes'
- EXTERN_H = 'all.h'
- OUTPUT_DIR = 'c'
-
- output_file_top = """\
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/{filename}
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "ni_device_routes.h"
-#include "{extern_h}"\
-""".format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
-
- extern_header = """\
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/{filename}
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
-#define _COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
-
-#include "../ni_device_routes.h"
-
-{externs}
-
-#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_DEVICE_ROUTES_EXTERN_H
-"""
-
- single_output_file_top = """\
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/{filename}
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "../ni_device_routes.h"
-#include "{extern_h}"
-
-struct ni_device_routes {table_name} = {{\
-"""
-
- def __init__(self, pattern='csv/device_routes/*.csv'):
- super(DeviceRoutes,self).__init__(pattern)
-
- def to_listinit(self):
- chunks = [ self.output_file_top,
- '',
- 'struct ni_device_routes *const ni_device_routes_list[] = {'
- ]
- # put the sheets in lexical order of device numbers then bus
- sheets = sorted(self.items(), key=lambda i : tuple(i[0].split('-')[::-1]) )
-
- externs = []
- objs = [c_to_o(self.SET_C)]
-
- for sheet,D in sheets:
- S = sheet.lower()
- dev_table_name = 'ni_{}_device_routes'.format(S.replace('-','_'))
- sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
- externs.append('extern struct ni_device_routes {};'.format(dev_table_name))
-
- chunks.append('\t&{},'.format(dev_table_name))
-
- s_chunks = [
- self.single_output_file_top.format(
- filename = sheet_filename,
- table_name = dev_table_name,
- extern_h = self.EXTERN_H,
- ),
- routedict_to_routelist_single(S, D),
- '};',
- ]
-
- objs.append(c_to_o(sheet_filename))
-
- with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
- f.write('\n'.join(s_chunks))
- f.write('\n')
-
- with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
- f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
- f.write('ni_routing-objs\t\t\t\t+= \\\n')
- f.write('\n'.join(objs))
- f.write('\n')
-
- EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
- with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
- f.write(self.extern_header.format(
- filename=EXTERN_H, externs='\n'.join(externs)))
-
- chunks.append('\tNULL,') # terminate list
- chunks.append('};')
- return '\n'.join(chunks)
-
- def save(self):
- filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
-
- try:
- os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
- except:
- pass
- with open(filename,'w') as f:
- f.write( self.to_listinit() )
- f.write( '\n' )
-
-
-class RouteValues(CSVCollection):
- MKFILE_SEGMENTS = 'route-values.mk'
- SET_C = 'ni_route_values.c'
- ITEMS_DIR = 'ni_route_values'
- EXTERN_H = 'all.h'
- OUTPUT_DIR = 'c'
-
- output_file_top = """\
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/{filename}
- * Route information for NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * This file includes the tables that are a list of all the values of various
- * signals routes available on NI hardware. In many cases, one does not
- * explicitly make these routes, rather one might indicate that something is
- * used as the source of one particular trigger or another (using
- * *_src=TRIG_EXT).
- *
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#include "ni_route_values.h"
-#include "{extern_h}"\
-""".format(filename=SET_C, extern_h=os.path.join(ITEMS_DIR, EXTERN_H))
-
- extern_header = """\
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/{filename}
- * List of valid routes for specific NI boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * The contents of this file are generated using the tools in
- * comedi/drivers/ni_routing/tools
- *
- * Please use those tools to help maintain the contents of this file.
- */
-
-#ifndef _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
-#define _COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
-
-#include "../ni_route_values.h"
-
-{externs}
-
-#endif //_COMEDI_DRIVERS_NI_ROUTING_NI_ROUTE_VALUES_EXTERN_H
-"""
-
- single_output_file_top = """\
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/ni_routing/{filename}
- * Route information for {sheet} boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-/*
- * This file includes a list of all the values of various signals routes
- * available on NI 660x hardware. In many cases, one does not explicitly make
- * these routes, rather one might indicate that something is used as the source
- * of one particular trigger or another (using *_src=TRIG_EXT).
- *
- * The contents of this file can be generated using the tools in
- * comedi/drivers/ni_routing/tools. This file also contains specific notes to
- * this family of devices.
- *
- * Please use those tools to help maintain the contents of this file, but be
- * mindful to not lose the notes already made in this file, since these notes
- * are critical to a complete undertsanding of the register values of this
- * family.
- */
-
-#include "../ni_route_values.h"
-#include "{extern_h}"
-
-const struct family_route_values {table_name} = {{\
-"""
-
- def __init__(self, pattern='csv/route_values/*.csv'):
- super(RouteValues,self).__init__(pattern)
-
- def to_structinit(self):
- chunks = [ self.output_file_top,
- '',
- 'const struct family_route_values *const ni_all_route_values[] = {'
- ]
- # put the sheets in lexical order for consistency
- sheets = sorted(self.items(), key=lambda i : i[0] )
-
- externs = []
- objs = [c_to_o(self.SET_C)]
-
- for sheet,D in sheets:
- S = sheet.lower()
- fam_table_name = '{}_route_values'.format(S.replace('-','_'))
- sheet_filename = os.path.join(self.ITEMS_DIR,'{}.c'.format(S))
- externs.append('extern const struct family_route_values {};'.format(fam_table_name))
-
- chunks.append('\t&{},'.format(fam_table_name))
-
- s_chunks = [
- self.single_output_file_top.format(
- filename = sheet_filename,
- sheet = sheet.upper(),
- table_name = fam_table_name,
- extern_h = self.EXTERN_H,
- ),
- routedict_to_structinit_single(S, D),
- '};',
- ]
-
- objs.append(c_to_o(sheet_filename))
-
- with open(os.path.join(self.OUTPUT_DIR, sheet_filename), 'w') as f:
- f.write('\n'.join(s_chunks))
- f.write( '\n' )
-
- with open(os.path.join(self.OUTPUT_DIR, self.MKFILE_SEGMENTS), 'w') as f:
- f.write('# This is the segment that should be included in comedi/drivers/Makefile\n')
- f.write('ni_routing-objs\t\t\t\t+= \\\n')
- f.write('\n'.join(objs))
- f.write('\n')
-
- EXTERN_H = os.path.join(self.ITEMS_DIR, self.EXTERN_H)
- with open(os.path.join(self.OUTPUT_DIR, EXTERN_H), 'w') as f:
- f.write(self.extern_header.format(
- filename=EXTERN_H, externs='\n'.join(externs)))
-
- chunks.append('\tNULL,') # terminate list
- chunks.append('};')
- return '\n'.join(chunks)
-
- def save(self):
- filename=os.path.join(self.OUTPUT_DIR, self.SET_C)
-
- try:
- os.makedirs(os.path.join(self.OUTPUT_DIR, self.ITEMS_DIR))
- except:
- pass
- with open(filename,'w') as f:
- f.write( self.to_structinit() )
- f.write( '\n' )
-
-
-
-if __name__ == '__main__':
- import argparse
- parser = argparse.ArgumentParser()
- parser.add_argument( '--route_values', action='store_true',
- help='Extract route values from csv/route_values/*.csv' )
- parser.add_argument( '--device_routes', action='store_true',
- help='Extract route values from csv/device_routes/*.csv' )
- args = parser.parse_args()
- KL = list()
- if args.route_values:
- KL.append( RouteValues )
- if args.device_routes:
- KL.append( DeviceRoutes )
- if not KL:
- parser.error('nothing to do...')
- for K in KL:
- doc = K()
- doc.save()
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/convert_py_to_csv.py b/drivers/staging/comedi/drivers/ni_routing/tools/convert_py_to_csv.py
deleted file mode 100755
index b3e6472bac22..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/convert_py_to_csv.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0+
-# vim: ts=2:sw=2:et:tw=80:nowrap
-
-from os import path
-import os, csv
-from itertools import chain
-
-from csv_collection import CSVCollection
-from ni_names import value_to_name
-import ni_values
-
-CSV_DIR = 'csv'
-
-def iter_src_values(D):
- return D.items()
-
-def iter_src(D):
- for dest in D:
- yield dest, 1
-
-def create_csv(name, D, src_iter):
- # have to change dest->{src:val} to src->{dest:val}
- fieldnames = [value_to_name[i] for i in sorted(D.keys())]
- fieldnames.insert(0, CSVCollection.source_column_name)
-
- S = dict()
- for dest, srcD in D.items():
- for src,val in src_iter(srcD):
- S.setdefault(src,{})[dest] = val
-
- S = sorted(S.items(), key = lambda src_destD : src_destD[0])
-
-
- csv_fname = path.join(CSV_DIR, name + '.csv')
- with open(csv_fname, 'w') as F_csv:
- dR = csv.DictWriter(F_csv, fieldnames, delimiter=';', quotechar='"')
- dR.writeheader()
-
- # now change the json back into the csv dictionaries
- rows = [
- dict(chain(
- ((CSVCollection.source_column_name,value_to_name[src]),),
- *(((value_to_name[dest],v),) for dest,v in destD.items())
- ))
- for src, destD in S
- ]
-
- dR.writerows(rows)
-
-
-def to_csv():
- for d in ['route_values', 'device_routes']:
- try:
- os.makedirs(path.join(CSV_DIR,d))
- except:
- pass
-
- for family, dst_src_map in ni_values.ni_route_values.items():
- create_csv(path.join('route_values',family), dst_src_map, iter_src_values)
-
- for device, dst_src_map in ni_values.ni_device_routes.items():
- create_csv(path.join('device_routes',device), dst_src_map, iter_src)
-
-
-if __name__ == '__main__':
- to_csv()
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/csv_collection.py b/drivers/staging/comedi/drivers/ni_routing/tools/csv_collection.py
deleted file mode 100644
index 12617329a928..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/csv_collection.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-# vim: ts=2:sw=2:et:tw=80:nowrap
-
-import os, csv, glob
-
-class CSVCollection(dict):
- delimiter=';'
- quotechar='"'
- source_column_name = 'Sources / Destinations'
-
- """
- This class is a dictionary representation of the collection of sheets that
- exist in a given .ODS file.
- """
- def __init__(self, pattern, skip_commented_lines=True, strip_lines=True):
- super(CSVCollection, self).__init__()
- self.pattern = pattern
- C = '#' if skip_commented_lines else 'blahblahblah'
-
- if strip_lines:
- strip = lambda s:s.strip()
- else:
- strip = lambda s:s
-
- # load all CSV files
- key = self.source_column_name
- for fname in glob.glob(pattern):
- with open(fname) as F:
- dR = csv.DictReader(F, delimiter=self.delimiter,
- quotechar=self.quotechar)
- name = os.path.basename(fname).partition('.')[0]
- D = {
- r[key]:{f:strip(c) for f,c in r.items()
- if f != key and f[:1] not in ['', C] and
- strip(c)[:1] not in ['', C]}
- for r in dR if r[key][:1] not in ['', C]
- }
- # now, go back through and eliminate all empty dictionaries
- D = {k:v for k,v in D.items() if v}
- self[name] = D
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/make_blank_csv.py b/drivers/staging/comedi/drivers/ni_routing/tools/make_blank_csv.py
deleted file mode 100755
index 89c90a0ba24d..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/make_blank_csv.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: GPL-2.0+
-# vim: ts=2:sw=2:et:tw=80:nowrap
-
-from os import path
-import os, csv
-
-from csv_collection import CSVCollection
-from ni_names import value_to_name
-
-CSV_DIR = 'csv'
-
-def to_csv():
- try:
- os.makedirs(CSV_DIR)
- except:
- pass
-
- csv_fname = path.join(CSV_DIR, 'blank_route_table.csv')
-
- fieldnames = [sig for sig_val, sig in sorted(value_to_name.items())]
- fieldnames.insert(0, CSVCollection.source_column_name)
-
- with open(csv_fname, 'w') as F_csv:
- dR = csv.DictWriter(F_csv, fieldnames, delimiter=';', quotechar='"')
- dR.writeheader()
-
- for sig in fieldnames[1:]:
- dR.writerow({CSVCollection.source_column_name: sig})
-
-if __name__ == '__main__':
- to_csv()
diff --git a/drivers/staging/comedi/drivers/ni_routing/tools/ni_names.py b/drivers/staging/comedi/drivers/ni_routing/tools/ni_names.py
deleted file mode 100644
index 5f9b825968b1..000000000000
--- a/drivers/staging/comedi/drivers/ni_routing/tools/ni_names.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-# vim: ts=2:sw=2:et:tw=80:nowrap
-"""
-This file helps to extract string names of NI signals as included in comedi.h
-between NI_NAMES_BASE and NI_NAMES_BASE+NI_NUM_NAMES.
-"""
-
-# This is simply to aide in creating the entries in the order of the value of
-# the device-global NI signal/terminal constants defined in comedi.h
-import comedi_h
-
-
-ni_macros = (
- 'NI_PFI',
- 'TRIGGER_LINE',
- 'NI_RTSI_BRD',
- 'NI_CtrSource',
- 'NI_CtrGate',
- 'NI_CtrAux',
- 'NI_CtrA',
- 'NI_CtrB',
- 'NI_CtrZ',
- 'NI_CtrArmStartTrigger',
- 'NI_CtrInternalOutput',
- 'NI_CtrOut',
- 'NI_CtrSampleClock',
-)
-
-def get_ni_names():
- name_dict = dict()
-
- # load all the static names; start with those that do not begin with NI_
- name_dict['PXI_Star'] = comedi_h.PXI_Star
- name_dict['PXI_Clk10'] = comedi_h.PXI_Clk10
-
- #load all macro values
- for fun in ni_macros:
- f = getattr(comedi_h, fun)
- name_dict.update({
- '{}({})'.format(fun,i):f(i) for i in range(1 + f(-1) - f(0))
- })
-
- #load everything else in ni_common_signal_names enum
- name_dict.update({
- k:v for k,v in comedi_h.__dict__.items()
- if k.startswith('NI_') and (not callable(v)) and
- comedi_h.NI_COUNTER_NAMES_MAX < v < (comedi_h.NI_NAMES_BASE + comedi_h.NI_NUM_NAMES)
- })
-
- # now create reverse lookup (value -> name)
-
- val_dict = {v:k for k,v in name_dict.items()}
-
- return name_dict, val_dict
-
-name_to_value, value_to_name = get_ni_names()
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
deleted file mode 100644
index fbc0b753a0f5..000000000000
--- a/drivers/staging/comedi/drivers/ni_stc.h
+++ /dev/null
@@ -1,1142 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Register descriptions for NI DAQ-STC chip
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998-9 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * References:
- * DAQ-STC Technical Reference Manual
- */
-
-#ifndef _COMEDI_NI_STC_H
-#define _COMEDI_NI_STC_H
-
-#include "ni_tio.h"
-#include "ni_routes.h"
-
-/*
- * Registers in the National Instruments DAQ-STC chip
- */
-
-#define NISTC_INTA_ACK_REG 2
-#define NISTC_INTA_ACK_G0_GATE BIT(15)
-#define NISTC_INTA_ACK_G0_TC BIT(14)
-#define NISTC_INTA_ACK_AI_ERR BIT(13)
-#define NISTC_INTA_ACK_AI_STOP BIT(12)
-#define NISTC_INTA_ACK_AI_START BIT(11)
-#define NISTC_INTA_ACK_AI_START2 BIT(10)
-#define NISTC_INTA_ACK_AI_START1 BIT(9)
-#define NISTC_INTA_ACK_AI_SC_TC BIT(8)
-#define NISTC_INTA_ACK_AI_SC_TC_ERR BIT(7)
-#define NISTC_INTA_ACK_G0_TC_ERR BIT(6)
-#define NISTC_INTA_ACK_G0_GATE_ERR BIT(5)
-#define NISTC_INTA_ACK_AI_ALL (NISTC_INTA_ACK_AI_ERR | \
- NISTC_INTA_ACK_AI_STOP | \
- NISTC_INTA_ACK_AI_START | \
- NISTC_INTA_ACK_AI_START2 | \
- NISTC_INTA_ACK_AI_START1 | \
- NISTC_INTA_ACK_AI_SC_TC | \
- NISTC_INTA_ACK_AI_SC_TC_ERR)
-
-#define NISTC_INTB_ACK_REG 3
-#define NISTC_INTB_ACK_G1_GATE BIT(15)
-#define NISTC_INTB_ACK_G1_TC BIT(14)
-#define NISTC_INTB_ACK_AO_ERR BIT(13)
-#define NISTC_INTB_ACK_AO_STOP BIT(12)
-#define NISTC_INTB_ACK_AO_START BIT(11)
-#define NISTC_INTB_ACK_AO_UPDATE BIT(10)
-#define NISTC_INTB_ACK_AO_START1 BIT(9)
-#define NISTC_INTB_ACK_AO_BC_TC BIT(8)
-#define NISTC_INTB_ACK_AO_UC_TC BIT(7)
-#define NISTC_INTB_ACK_AO_UI2_TC BIT(6)
-#define NISTC_INTB_ACK_AO_UI2_TC_ERR BIT(5)
-#define NISTC_INTB_ACK_AO_BC_TC_ERR BIT(4)
-#define NISTC_INTB_ACK_AO_BC_TC_TRIG_ERR BIT(3)
-#define NISTC_INTB_ACK_G1_TC_ERR BIT(2)
-#define NISTC_INTB_ACK_G1_GATE_ERR BIT(1)
-#define NISTC_INTB_ACK_AO_ALL (NISTC_INTB_ACK_AO_ERR | \
- NISTC_INTB_ACK_AO_STOP | \
- NISTC_INTB_ACK_AO_START | \
- NISTC_INTB_ACK_AO_UPDATE | \
- NISTC_INTB_ACK_AO_START1 | \
- NISTC_INTB_ACK_AO_BC_TC | \
- NISTC_INTB_ACK_AO_UC_TC | \
- NISTC_INTB_ACK_AO_BC_TC_ERR | \
- NISTC_INTB_ACK_AO_BC_TC_TRIG_ERR)
-
-#define NISTC_AI_CMD2_REG 4
-#define NISTC_AI_CMD2_END_ON_SC_TC BIT(15)
-#define NISTC_AI_CMD2_END_ON_EOS BIT(14)
-#define NISTC_AI_CMD2_START1_DISABLE BIT(11)
-#define NISTC_AI_CMD2_SC_SAVE_TRACE BIT(10)
-#define NISTC_AI_CMD2_SI_SW_ON_SC_TC BIT(9)
-#define NISTC_AI_CMD2_SI_SW_ON_STOP BIT(8)
-#define NISTC_AI_CMD2_SI_SW_ON_TC BIT(7)
-#define NISTC_AI_CMD2_SC_SW_ON_TC BIT(4)
-#define NISTC_AI_CMD2_STOP_PULSE BIT(3)
-#define NISTC_AI_CMD2_START_PULSE BIT(2)
-#define NISTC_AI_CMD2_START2_PULSE BIT(1)
-#define NISTC_AI_CMD2_START1_PULSE BIT(0)
-
-#define NISTC_AO_CMD2_REG 5
-#define NISTC_AO_CMD2_END_ON_BC_TC(x) (((x) & 0x3) << 14)
-#define NISTC_AO_CMD2_START_STOP_GATE_ENA BIT(13)
-#define NISTC_AO_CMD2_UC_SAVE_TRACE BIT(12)
-#define NISTC_AO_CMD2_BC_GATE_ENA BIT(11)
-#define NISTC_AO_CMD2_BC_SAVE_TRACE BIT(10)
-#define NISTC_AO_CMD2_UI_SW_ON_BC_TC BIT(9)
-#define NISTC_AO_CMD2_UI_SW_ON_STOP BIT(8)
-#define NISTC_AO_CMD2_UI_SW_ON_TC BIT(7)
-#define NISTC_AO_CMD2_UC_SW_ON_BC_TC BIT(6)
-#define NISTC_AO_CMD2_UC_SW_ON_TC BIT(5)
-#define NISTC_AO_CMD2_BC_SW_ON_TC BIT(4)
-#define NISTC_AO_CMD2_MUTE_B BIT(3)
-#define NISTC_AO_CMD2_MUTE_A BIT(2)
-#define NISTC_AO_CMD2_UPDATE2_PULSE BIT(1)
-#define NISTC_AO_CMD2_START1_PULSE BIT(0)
-
-#define NISTC_G0_CMD_REG 6
-#define NISTC_G1_CMD_REG 7
-
-#define NISTC_AI_CMD1_REG 8
-#define NISTC_AI_CMD1_ATRIG_RESET BIT(14)
-#define NISTC_AI_CMD1_DISARM BIT(13)
-#define NISTC_AI_CMD1_SI2_ARM BIT(12)
-#define NISTC_AI_CMD1_SI2_LOAD BIT(11)
-#define NISTC_AI_CMD1_SI_ARM BIT(10)
-#define NISTC_AI_CMD1_SI_LOAD BIT(9)
-#define NISTC_AI_CMD1_DIV_ARM BIT(8)
-#define NISTC_AI_CMD1_DIV_LOAD BIT(7)
-#define NISTC_AI_CMD1_SC_ARM BIT(6)
-#define NISTC_AI_CMD1_SC_LOAD BIT(5)
-#define NISTC_AI_CMD1_SCAN_IN_PROG_PULSE BIT(4)
-#define NISTC_AI_CMD1_EXTMUX_CLK_PULSE BIT(3)
-#define NISTC_AI_CMD1_LOCALMUX_CLK_PULSE BIT(2)
-#define NISTC_AI_CMD1_SC_TC_PULSE BIT(1)
-#define NISTC_AI_CMD1_CONVERT_PULSE BIT(0)
-
-#define NISTC_AO_CMD1_REG 9
-#define NISTC_AO_CMD1_ATRIG_RESET BIT(15)
-#define NISTC_AO_CMD1_START_PULSE BIT(14)
-#define NISTC_AO_CMD1_DISARM BIT(13)
-#define NISTC_AO_CMD1_UI2_ARM_DISARM BIT(12)
-#define NISTC_AO_CMD1_UI2_LOAD BIT(11)
-#define NISTC_AO_CMD1_UI_ARM BIT(10)
-#define NISTC_AO_CMD1_UI_LOAD BIT(9)
-#define NISTC_AO_CMD1_UC_ARM BIT(8)
-#define NISTC_AO_CMD1_UC_LOAD BIT(7)
-#define NISTC_AO_CMD1_BC_ARM BIT(6)
-#define NISTC_AO_CMD1_BC_LOAD BIT(5)
-#define NISTC_AO_CMD1_DAC1_UPDATE_MODE BIT(4)
-#define NISTC_AO_CMD1_LDAC1_SRC_SEL BIT(3)
-#define NISTC_AO_CMD1_DAC0_UPDATE_MODE BIT(2)
-#define NISTC_AO_CMD1_LDAC0_SRC_SEL BIT(1)
-#define NISTC_AO_CMD1_UPDATE_PULSE BIT(0)
-
-#define NISTC_DIO_OUT_REG 10
-#define NISTC_DIO_OUT_SERIAL(x) (((x) & 0xff) << 8)
-#define NISTC_DIO_OUT_SERIAL_MASK NISTC_DIO_OUT_SERIAL(0xff)
-#define NISTC_DIO_OUT_PARALLEL(x) ((x) & 0xff)
-#define NISTC_DIO_OUT_PARALLEL_MASK NISTC_DIO_OUT_PARALLEL(0xff)
-#define NISTC_DIO_SDIN BIT(4)
-#define NISTC_DIO_SDOUT BIT(0)
-
-#define NISTC_DIO_CTRL_REG 11
-#define NISTC_DIO_SDCLK BIT(11)
-#define NISTC_DIO_CTRL_HW_SER_TIMEBASE BIT(10)
-#define NISTC_DIO_CTRL_HW_SER_ENA BIT(9)
-#define NISTC_DIO_CTRL_HW_SER_START BIT(8)
-#define NISTC_DIO_CTRL_DIR(x) ((x) & 0xff)
-#define NISTC_DIO_CTRL_DIR_MASK NISTC_DIO_CTRL_DIR(0xff)
-
-#define NISTC_AI_MODE1_REG 12
-#define NISTC_AI_MODE1_CONVERT_SRC(x) (((x) & 0x1f) << 11)
-#define NISTC_AI_MODE1_SI_SRC(x) (((x) & 0x1f) << 6)
-#define NISTC_AI_MODE1_CONVERT_POLARITY BIT(5)
-#define NISTC_AI_MODE1_SI_POLARITY BIT(4)
-#define NISTC_AI_MODE1_START_STOP BIT(3)
-#define NISTC_AI_MODE1_RSVD BIT(2)
-#define NISTC_AI_MODE1_CONTINUOUS BIT(1)
-#define NISTC_AI_MODE1_TRIGGER_ONCE BIT(0)
-
-#define NISTC_AI_MODE2_REG 13
-#define NISTC_AI_MODE2_SC_GATE_ENA BIT(15)
-#define NISTC_AI_MODE2_START_STOP_GATE_ENA BIT(14)
-#define NISTC_AI_MODE2_PRE_TRIGGER BIT(13)
-#define NISTC_AI_MODE2_EXTMUX_PRESENT BIT(12)
-#define NISTC_AI_MODE2_SI2_INIT_LOAD_SRC BIT(9)
-#define NISTC_AI_MODE2_SI2_RELOAD_MODE BIT(8)
-#define NISTC_AI_MODE2_SI_INIT_LOAD_SRC BIT(7)
-#define NISTC_AI_MODE2_SI_RELOAD_MODE(x) (((x) & 0x7) << 4)
-#define NISTC_AI_MODE2_SI_WR_SWITCH BIT(3)
-#define NISTC_AI_MODE2_SC_INIT_LOAD_SRC BIT(2)
-#define NISTC_AI_MODE2_SC_RELOAD_MODE BIT(1)
-#define NISTC_AI_MODE2_SC_WR_SWITCH BIT(0)
-
-#define NISTC_AI_SI_LOADA_REG 14
-#define NISTC_AI_SI_LOADB_REG 16
-#define NISTC_AI_SC_LOADA_REG 18
-#define NISTC_AI_SC_LOADB_REG 20
-#define NISTC_AI_SI2_LOADA_REG 23
-#define NISTC_AI_SI2_LOADB_REG 25
-
-#define NISTC_G0_MODE_REG 26
-#define NISTC_G1_MODE_REG 27
-#define NISTC_G0_LOADA_REG 28
-#define NISTC_G0_LOADB_REG 30
-#define NISTC_G1_LOADA_REG 32
-#define NISTC_G1_LOADB_REG 34
-#define NISTC_G0_INPUT_SEL_REG 36
-#define NISTC_G1_INPUT_SEL_REG 37
-
-#define NISTC_AO_MODE1_REG 38
-#define NISTC_AO_MODE1_UPDATE_SRC(x) (((x) & 0x1f) << 11)
-#define NISTC_AO_MODE1_UPDATE_SRC_MASK NISTC_AO_MODE1_UPDATE_SRC(0x1f)
-#define NISTC_AO_MODE1_UI_SRC(x) (((x) & 0x1f) << 6)
-#define NISTC_AO_MODE1_UI_SRC_MASK NISTC_AO_MODE1_UI_SRC(0x1f)
-#define NISTC_AO_MODE1_MULTI_CHAN BIT(5)
-#define NISTC_AO_MODE1_UPDATE_SRC_POLARITY BIT(4)
-#define NISTC_AO_MODE1_UI_SRC_POLARITY BIT(3)
-#define NISTC_AO_MODE1_UC_SW_EVERY_TC BIT(2)
-#define NISTC_AO_MODE1_CONTINUOUS BIT(1)
-#define NISTC_AO_MODE1_TRIGGER_ONCE BIT(0)
-
-#define NISTC_AO_MODE2_REG 39
-#define NISTC_AO_MODE2_FIFO_MODE(x) (((x) & 0x3) << 14)
-#define NISTC_AO_MODE2_FIFO_MODE_MASK NISTC_AO_MODE2_FIFO_MODE(3)
-#define NISTC_AO_MODE2_FIFO_MODE_E NISTC_AO_MODE2_FIFO_MODE(0)
-#define NISTC_AO_MODE2_FIFO_MODE_HF NISTC_AO_MODE2_FIFO_MODE(1)
-#define NISTC_AO_MODE2_FIFO_MODE_F NISTC_AO_MODE2_FIFO_MODE(2)
-#define NISTC_AO_MODE2_FIFO_MODE_HF_F NISTC_AO_MODE2_FIFO_MODE(3)
-#define NISTC_AO_MODE2_FIFO_REXMIT_ENA BIT(13)
-#define NISTC_AO_MODE2_START1_DISABLE BIT(12)
-#define NISTC_AO_MODE2_UC_INIT_LOAD_SRC BIT(11)
-#define NISTC_AO_MODE2_UC_WR_SWITCH BIT(10)
-#define NISTC_AO_MODE2_UI2_INIT_LOAD_SRC BIT(9)
-#define NISTC_AO_MODE2_UI2_RELOAD_MODE BIT(8)
-#define NISTC_AO_MODE2_UI_INIT_LOAD_SRC BIT(7)
-#define NISTC_AO_MODE2_UI_RELOAD_MODE(x) (((x) & 0x7) << 4)
-#define NISTC_AO_MODE2_UI_WR_SWITCH BIT(3)
-#define NISTC_AO_MODE2_BC_INIT_LOAD_SRC BIT(2)
-#define NISTC_AO_MODE2_BC_RELOAD_MODE BIT(1)
-#define NISTC_AO_MODE2_BC_WR_SWITCH BIT(0)
-
-#define NISTC_AO_UI_LOADA_REG 40
-#define NISTC_AO_UI_LOADB_REG 42
-#define NISTC_AO_BC_LOADA_REG 44
-#define NISTC_AO_BC_LOADB_REG 46
-#define NISTC_AO_UC_LOADA_REG 48
-#define NISTC_AO_UC_LOADB_REG 50
-
-#define NISTC_CLK_FOUT_REG 56
-#define NISTC_CLK_FOUT_ENA BIT(15)
-#define NISTC_CLK_FOUT_TIMEBASE_SEL BIT(14)
-#define NISTC_CLK_FOUT_DIO_SER_OUT_DIV2 BIT(13)
-#define NISTC_CLK_FOUT_SLOW_DIV2 BIT(12)
-#define NISTC_CLK_FOUT_SLOW_TIMEBASE BIT(11)
-#define NISTC_CLK_FOUT_G_SRC_DIV2 BIT(10)
-#define NISTC_CLK_FOUT_TO_BOARD_DIV2 BIT(9)
-#define NISTC_CLK_FOUT_TO_BOARD BIT(8)
-#define NISTC_CLK_FOUT_AI_OUT_DIV2 BIT(7)
-#define NISTC_CLK_FOUT_AI_SRC_DIV2 BIT(6)
-#define NISTC_CLK_FOUT_AO_OUT_DIV2 BIT(5)
-#define NISTC_CLK_FOUT_AO_SRC_DIV2 BIT(4)
-#define NISTC_CLK_FOUT_DIVIDER(x) (((x) & 0xf) << 0)
-#define NISTC_CLK_FOUT_TO_DIVIDER(x) (((x) >> 0) & 0xf)
-#define NISTC_CLK_FOUT_DIVIDER_MASK NISTC_CLK_FOUT_DIVIDER(0xf)
-
-#define NISTC_IO_BIDIR_PIN_REG 57
-
-#define NISTC_RTSI_TRIG_DIR_REG 58
-#define NISTC_RTSI_TRIG_OLD_CLK_CHAN 7
-#define NISTC_RTSI_TRIG_NUM_CHAN(_m) ((_m) ? 8 : 7)
-#define NISTC_RTSI_TRIG_DIR(_c, _m) ((_m) ? BIT(8 + (_c)) : BIT(7 + (_c)))
-#define NISTC_RTSI_TRIG_DIR_SUB_SEL1 BIT(2) /* only for M-Series */
-#define NISTC_RTSI_TRIG_DIR_SUB_SEL1_SHIFT 2 /* only for M-Series */
-#define NISTC_RTSI_TRIG_USE_CLK BIT(1)
-#define NISTC_RTSI_TRIG_DRV_CLK BIT(0)
-
-#define NISTC_INT_CTRL_REG 59
-#define NISTC_INT_CTRL_INTB_ENA BIT(15)
-#define NISTC_INT_CTRL_INTB_SEL(x) (((x) & 0x7) << 12)
-#define NISTC_INT_CTRL_INTA_ENA BIT(11)
-#define NISTC_INT_CTRL_INTA_SEL(x) (((x) & 0x7) << 8)
-#define NISTC_INT_CTRL_PASSTHRU0_POL BIT(3)
-#define NISTC_INT_CTRL_PASSTHRU1_POL BIT(2)
-#define NISTC_INT_CTRL_3PIN_INT BIT(1)
-#define NISTC_INT_CTRL_INT_POL BIT(0)
-
-#define NISTC_AI_OUT_CTRL_REG 60
-#define NISTC_AI_OUT_CTRL_START_SEL BIT(10)
-#define NISTC_AI_OUT_CTRL_SCAN_IN_PROG_SEL(x) (((x) & 0x3) << 8)
-#define NISTC_AI_OUT_CTRL_EXTMUX_CLK_SEL(x) (((x) & 0x3) << 6)
-#define NISTC_AI_OUT_CTRL_LOCALMUX_CLK_SEL(x) (((x) & 0x3) << 4)
-#define NISTC_AI_OUT_CTRL_SC_TC_SEL(x) (((x) & 0x3) << 2)
-#define NISTC_AI_OUT_CTRL_CONVERT_SEL(x) (((x) & 0x3) << 0)
-#define NISTC_AI_OUT_CTRL_CONVERT_HIGH_Z NISTC_AI_OUT_CTRL_CONVERT_SEL(0)
-#define NISTC_AI_OUT_CTRL_CONVERT_GND NISTC_AI_OUT_CTRL_CONVERT_SEL(1)
-#define NISTC_AI_OUT_CTRL_CONVERT_LOW NISTC_AI_OUT_CTRL_CONVERT_SEL(2)
-#define NISTC_AI_OUT_CTRL_CONVERT_HIGH NISTC_AI_OUT_CTRL_CONVERT_SEL(3)
-
-#define NISTC_ATRIG_ETC_REG 61
-#define NISTC_ATRIG_ETC_GPFO_1_ENA BIT(15)
-#define NISTC_ATRIG_ETC_GPFO_0_ENA BIT(14)
-#define NISTC_ATRIG_ETC_GPFO_0_SEL(x) (((x) & 0x7) << 11)
-#define NISTC_ATRIG_ETC_GPFO_0_SEL_TO_SRC(x) (((x) >> 11) & 0x7)
-#define NISTC_ATRIG_ETC_GPFO_1_SEL BIT(7)
-#define NISTC_ATRIG_ETC_GPFO_1_SEL_TO_SRC(x) (((x) >> 7) & 0x1)
-#define NISTC_ATRIG_ETC_DRV BIT(4)
-#define NISTC_ATRIG_ETC_ENA BIT(3)
-#define NISTC_ATRIG_ETC_MODE(x) (((x) & 0x7) << 0)
-#define NISTC_GPFO_0_G_OUT 0 /* input to GPFO_0_SEL for Ctr0Out */
-#define NISTC_GPFO_1_G_OUT 0 /* input to GPFO_1_SEL for Ctr1Out */
-
-#define NISTC_AI_START_STOP_REG 62
-#define NISTC_AI_START_POLARITY BIT(15)
-#define NISTC_AI_STOP_POLARITY BIT(14)
-#define NISTC_AI_STOP_SYNC BIT(13)
-#define NISTC_AI_STOP_EDGE BIT(12)
-#define NISTC_AI_STOP_SEL(x) (((x) & 0x1f) << 7)
-#define NISTC_AI_START_SYNC BIT(6)
-#define NISTC_AI_START_EDGE BIT(5)
-#define NISTC_AI_START_SEL(x) (((x) & 0x1f) << 0)
-
-#define NISTC_AI_TRIG_SEL_REG 63
-#define NISTC_AI_TRIG_START1_POLARITY BIT(15)
-#define NISTC_AI_TRIG_START2_POLARITY BIT(14)
-#define NISTC_AI_TRIG_START2_SYNC BIT(13)
-#define NISTC_AI_TRIG_START2_EDGE BIT(12)
-#define NISTC_AI_TRIG_START2_SEL(x) (((x) & 0x1f) << 7)
-#define NISTC_AI_TRIG_START1_SYNC BIT(6)
-#define NISTC_AI_TRIG_START1_EDGE BIT(5)
-#define NISTC_AI_TRIG_START1_SEL(x) (((x) & 0x1f) << 0)
-
-#define NISTC_AI_DIV_LOADA_REG 64
-
-#define NISTC_AO_START_SEL_REG 66
-#define NISTC_AO_START_UI2_SW_GATE BIT(15)
-#define NISTC_AO_START_UI2_EXT_GATE_POL BIT(14)
-#define NISTC_AO_START_POLARITY BIT(13)
-#define NISTC_AO_START_AOFREQ_ENA BIT(12)
-#define NISTC_AO_START_UI2_EXT_GATE_SEL(x) (((x) & 0x1f) << 7)
-#define NISTC_AO_START_SYNC BIT(6)
-#define NISTC_AO_START_EDGE BIT(5)
-#define NISTC_AO_START_SEL(x) (((x) & 0x1f) << 0)
-
-#define NISTC_AO_TRIG_SEL_REG 67
-#define NISTC_AO_TRIG_UI2_EXT_GATE_ENA BIT(15)
-#define NISTC_AO_TRIG_DELAYED_START1 BIT(14)
-#define NISTC_AO_TRIG_START1_POLARITY BIT(13)
-#define NISTC_AO_TRIG_UI2_SRC_POLARITY BIT(12)
-#define NISTC_AO_TRIG_UI2_SRC_SEL(x) (((x) & 0x1f) << 7)
-#define NISTC_AO_TRIG_START1_SYNC BIT(6)
-#define NISTC_AO_TRIG_START1_EDGE BIT(5)
-#define NISTC_AO_TRIG_START1_SEL(x) (((x) & 0x1f) << 0)
-#define NISTC_AO_TRIG_START1_SEL_MASK NISTC_AO_TRIG_START1_SEL(0x1f)
-
-#define NISTC_G0_AUTOINC_REG 68
-#define NISTC_G1_AUTOINC_REG 69
-
-#define NISTC_AO_MODE3_REG 70
-#define NISTC_AO_MODE3_UI2_SW_NEXT_TC BIT(13)
-#define NISTC_AO_MODE3_UC_SW_EVERY_BC_TC BIT(12)
-#define NISTC_AO_MODE3_TRIG_LEN BIT(11)
-#define NISTC_AO_MODE3_STOP_ON_OVERRUN_ERR BIT(5)
-#define NISTC_AO_MODE3_STOP_ON_BC_TC_TRIG_ERR BIT(4)
-#define NISTC_AO_MODE3_STOP_ON_BC_TC_ERR BIT(3)
-#define NISTC_AO_MODE3_NOT_AN_UPDATE BIT(2)
-#define NISTC_AO_MODE3_SW_GATE BIT(1)
-#define NISTC_AO_MODE3_LAST_GATE_DISABLE BIT(0) /* M-Series only */
-
-#define NISTC_RESET_REG 72
-#define NISTC_RESET_SOFTWARE BIT(11)
-#define NISTC_RESET_AO_CFG_END BIT(9)
-#define NISTC_RESET_AI_CFG_END BIT(8)
-#define NISTC_RESET_AO_CFG_START BIT(5)
-#define NISTC_RESET_AI_CFG_START BIT(4)
-#define NISTC_RESET_G1 BIT(3)
-#define NISTC_RESET_G0 BIT(2)
-#define NISTC_RESET_AO BIT(1)
-#define NISTC_RESET_AI BIT(0)
-
-#define NISTC_INTA_ENA_REG 73
-#define NISTC_INTA2_ENA_REG 74
-#define NISTC_INTA_ENA_PASSTHRU0 BIT(9)
-#define NISTC_INTA_ENA_G0_GATE BIT(8)
-#define NISTC_INTA_ENA_AI_FIFO BIT(7)
-#define NISTC_INTA_ENA_G0_TC BIT(6)
-#define NISTC_INTA_ENA_AI_ERR BIT(5)
-#define NISTC_INTA_ENA_AI_STOP BIT(4)
-#define NISTC_INTA_ENA_AI_START BIT(3)
-#define NISTC_INTA_ENA_AI_START2 BIT(2)
-#define NISTC_INTA_ENA_AI_START1 BIT(1)
-#define NISTC_INTA_ENA_AI_SC_TC BIT(0)
-#define NISTC_INTA_ENA_AI_MASK (NISTC_INTA_ENA_AI_FIFO | \
- NISTC_INTA_ENA_AI_ERR | \
- NISTC_INTA_ENA_AI_STOP | \
- NISTC_INTA_ENA_AI_START | \
- NISTC_INTA_ENA_AI_START2 | \
- NISTC_INTA_ENA_AI_START1 | \
- NISTC_INTA_ENA_AI_SC_TC)
-
-#define NISTC_INTB_ENA_REG 75
-#define NISTC_INTB2_ENA_REG 76
-#define NISTC_INTB_ENA_PASSTHRU1 BIT(11)
-#define NISTC_INTB_ENA_G1_GATE BIT(10)
-#define NISTC_INTB_ENA_G1_TC BIT(9)
-#define NISTC_INTB_ENA_AO_FIFO BIT(8)
-#define NISTC_INTB_ENA_AO_UI2_TC BIT(7)
-#define NISTC_INTB_ENA_AO_UC_TC BIT(6)
-#define NISTC_INTB_ENA_AO_ERR BIT(5)
-#define NISTC_INTB_ENA_AO_STOP BIT(4)
-#define NISTC_INTB_ENA_AO_START BIT(3)
-#define NISTC_INTB_ENA_AO_UPDATE BIT(2)
-#define NISTC_INTB_ENA_AO_START1 BIT(1)
-#define NISTC_INTB_ENA_AO_BC_TC BIT(0)
-
-#define NISTC_AI_PERSONAL_REG 77
-#define NISTC_AI_PERSONAL_SHIFTIN_PW BIT(15)
-#define NISTC_AI_PERSONAL_EOC_POLARITY BIT(14)
-#define NISTC_AI_PERSONAL_SOC_POLARITY BIT(13)
-#define NISTC_AI_PERSONAL_SHIFTIN_POL BIT(12)
-#define NISTC_AI_PERSONAL_CONVERT_TIMEBASE BIT(11)
-#define NISTC_AI_PERSONAL_CONVERT_PW BIT(10)
-#define NISTC_AI_PERSONAL_CONVERT_ORIG_PULSE BIT(9)
-#define NISTC_AI_PERSONAL_FIFO_FLAGS_POL BIT(8)
-#define NISTC_AI_PERSONAL_OVERRUN_MODE BIT(7)
-#define NISTC_AI_PERSONAL_EXTMUX_CLK_PW BIT(6)
-#define NISTC_AI_PERSONAL_LOCALMUX_CLK_PW BIT(5)
-#define NISTC_AI_PERSONAL_AIFREQ_POL BIT(4)
-
-#define NISTC_AO_PERSONAL_REG 78
-#define NISTC_AO_PERSONAL_MULTI_DACS BIT(15) /* M-Series only */
-#define NISTC_AO_PERSONAL_NUM_DAC BIT(14) /* 1:single; 0:dual */
-#define NISTC_AO_PERSONAL_FAST_CPU BIT(13) /* M-Series reserved */
-#define NISTC_AO_PERSONAL_TMRDACWR_PW BIT(12)
-#define NISTC_AO_PERSONAL_FIFO_FLAGS_POL BIT(11) /* M-Series reserved */
-#define NISTC_AO_PERSONAL_FIFO_ENA BIT(10)
-#define NISTC_AO_PERSONAL_AOFREQ_POL BIT(9) /* M-Series reserved */
-#define NISTC_AO_PERSONAL_DMA_PIO_CTRL BIT(8) /* M-Series reserved */
-#define NISTC_AO_PERSONAL_UPDATE_ORIG_PULSE BIT(7)
-#define NISTC_AO_PERSONAL_UPDATE_TIMEBASE BIT(6)
-#define NISTC_AO_PERSONAL_UPDATE_PW BIT(5)
-#define NISTC_AO_PERSONAL_BC_SRC_SEL BIT(4)
-#define NISTC_AO_PERSONAL_INTERVAL_BUFFER_MODE BIT(3)
-
-#define NISTC_RTSI_TRIGA_OUT_REG 79
-#define NISTC_RTSI_TRIGB_OUT_REG 80
-#define NISTC_RTSI_TRIGB_SUB_SEL1 BIT(15) /* not for M-Series */
-#define NISTC_RTSI_TRIGB_SUB_SEL1_SHIFT 15 /* not for M-Series */
-#define NISTC_RTSI_TRIG(_c, _s) (((_s) & 0xf) << (((_c) % 4) * 4))
-#define NISTC_RTSI_TRIG_MASK(_c) NISTC_RTSI_TRIG((_c), 0xf)
-#define NISTC_RTSI_TRIG_TO_SRC(_c, _b) (((_b) >> (((_c) % 4) * 4)) & 0xf)
-
-#define NISTC_RTSI_BOARD_REG 81
-
-#define NISTC_CFG_MEM_CLR_REG 82
-#define NISTC_ADC_FIFO_CLR_REG 83
-#define NISTC_DAC_FIFO_CLR_REG 84
-#define NISTC_WR_STROBE3_REG 85
-
-#define NISTC_AO_OUT_CTRL_REG 86
-#define NISTC_AO_OUT_CTRL_EXT_GATE_ENA BIT(15)
-#define NISTC_AO_OUT_CTRL_EXT_GATE_SEL(x) (((x) & 0x1f) << 10)
-#define NISTC_AO_OUT_CTRL_CHANS(x) (((x) & 0xf) << 6)
-#define NISTC_AO_OUT_CTRL_UPDATE2_SEL(x) (((x) & 0x3) << 4)
-#define NISTC_AO_OUT_CTRL_EXT_GATE_POL BIT(3)
-#define NISTC_AO_OUT_CTRL_UPDATE2_TOGGLE BIT(2)
-#define NISTC_AO_OUT_CTRL_UPDATE_SEL(x) (((x) & 0x3) << 0)
-#define NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ NISTC_AO_OUT_CTRL_UPDATE_SEL(0)
-#define NISTC_AO_OUT_CTRL_UPDATE_SEL_GND NISTC_AO_OUT_CTRL_UPDATE_SEL(1)
-#define NISTC_AO_OUT_CTRL_UPDATE_SEL_LOW NISTC_AO_OUT_CTRL_UPDATE_SEL(2)
-#define NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGH NISTC_AO_OUT_CTRL_UPDATE_SEL(3)
-
-#define NISTC_AI_MODE3_REG 87
-#define NISTC_AI_MODE3_TRIG_LEN BIT(15)
-#define NISTC_AI_MODE3_DELAY_START BIT(14)
-#define NISTC_AI_MODE3_SOFTWARE_GATE BIT(13)
-#define NISTC_AI_MODE3_SI_TRIG_DELAY BIT(12)
-#define NISTC_AI_MODE3_SI2_SRC_SEL BIT(11)
-#define NISTC_AI_MODE3_DELAYED_START2 BIT(10)
-#define NISTC_AI_MODE3_DELAYED_START1 BIT(9)
-#define NISTC_AI_MODE3_EXT_GATE_MODE BIT(8)
-#define NISTC_AI_MODE3_FIFO_MODE(x) (((x) & 0x3) << 6)
-#define NISTC_AI_MODE3_FIFO_MODE_NE NISTC_AI_MODE3_FIFO_MODE(0)
-#define NISTC_AI_MODE3_FIFO_MODE_HF NISTC_AI_MODE3_FIFO_MODE(1)
-#define NISTC_AI_MODE3_FIFO_MODE_F NISTC_AI_MODE3_FIFO_MODE(2)
-#define NISTC_AI_MODE3_FIFO_MODE_HF_E NISTC_AI_MODE3_FIFO_MODE(3)
-#define NISTC_AI_MODE3_EXT_GATE_POL BIT(5)
-#define NISTC_AI_MODE3_EXT_GATE_SEL(x) (((x) & 0x1f) << 0)
-
-#define NISTC_AI_STATUS1_REG 2
-#define NISTC_AI_STATUS1_INTA BIT(15)
-#define NISTC_AI_STATUS1_FIFO_F BIT(14)
-#define NISTC_AI_STATUS1_FIFO_HF BIT(13)
-#define NISTC_AI_STATUS1_FIFO_E BIT(12)
-#define NISTC_AI_STATUS1_OVERRUN BIT(11)
-#define NISTC_AI_STATUS1_OVERFLOW BIT(10)
-#define NISTC_AI_STATUS1_SC_TC_ERR BIT(9)
-#define NISTC_AI_STATUS1_OVER (NISTC_AI_STATUS1_OVERRUN | \
- NISTC_AI_STATUS1_OVERFLOW)
-#define NISTC_AI_STATUS1_ERR (NISTC_AI_STATUS1_OVER | \
- NISTC_AI_STATUS1_SC_TC_ERR)
-#define NISTC_AI_STATUS1_START2 BIT(8)
-#define NISTC_AI_STATUS1_START1 BIT(7)
-#define NISTC_AI_STATUS1_SC_TC BIT(6)
-#define NISTC_AI_STATUS1_START BIT(5)
-#define NISTC_AI_STATUS1_STOP BIT(4)
-#define NISTC_AI_STATUS1_G0_TC BIT(3)
-#define NISTC_AI_STATUS1_G0_GATE BIT(2)
-#define NISTC_AI_STATUS1_FIFO_REQ BIT(1)
-#define NISTC_AI_STATUS1_PASSTHRU0 BIT(0)
-
-#define NISTC_AO_STATUS1_REG 3
-#define NISTC_AO_STATUS1_INTB BIT(15)
-#define NISTC_AO_STATUS1_FIFO_F BIT(14)
-#define NISTC_AO_STATUS1_FIFO_HF BIT(13)
-#define NISTC_AO_STATUS1_FIFO_E BIT(12)
-#define NISTC_AO_STATUS1_BC_TC_ERR BIT(11)
-#define NISTC_AO_STATUS1_START BIT(10)
-#define NISTC_AO_STATUS1_OVERRUN BIT(9)
-#define NISTC_AO_STATUS1_START1 BIT(8)
-#define NISTC_AO_STATUS1_BC_TC BIT(7)
-#define NISTC_AO_STATUS1_UC_TC BIT(6)
-#define NISTC_AO_STATUS1_UPDATE BIT(5)
-#define NISTC_AO_STATUS1_UI2_TC BIT(4)
-#define NISTC_AO_STATUS1_G1_TC BIT(3)
-#define NISTC_AO_STATUS1_G1_GATE BIT(2)
-#define NISTC_AO_STATUS1_FIFO_REQ BIT(1)
-#define NISTC_AO_STATUS1_PASSTHRU1 BIT(0)
-
-#define NISTC_G01_STATUS_REG 4
-
-#define NISTC_AI_STATUS2_REG 5
-
-#define NISTC_AO_STATUS2_REG 6
-
-#define NISTC_DIO_IN_REG 7
-
-#define NISTC_G0_HW_SAVE_REG 8
-#define NISTC_G1_HW_SAVE_REG 10
-
-#define NISTC_G0_SAVE_REG 12
-#define NISTC_G1_SAVE_REG 14
-
-#define NISTC_AO_UI_SAVE_REG 16
-#define NISTC_AO_BC_SAVE_REG 18
-#define NISTC_AO_UC_SAVE_REG 20
-
-#define NISTC_STATUS1_REG 27
-#define NISTC_STATUS1_SERIO_IN_PROG BIT(12)
-
-#define NISTC_DIO_SERIAL_IN_REG 28
-
-#define NISTC_STATUS2_REG 29
-#define NISTC_STATUS2_AO_TMRDACWRS_IN_PROGRESS BIT(5)
-
-#define NISTC_AI_SI_SAVE_REG 64
-#define NISTC_AI_SC_SAVE_REG 66
-
-/*
- * PCI E Series Registers
- */
-#define NI_E_STC_WINDOW_ADDR_REG 0x00 /* rw16 */
-#define NI_E_STC_WINDOW_DATA_REG 0x02 /* rw16 */
-
-#define NI_E_STATUS_REG 0x01 /* r8 */
-#define NI_E_STATUS_AI_FIFO_LOWER_NE BIT(3)
-#define NI_E_STATUS_PROMOUT BIT(0)
-
-#define NI_E_DMA_AI_AO_SEL_REG 0x09 /* w8 */
-#define NI_E_DMA_AI_SEL(x) (((x) & 0xf) << 0)
-#define NI_E_DMA_AI_SEL_MASK NI_E_DMA_AI_SEL(0xf)
-#define NI_E_DMA_AO_SEL(x) (((x) & 0xf) << 4)
-#define NI_E_DMA_AO_SEL_MASK NI_E_DMA_AO_SEL(0xf)
-
-#define NI_E_DMA_G0_G1_SEL_REG 0x0b /* w8 */
-#define NI_E_DMA_G0_G1_SEL(_g, _c) (((_c) & 0xf) << ((_g) * 4))
-#define NI_E_DMA_G0_G1_SEL_MASK(_g) NI_E_DMA_G0_G1_SEL((_g), 0xf)
-
-#define NI_E_SERIAL_CMD_REG 0x0d /* w8 */
-#define NI_E_SERIAL_CMD_DAC_LD(x) BIT(3 + (x))
-#define NI_E_SERIAL_CMD_EEPROM_CS BIT(2)
-#define NI_E_SERIAL_CMD_SDATA BIT(1)
-#define NI_E_SERIAL_CMD_SCLK BIT(0)
-
-#define NI_E_MISC_CMD_REG 0x0f /* w8 */
-#define NI_E_MISC_CMD_INTEXT_ATRIG(x) (((x) & 0x1) << 7)
-#define NI_E_MISC_CMD_EXT_ATRIG NI_E_MISC_CMD_INTEXT_ATRIG(0)
-#define NI_E_MISC_CMD_INT_ATRIG NI_E_MISC_CMD_INTEXT_ATRIG(1)
-
-#define NI_E_AI_CFG_LO_REG 0x10 /* w16 */
-#define NI_E_AI_CFG_LO_LAST_CHAN BIT(15)
-#define NI_E_AI_CFG_LO_GEN_TRIG BIT(12)
-#define NI_E_AI_CFG_LO_DITHER BIT(9)
-#define NI_E_AI_CFG_LO_UNI BIT(8)
-#define NI_E_AI_CFG_LO_GAIN(x) ((x) << 0)
-
-#define NI_E_AI_CFG_HI_REG 0x12 /* w16 */
-#define NI_E_AI_CFG_HI_TYPE(x) (((x) & 0x7) << 12)
-#define NI_E_AI_CFG_HI_TYPE_DIFF NI_E_AI_CFG_HI_TYPE(1)
-#define NI_E_AI_CFG_HI_TYPE_COMMON NI_E_AI_CFG_HI_TYPE(2)
-#define NI_E_AI_CFG_HI_TYPE_GROUND NI_E_AI_CFG_HI_TYPE(3)
-#define NI_E_AI_CFG_HI_AC_COUPLE BIT(11)
-#define NI_E_AI_CFG_HI_CHAN(x) (((x) & 0x3f) << 0)
-
-#define NI_E_AO_CFG_REG 0x16 /* w16 */
-#define NI_E_AO_DACSEL(x) ((x) << 8)
-#define NI_E_AO_GROUND_REF BIT(3)
-#define NI_E_AO_EXT_REF BIT(2)
-#define NI_E_AO_DEGLITCH BIT(1)
-#define NI_E_AO_CFG_BIP BIT(0)
-
-#define NI_E_DAC_DIRECT_DATA_REG(x) (0x18 + ((x) * 2)) /* w16 */
-
-#define NI_E_8255_BASE 0x19 /* rw8 */
-
-#define NI_E_AI_FIFO_DATA_REG 0x1c /* r16 */
-
-#define NI_E_AO_FIFO_DATA_REG 0x1e /* w16 */
-
-/*
- * 611x registers (these boards differ from the e-series)
- */
-#define NI611X_MAGIC_REG 0x19 /* w8 (new) */
-#define NI611X_CALIB_CHAN_SEL_REG 0x1a /* w16 (new) */
-#define NI611X_AI_FIFO_DATA_REG 0x1c /* r32 (incompatible) */
-#define NI611X_AI_FIFO_OFFSET_LOAD_REG 0x05 /* r8 (new) */
-#define NI611X_AO_FIFO_DATA_REG 0x14 /* w32 (incompatible) */
-#define NI611X_CAL_GAIN_SEL_REG 0x05 /* w8 (new) */
-
-#define NI611X_AO_WINDOW_ADDR_REG 0x18
-#define NI611X_AO_WINDOW_DATA_REG 0x1e
-
-/*
- * 6143 registers
- */
-#define NI6143_MAGIC_REG 0x19 /* w8 */
-#define NI6143_DMA_G0_G1_SEL_REG 0x0b /* w8 */
-#define NI6143_PIPELINE_DELAY_REG 0x1f /* w8 */
-#define NI6143_EOC_SET_REG 0x1d /* w8 */
-#define NI6143_DMA_AI_SEL_REG 0x09 /* w8 */
-#define NI6143_AI_FIFO_DATA_REG 0x8c /* r32 */
-#define NI6143_AI_FIFO_FLAG_REG 0x84 /* w32 */
-#define NI6143_AI_FIFO_CTRL_REG 0x88 /* w32 */
-#define NI6143_AI_FIFO_STATUS_REG 0x88 /* r32 */
-#define NI6143_AI_FIFO_DMA_THRESH_REG 0x90 /* w32 */
-#define NI6143_AI_FIFO_WORDS_AVAIL_REG 0x94 /* w32 */
-
-#define NI6143_CALIB_CHAN_REG 0x42 /* w16 */
-#define NI6143_CALIB_CHAN_RELAY_ON BIT(15)
-#define NI6143_CALIB_CHAN_RELAY_OFF BIT(14)
-#define NI6143_CALIB_CHAN(x) (((x) & 0xf) << 0)
-#define NI6143_CALIB_CHAN_GND_GND NI6143_CALIB_CHAN(0) /* Offset Cal */
-#define NI6143_CALIB_CHAN_2V5_GND NI6143_CALIB_CHAN(2) /* 2.5V ref */
-#define NI6143_CALIB_CHAN_PWM_GND NI6143_CALIB_CHAN(5) /* +-5V Self Cal */
-#define NI6143_CALIB_CHAN_2V5_PWM NI6143_CALIB_CHAN(10) /* PWM Cal */
-#define NI6143_CALIB_CHAN_PWM_PWM NI6143_CALIB_CHAN(13) /* CMRR */
-#define NI6143_CALIB_CHAN_GND_PWM NI6143_CALIB_CHAN(14) /* PWM Cal */
-#define NI6143_CALIB_LO_TIME_REG 0x20 /* w16 */
-#define NI6143_CALIB_HI_TIME_REG 0x22 /* w16 */
-#define NI6143_RELAY_COUNTER_LOAD_REG 0x4c /* w32 */
-#define NI6143_SIGNATURE_REG 0x50 /* w32 */
-#define NI6143_RELEASE_DATE_REG 0x54 /* w32 */
-#define NI6143_RELEASE_OLDEST_DATE_REG 0x58 /* w32 */
-
-/*
- * 671x, 611x windowed ao registers
- */
-#define NI671X_DAC_DIRECT_DATA_REG(x) (0x00 + (x)) /* w16 */
-#define NI611X_AO_TIMED_REG 0x10 /* w16 */
-#define NI671X_AO_IMMEDIATE_REG 0x11 /* w16 */
-#define NI611X_AO_FIFO_OFFSET_LOAD_REG 0x13 /* w32 */
-#define NI67XX_AO_SP_UPDATES_REG 0x14 /* w16 */
-#define NI611X_AO_WAVEFORM_GEN_REG 0x15 /* w16 */
-#define NI611X_AO_MISC_REG 0x16 /* w16 */
-#define NI611X_AO_MISC_CLEAR_WG BIT(0)
-#define NI67XX_AO_CAL_CHAN_SEL_REG 0x17 /* w16 */
-#define NI67XX_AO_CFG2_REG 0x18 /* w16 */
-#define NI67XX_CAL_CMD_REG 0x19 /* w16 */
-#define NI67XX_CAL_STATUS_REG 0x1a /* r8 */
-#define NI67XX_CAL_STATUS_BUSY BIT(0)
-#define NI67XX_CAL_STATUS_OSC_DETECT BIT(1)
-#define NI67XX_CAL_STATUS_OVERRANGE BIT(2)
-#define NI67XX_CAL_DATA_REG 0x1b /* r16 */
-#define NI67XX_CAL_CFG_HI_REG 0x1c /* rw16 */
-#define NI67XX_CAL_CFG_LO_REG 0x1d /* rw16 */
-
-#define CS5529_CMD_CB BIT(7)
-#define CS5529_CMD_SINGLE_CONV BIT(6)
-#define CS5529_CMD_CONT_CONV BIT(5)
-#define CS5529_CMD_READ BIT(4)
-#define CS5529_CMD_REG(x) (((x) & 0x7) << 1)
-#define CS5529_CMD_REG_MASK CS5529_CMD_REG(7)
-#define CS5529_CMD_PWR_SAVE BIT(0)
-
-#define CS5529_OFFSET_REG CS5529_CMD_REG(0)
-#define CS5529_GAIN_REG CS5529_CMD_REG(1)
-#define CS5529_CONV_DATA_REG CS5529_CMD_REG(3)
-#define CS5529_SETUP_REG CS5529_CMD_REG(4)
-
-#define CS5529_CFG_REG CS5529_CMD_REG(2)
-#define CS5529_CFG_AOUT(x) BIT(22 + (x))
-#define CS5529_CFG_DOUT(x) BIT(18 + (x))
-#define CS5529_CFG_LOW_PWR_MODE BIT(16)
-#define CS5529_CFG_WORD_RATE(x) (((x) & 0x7) << 13)
-#define CS5529_CFG_WORD_RATE_MASK CS5529_CFG_WORD_RATE(0x7)
-#define CS5529_CFG_WORD_RATE_2180 CS5529_CFG_WORD_RATE(0)
-#define CS5529_CFG_WORD_RATE_1092 CS5529_CFG_WORD_RATE(1)
-#define CS5529_CFG_WORD_RATE_532 CS5529_CFG_WORD_RATE(2)
-#define CS5529_CFG_WORD_RATE_388 CS5529_CFG_WORD_RATE(3)
-#define CS5529_CFG_WORD_RATE_324 CS5529_CFG_WORD_RATE(4)
-#define CS5529_CFG_WORD_RATE_17444 CS5529_CFG_WORD_RATE(5)
-#define CS5529_CFG_WORD_RATE_8724 CS5529_CFG_WORD_RATE(6)
-#define CS5529_CFG_WORD_RATE_4364 CS5529_CFG_WORD_RATE(7)
-#define CS5529_CFG_UNIPOLAR BIT(12)
-#define CS5529_CFG_RESET BIT(7)
-#define CS5529_CFG_RESET_VALID BIT(6)
-#define CS5529_CFG_PORT_FLAG BIT(5)
-#define CS5529_CFG_PWR_SAVE_SEL BIT(4)
-#define CS5529_CFG_DONE_FLAG BIT(3)
-#define CS5529_CFG_CALIB(x) (((x) & 0x7) << 0)
-#define CS5529_CFG_CALIB_NONE CS5529_CFG_CALIB(0)
-#define CS5529_CFG_CALIB_OFFSET_SELF CS5529_CFG_CALIB(1)
-#define CS5529_CFG_CALIB_GAIN_SELF CS5529_CFG_CALIB(2)
-#define CS5529_CFG_CALIB_BOTH_SELF CS5529_CFG_CALIB(3)
-#define CS5529_CFG_CALIB_OFFSET_SYS CS5529_CFG_CALIB(5)
-#define CS5529_CFG_CALIB_GAIN_SYS CS5529_CFG_CALIB(6)
-
-/*
- * M-Series specific registers not handled by the DAQ-STC and GPCT register
- * remapping.
- */
-#define NI_M_CDIO_DMA_SEL_REG 0x007
-#define NI_M_CDIO_DMA_SEL_CDO(x) (((x) & 0xf) << 4)
-#define NI_M_CDIO_DMA_SEL_CDO_MASK NI_M_CDIO_DMA_SEL_CDO(0xf)
-#define NI_M_CDIO_DMA_SEL_CDI(x) (((x) & 0xf) << 0)
-#define NI_M_CDIO_DMA_SEL_CDI_MASK NI_M_CDIO_DMA_SEL_CDI(0xf)
-#define NI_M_SCXI_STATUS_REG 0x007
-#define NI_M_AI_AO_SEL_REG 0x009
-#define NI_M_G0_G1_SEL_REG 0x00b
-#define NI_M_MISC_CMD_REG 0x00f
-#define NI_M_SCXI_SER_DO_REG 0x011
-#define NI_M_SCXI_CTRL_REG 0x013
-#define NI_M_SCXI_OUT_ENA_REG 0x015
-#define NI_M_AI_FIFO_DATA_REG 0x01c
-#define NI_M_DIO_REG 0x024
-#define NI_M_DIO_DIR_REG 0x028
-#define NI_M_CAL_PWM_REG 0x040
-#define NI_M_CAL_PWM_HIGH_TIME(x) (((x) & 0xffff) << 16)
-#define NI_M_CAL_PWM_LOW_TIME(x) (((x) & 0xffff) << 0)
-#define NI_M_GEN_PWM_REG(x) (0x044 + ((x) * 2))
-#define NI_M_AI_CFG_FIFO_DATA_REG 0x05e
-#define NI_M_AI_CFG_LAST_CHAN BIT(14)
-#define NI_M_AI_CFG_DITHER BIT(13)
-#define NI_M_AI_CFG_POLARITY BIT(12)
-#define NI_M_AI_CFG_GAIN(x) (((x) & 0x7) << 9)
-#define NI_M_AI_CFG_CHAN_TYPE(x) (((x) & 0x7) << 6)
-#define NI_M_AI_CFG_CHAN_TYPE_MASK NI_M_AI_CFG_CHAN_TYPE(7)
-#define NI_M_AI_CFG_CHAN_TYPE_CALIB NI_M_AI_CFG_CHAN_TYPE(0)
-#define NI_M_AI_CFG_CHAN_TYPE_DIFF NI_M_AI_CFG_CHAN_TYPE(1)
-#define NI_M_AI_CFG_CHAN_TYPE_COMMON NI_M_AI_CFG_CHAN_TYPE(2)
-#define NI_M_AI_CFG_CHAN_TYPE_GROUND NI_M_AI_CFG_CHAN_TYPE(3)
-#define NI_M_AI_CFG_CHAN_TYPE_AUX NI_M_AI_CFG_CHAN_TYPE(5)
-#define NI_M_AI_CFG_CHAN_TYPE_GHOST NI_M_AI_CFG_CHAN_TYPE(7)
-#define NI_M_AI_CFG_BANK_SEL(x) ((((x) & 0x40) << 4) | ((x) & 0x30))
-#define NI_M_AI_CFG_CHAN_SEL(x) (((x) & 0xf) << 0)
-#define NI_M_INTC_ENA_REG 0x088
-#define NI_M_INTC_ENA BIT(0)
-#define NI_M_INTC_STATUS_REG 0x088
-#define NI_M_INTC_STATUS BIT(0)
-#define NI_M_ATRIG_CTRL_REG 0x08c
-#define NI_M_AO_SER_INT_ENA_REG 0x0a0
-#define NI_M_AO_SER_INT_ACK_REG 0x0a1
-#define NI_M_AO_SER_INT_STATUS_REG 0x0a1
-#define NI_M_AO_CALIB_REG 0x0a3
-#define NI_M_AO_FIFO_DATA_REG 0x0a4
-#define NI_M_PFI_FILTER_REG 0x0b0
-#define NI_M_PFI_FILTER_SEL(_c, _f) (((_f) & 0x3) << ((_c) * 2))
-#define NI_M_PFI_FILTER_SEL_MASK(_c) NI_M_PFI_FILTER_SEL((_c), 0x3)
-#define NI_M_RTSI_FILTER_REG 0x0b4
-#define NI_M_SCXI_LEGACY_COMPAT_REG 0x0bc
-#define NI_M_DAC_DIRECT_DATA_REG(x) (0x0c0 + ((x) * 4))
-#define NI_M_AO_WAVEFORM_ORDER_REG(x) (0x0c2 + ((x) * 4))
-#define NI_M_AO_CFG_BANK_REG(x) (0x0c3 + ((x) * 4))
-#define NI_M_AO_CFG_BANK_BIPOLAR BIT(7)
-#define NI_M_AO_CFG_BANK_UPDATE_TIMED BIT(6)
-#define NI_M_AO_CFG_BANK_REF(x) (((x) & 0x7) << 3)
-#define NI_M_AO_CFG_BANK_REF_MASK NI_M_AO_CFG_BANK_REF(7)
-#define NI_M_AO_CFG_BANK_REF_INT_10V NI_M_AO_CFG_BANK_REF(0)
-#define NI_M_AO_CFG_BANK_REF_INT_5V NI_M_AO_CFG_BANK_REF(1)
-#define NI_M_AO_CFG_BANK_OFFSET(x) (((x) & 0x7) << 0)
-#define NI_M_AO_CFG_BANK_OFFSET_MASK NI_M_AO_CFG_BANK_OFFSET(7)
-#define NI_M_AO_CFG_BANK_OFFSET_0V NI_M_AO_CFG_BANK_OFFSET(0)
-#define NI_M_AO_CFG_BANK_OFFSET_5V NI_M_AO_CFG_BANK_OFFSET(1)
-#define NI_M_RTSI_SHARED_MUX_REG 0x1a2
-#define NI_M_CLK_FOUT2_REG 0x1c4
-#define NI_M_CLK_FOUT2_RTSI_10MHZ BIT(7)
-#define NI_M_CLK_FOUT2_TIMEBASE3_PLL BIT(6)
-#define NI_M_CLK_FOUT2_TIMEBASE1_PLL BIT(5)
-#define NI_M_CLK_FOUT2_PLL_SRC(x) (((x) & 0x1f) << 0)
-#define NI_M_CLK_FOUT2_PLL_SRC_MASK NI_M_CLK_FOUT2_PLL_SRC(0x1f)
-#define NI_M_MAX_RTSI_CHAN 7
-#define NI_M_CLK_FOUT2_PLL_SRC_RTSI(x) (((x) == NI_M_MAX_RTSI_CHAN) \
- ? NI_M_CLK_FOUT2_PLL_SRC(0x1b) \
- : NI_M_CLK_FOUT2_PLL_SRC(0xb + (x)))
-#define NI_M_CLK_FOUT2_PLL_SRC_STAR NI_M_CLK_FOUT2_PLL_SRC(0x14)
-#define NI_M_CLK_FOUT2_PLL_SRC_PXI10 NI_M_CLK_FOUT2_PLL_SRC(0x1d)
-#define NI_M_PLL_CTRL_REG 0x1c6
-#define NI_M_PLL_CTRL_VCO_MODE(x) (((x) & 0x3) << 13)
-#define NI_M_PLL_CTRL_VCO_MODE_200_325MHZ NI_M_PLL_CTRL_VCO_MODE(0)
-#define NI_M_PLL_CTRL_VCO_MODE_175_225MHZ NI_M_PLL_CTRL_VCO_MODE(1)
-#define NI_M_PLL_CTRL_VCO_MODE_100_225MHZ NI_M_PLL_CTRL_VCO_MODE(2)
-#define NI_M_PLL_CTRL_VCO_MODE_75_150MHZ NI_M_PLL_CTRL_VCO_MODE(3)
-#define NI_M_PLL_CTRL_ENA BIT(12)
-#define NI_M_PLL_MAX_DIVISOR 0x10
-#define NI_M_PLL_CTRL_DIVISOR(x) (((x) & 0xf) << 8)
-#define NI_M_PLL_MAX_MULTIPLIER 0x100
-#define NI_M_PLL_CTRL_MULTIPLIER(x) (((x) & 0xff) << 0)
-#define NI_M_PLL_STATUS_REG 0x1c8
-#define NI_M_PLL_STATUS_LOCKED BIT(0)
-#define NI_M_PFI_OUT_SEL_REG(x) (0x1d0 + ((x) * 2))
-#define NI_M_PFI_CHAN(_c) (((_c) % 3) * 5)
-#define NI_M_PFI_OUT_SEL(_c, _s) (((_s) & 0x1f) << NI_M_PFI_CHAN(_c))
-#define NI_M_PFI_OUT_SEL_MASK(_c) (0x1f << NI_M_PFI_CHAN(_c))
-#define NI_M_PFI_OUT_SEL_TO_SRC(_c, _b) (((_b) >> NI_M_PFI_CHAN(_c)) & 0x1f)
-#define NI_M_PFI_DI_REG 0x1dc
-#define NI_M_PFI_DO_REG 0x1de
-#define NI_M_CFG_BYPASS_FIFO_REG 0x218
-#define NI_M_CFG_BYPASS_FIFO BIT(31)
-#define NI_M_CFG_BYPASS_AI_POLARITY BIT(22)
-#define NI_M_CFG_BYPASS_AI_DITHER BIT(21)
-#define NI_M_CFG_BYPASS_AI_GAIN(x) (((x) & 0x7) << 18)
-#define NI_M_CFG_BYPASS_AO_CAL(x) (((x) & 0xf) << 15)
-#define NI_M_CFG_BYPASS_AO_CAL_MASK NI_M_CFG_BYPASS_AO_CAL(0xf)
-#define NI_M_CFG_BYPASS_AI_MODE_MUX(x) (((x) & 0x3) << 13)
-#define NI_M_CFG_BYPASS_AI_MODE_MUX_MASK NI_M_CFG_BYPASS_AI_MODE_MUX(3)
-#define NI_M_CFG_BYPASS_AI_CAL_NEG(x) (((x) & 0x7) << 10)
-#define NI_M_CFG_BYPASS_AI_CAL_NEG_MASK NI_M_CFG_BYPASS_AI_CAL_NEG(7)
-#define NI_M_CFG_BYPASS_AI_CAL_POS(x) (((x) & 0x7) << 7)
-#define NI_M_CFG_BYPASS_AI_CAL_POS_MASK NI_M_CFG_BYPASS_AI_CAL_POS(7)
-#define NI_M_CFG_BYPASS_AI_CAL_MASK (NI_M_CFG_BYPASS_AI_CAL_POS_MASK | \
- NI_M_CFG_BYPASS_AI_CAL_NEG_MASK | \
- NI_M_CFG_BYPASS_AI_MODE_MUX_MASK | \
- NI_M_CFG_BYPASS_AO_CAL_MASK)
-#define NI_M_CFG_BYPASS_AI_BANK(x) (((x) & 0xf) << 3)
-#define NI_M_CFG_BYPASS_AI_BANK_MASK NI_M_CFG_BYPASS_AI_BANK(0xf)
-#define NI_M_CFG_BYPASS_AI_CHAN(x) (((x) & 0x7) << 0)
-#define NI_M_CFG_BYPASS_AI_CHAN_MASK NI_M_CFG_BYPASS_AI_CHAN(7)
-#define NI_M_SCXI_DIO_ENA_REG 0x21c
-#define NI_M_CDI_FIFO_DATA_REG 0x220
-#define NI_M_CDO_FIFO_DATA_REG 0x220
-#define NI_M_CDIO_STATUS_REG 0x224
-#define NI_M_CDIO_STATUS_CDI_OVERFLOW BIT(20)
-#define NI_M_CDIO_STATUS_CDI_OVERRUN BIT(19)
-#define NI_M_CDIO_STATUS_CDI_ERROR (NI_M_CDIO_STATUS_CDI_OVERFLOW | \
- NI_M_CDIO_STATUS_CDI_OVERRUN)
-#define NI_M_CDIO_STATUS_CDI_FIFO_REQ BIT(18)
-#define NI_M_CDIO_STATUS_CDI_FIFO_FULL BIT(17)
-#define NI_M_CDIO_STATUS_CDI_FIFO_EMPTY BIT(16)
-#define NI_M_CDIO_STATUS_CDO_UNDERFLOW BIT(4)
-#define NI_M_CDIO_STATUS_CDO_OVERRUN BIT(3)
-#define NI_M_CDIO_STATUS_CDO_ERROR (NI_M_CDIO_STATUS_CDO_UNDERFLOW | \
- NI_M_CDIO_STATUS_CDO_OVERRUN)
-#define NI_M_CDIO_STATUS_CDO_FIFO_REQ BIT(2)
-#define NI_M_CDIO_STATUS_CDO_FIFO_FULL BIT(1)
-#define NI_M_CDIO_STATUS_CDO_FIFO_EMPTY BIT(0)
-#define NI_M_CDIO_CMD_REG 0x224
-#define NI_M_CDI_CMD_SW_UPDATE BIT(20)
-#define NI_M_CDO_CMD_SW_UPDATE BIT(19)
-#define NI_M_CDO_CMD_F_E_INT_ENA_CLR BIT(17)
-#define NI_M_CDO_CMD_F_E_INT_ENA_SET BIT(16)
-#define NI_M_CDI_CMD_ERR_INT_CONFIRM BIT(15)
-#define NI_M_CDO_CMD_ERR_INT_CONFIRM BIT(14)
-#define NI_M_CDI_CMD_F_REQ_INT_ENA_CLR BIT(13)
-#define NI_M_CDI_CMD_F_REQ_INT_ENA_SET BIT(12)
-#define NI_M_CDO_CMD_F_REQ_INT_ENA_CLR BIT(11)
-#define NI_M_CDO_CMD_F_REQ_INT_ENA_SET BIT(10)
-#define NI_M_CDI_CMD_ERR_INT_ENA_CLR BIT(9)
-#define NI_M_CDI_CMD_ERR_INT_ENA_SET BIT(8)
-#define NI_M_CDO_CMD_ERR_INT_ENA_CLR BIT(7)
-#define NI_M_CDO_CMD_ERR_INT_ENA_SET BIT(6)
-#define NI_M_CDI_CMD_RESET BIT(5)
-#define NI_M_CDO_CMD_RESET BIT(4)
-#define NI_M_CDI_CMD_ARM BIT(3)
-#define NI_M_CDI_CMD_DISARM BIT(2)
-#define NI_M_CDO_CMD_ARM BIT(1)
-#define NI_M_CDO_CMD_DISARM BIT(0)
-#define NI_M_CDI_MODE_REG 0x228
-#define NI_M_CDI_MODE_DATA_LANE(x) (((x) & 0x3) << 12)
-#define NI_M_CDI_MODE_DATA_LANE_MASK NI_M_CDI_MODE_DATA_LANE(3)
-#define NI_M_CDI_MODE_DATA_LANE_0_15 NI_M_CDI_MODE_DATA_LANE(0)
-#define NI_M_CDI_MODE_DATA_LANE_16_31 NI_M_CDI_MODE_DATA_LANE(1)
-#define NI_M_CDI_MODE_DATA_LANE_0_7 NI_M_CDI_MODE_DATA_LANE(0)
-#define NI_M_CDI_MODE_DATA_LANE_8_15 NI_M_CDI_MODE_DATA_LANE(1)
-#define NI_M_CDI_MODE_DATA_LANE_16_23 NI_M_CDI_MODE_DATA_LANE(2)
-#define NI_M_CDI_MODE_DATA_LANE_24_31 NI_M_CDI_MODE_DATA_LANE(3)
-#define NI_M_CDI_MODE_FIFO_MODE BIT(11)
-#define NI_M_CDI_MODE_POLARITY BIT(10)
-#define NI_M_CDI_MODE_HALT_ON_ERROR BIT(9)
-#define NI_M_CDI_MODE_SAMPLE_SRC(x) (((x) & 0x3f) << 0)
-#define NI_M_CDI_MODE_SAMPLE_SRC_MASK NI_M_CDI_MODE_SAMPLE_SRC(0x3f)
-#define NI_M_CDO_MODE_REG 0x22c
-#define NI_M_CDO_MODE_DATA_LANE(x) (((x) & 0x3) << 12)
-#define NI_M_CDO_MODE_DATA_LANE_MASK NI_M_CDO_MODE_DATA_LANE(3)
-#define NI_M_CDO_MODE_DATA_LANE_0_15 NI_M_CDO_MODE_DATA_LANE(0)
-#define NI_M_CDO_MODE_DATA_LANE_16_31 NI_M_CDO_MODE_DATA_LANE(1)
-#define NI_M_CDO_MODE_DATA_LANE_0_7 NI_M_CDO_MODE_DATA_LANE(0)
-#define NI_M_CDO_MODE_DATA_LANE_8_15 NI_M_CDO_MODE_DATA_LANE(1)
-#define NI_M_CDO_MODE_DATA_LANE_16_23 NI_M_CDO_MODE_DATA_LANE(2)
-#define NI_M_CDO_MODE_DATA_LANE_24_31 NI_M_CDO_MODE_DATA_LANE(3)
-#define NI_M_CDO_MODE_FIFO_MODE BIT(11)
-#define NI_M_CDO_MODE_POLARITY BIT(10)
-#define NI_M_CDO_MODE_HALT_ON_ERROR BIT(9)
-#define NI_M_CDO_MODE_RETRANSMIT BIT(8)
-#define NI_M_CDO_MODE_SAMPLE_SRC(x) (((x) & 0x3f) << 0)
-#define NI_M_CDO_MODE_SAMPLE_SRC_MASK NI_M_CDO_MODE_SAMPLE_SRC(0x3f)
-#define NI_M_CDI_MASK_ENA_REG 0x230
-#define NI_M_CDO_MASK_ENA_REG 0x234
-#define NI_M_STATIC_AI_CTRL_REG(x) ((x) ? (0x260 + (x)) : 0x064)
-#define NI_M_AO_REF_ATTENUATION_REG(x) (0x264 + (x))
-#define NI_M_AO_REF_ATTENUATION_X5 BIT(0)
-
-enum {
- ai_gain_16 = 0,
- ai_gain_8,
- ai_gain_14,
- ai_gain_4,
- ai_gain_611x,
- ai_gain_622x,
- ai_gain_628x,
- ai_gain_6143
-};
-
-enum caldac_enum {
- caldac_none = 0,
- mb88341,
- dac8800,
- dac8043,
- ad8522,
- ad8804,
- ad8842,
- ad8804_debug
-};
-
-enum ni_reg_type {
- ni_reg_normal = 0x0,
- ni_reg_611x = 0x1,
- ni_reg_6711 = 0x2,
- ni_reg_6713 = 0x4,
- ni_reg_67xx_mask = 0x6,
- ni_reg_6xxx_mask = 0x7,
- ni_reg_622x = 0x8,
- ni_reg_625x = 0x10,
- ni_reg_628x = 0x18,
- ni_reg_m_series_mask = 0x18,
- ni_reg_6143 = 0x20
-};
-
-struct ni_board_struct {
- const char *name;
- const char *alt_route_name;
- int device_id;
- int isapnp_id;
-
- int n_adchan;
- unsigned int ai_maxdata;
-
- int ai_fifo_depth;
- unsigned int alwaysdither:1;
- int gainlkup;
- int ai_speed;
-
- int n_aochan;
- unsigned int ao_maxdata;
- int ao_fifo_depth;
- const struct comedi_lrange *ao_range_table;
- unsigned int ao_speed;
-
- int reg_type;
- unsigned int has_8255:1;
- unsigned int has_32dio_chan:1;
- unsigned int dio_speed; /* not for e-series */
-
- enum caldac_enum caldac[3];
-};
-
-#define MAX_N_CALDACS 34
-#define MAX_N_AO_CHAN 8
-#define NUM_GPCT 2
-
-#define NUM_PFI_OUTPUT_SELECT_REGS 6
-#define NUM_RTSI_SHARED_MUXS (NI_RTSI_BRD(-1) - NI_RTSI_BRD(0) + 1)
-
-#define M_SERIES_EEPROM_SIZE 1024
-
-struct ni_private {
- unsigned short dio_output;
- unsigned short dio_control;
- int aimode;
- unsigned int ai_calib_source;
- unsigned int ai_calib_source_enabled;
- /* protects access to windowed registers */
- spinlock_t window_lock;
- /* protects interrupt/dma register access */
- spinlock_t soft_reg_copy_lock;
- /* protects mite DMA channel request/release */
- spinlock_t mite_channel_lock;
-
- int changain_state;
- unsigned int changain_spec;
-
- unsigned int caldac_maxdata_list[MAX_N_CALDACS];
- unsigned short caldacs[MAX_N_CALDACS];
-
- unsigned short ai_cmd2;
-
- unsigned short ao_conf[MAX_N_AO_CHAN];
- unsigned short ao_mode1;
- unsigned short ao_mode2;
- unsigned short ao_mode3;
- unsigned short ao_cmd1;
- unsigned short ao_cmd2;
-
- struct ni_gpct_device *counter_dev;
- unsigned short an_trig_etc_reg;
-
- unsigned int ai_offset[512];
-
- unsigned long serial_interval_ns;
- unsigned char serial_hw_mode;
- unsigned short clock_and_fout;
- unsigned short clock_and_fout2;
-
- unsigned short int_a_enable_reg;
- unsigned short int_b_enable_reg;
- unsigned short io_bidirection_pin_reg;
- unsigned short rtsi_trig_direction_reg;
- unsigned short rtsi_trig_a_output_reg;
- unsigned short rtsi_trig_b_output_reg;
- unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS];
- unsigned short ai_ao_select_reg;
- unsigned short g0_g1_select_reg;
- unsigned short cdio_dma_select_reg;
-
- unsigned int clock_ns;
- unsigned int clock_source;
-
- unsigned short pwm_up_count;
- unsigned short pwm_down_count;
-
- unsigned short ai_fifo_buffer[0x2000];
- u8 eeprom_buffer[M_SERIES_EEPROM_SIZE];
-
- struct mite *mite;
- struct mite_channel *ai_mite_chan;
- struct mite_channel *ao_mite_chan;
- struct mite_channel *cdo_mite_chan;
- struct mite_ring *ai_mite_ring;
- struct mite_ring *ao_mite_ring;
- struct mite_ring *cdo_mite_ring;
- struct mite_ring *gpct_mite_ring[NUM_GPCT];
-
- /* ni_pcimio board type flags (based on the boardinfo reg_type) */
- unsigned int is_m_series:1;
- unsigned int is_6xxx:1;
- unsigned int is_611x:1;
- unsigned int is_6143:1;
- unsigned int is_622x:1;
- unsigned int is_625x:1;
- unsigned int is_628x:1;
- unsigned int is_67xx:1;
- unsigned int is_6711:1;
- unsigned int is_6713:1;
-
- /*
- * Boolean value of whether device needs to be armed.
- *
- * Currently, only NI AO devices are known to be needing arming, since
- * the DAC registers must be preloaded before triggering.
- * This variable should only be set true during a command operation
- * (e.g ni_ao_cmd) and should then be set false by the arming
- * function (e.g. ni_ao_arm).
- *
- * This variable helps to ensure that multiple DMA allocations are not
- * possible.
- */
- unsigned int ao_needs_arming:1;
-
- /* device signal route tables */
- struct ni_route_tables routing_tables;
-
- /*
- * Number of clients (RTSI lines) for current RTSI MUX source.
- *
- * This allows resource management of RTSI board/shared mux lines by
- * marking the RTSI line that is using a particular MUX. Currently,
- * these lines are only automatically allocated based on source of the
- * route requested. Furthermore, the only way that this auto-allocation
- * and configuration works is via the globally-named ni signal/terminal
- * names.
- */
- u8 rtsi_shared_mux_usage[NUM_RTSI_SHARED_MUXS];
-
- /*
- * softcopy register for rtsi shared mux/board lines.
- * For e-series, the bit layout of this register is
- * (docs: mhddk/nieseries/ChipObjects/tSTC.{h,ipp},
- * DAQ-STC, Jan 1999, 340934B-01):
- * bits 0:2 -- NI_RTSI_BRD(0) source selection
- * bits 3:5 -- NI_RTSI_BRD(1) source selection
- * bits 6:8 -- NI_RTSI_BRD(2) source selection
- * bits 9:11 -- NI_RTSI_BRD(3) source selection
- * bit 12 -- NI_RTSI_BRD(0) direction, 0:input, 1:output
- * bit 13 -- NI_RTSI_BRD(1) direction, 0:input, 1:output
- * bit 14 -- NI_RTSI_BRD(2) direction, 0:input, 1:output
- * bit 15 -- NI_RTSI_BRD(3) direction, 0:input, 1:output
- * According to DAQ-STC:
- * RTSI Board Interface--Configured as an input, each bidirectional
- * RTSI_BRD pin can drive any of the seven RTSI_TRIGGER pins.
- * RTSI_BRD<0..1> can also be driven by AI STOP and RTSI_BRD<2..3>
- * can also be driven by the AI START and SCAN_IN_PROG signals.
- * These pins provide a mechanism for additional board-level signals
- * to be sent on or received from the RTSI bus.
- * Couple of comments:
- * - Neither the DAQ-STC nor the MHDDK is clear on what the direction
- * of the RTSI_BRD pins actually means. There does not appear to be
- * any clear indication on what "output" would mean, since the point
- * of the RTSI_BRD lines is to always drive one of the
- * RTSI_TRIGGER<0..6> lines.
- * - The DAQ-STC also indicates that the NI_RTSI_BRD lines can be
- * driven by any of the RTSI_TRIGGER<0..6> lines.
- * But, looking at valid device routes, as visually imported from
- * NI-MAX, there appears to be only one family (so far) that has the
- * ability to route a signal from one TRIGGER_LINE to another
- * TRIGGER_LINE: the 653x family of DIO devices.
- *
- * For m-series, the bit layout of this register is
- * (docs: mhddk/nimseries/ChipObjects/tMSeries.{h,ipp}):
- * bits 0:3 -- NI_RTSI_BRD(0) source selection
- * bits 4:7 -- NI_RTSI_BRD(1) source selection
- * bits 8:11 -- NI_RTSI_BRD(2) source selection
- * bits 12:15 -- NI_RTSI_BRD(3) source selection
- * Note: The m-series does not have any option to change direction of
- * NI_RTSI_BRD muxes. Furthermore, there are no register values that
- * indicate the ability to have TRIGGER_LINES driving the output of
- * the NI_RTSI_BRD muxes.
- */
- u16 rtsi_shared_mux_reg;
-
- /*
- * Number of clients (RTSI lines) for current RGOUT0 path.
- * Stored in part of in RTSI_TRIG_DIR or RTSI_TRIGB registers
- */
- u8 rgout0_usage;
-};
-
-static const struct comedi_lrange range_ni_E_ao_ext;
-
-#endif /* _COMEDI_NI_STC_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
deleted file mode 100644
index f6154addaa95..000000000000
--- a/drivers/staging/comedi/drivers/ni_tio.c
+++ /dev/null
@@ -1,1842 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Support for NI general purpose counters
- *
- * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-/*
- * Module: ni_tio
- * Description: National Instruments general purpose counters
- * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
- * Herman.Bruyninckx@mech.kuleuven.ac.be,
- * Wim.Meeussen@mech.kuleuven.ac.be,
- * Klaas.Gadeyne@mech.kuleuven.ac.be,
- * Frank Mori Hess <fmhess@users.sourceforge.net>
- * Updated: Thu Nov 16 09:50:32 EST 2006
- * Status: works
- *
- * This module is not used directly by end-users. Rather, it
- * is used by other drivers (for example ni_660x and ni_pcimio)
- * to provide support for NI's general purpose counters. It was
- * originally based on the counter code from ni_660x.c and
- * ni_mio_common.c.
- *
- * References:
- * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
- * DAQ 6601/6602 User Manual (NI 322137B-01)
- * 340934b.pdf DAQ-STC reference manual
- *
- * TODO: Support use of both banks X and Y
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "ni_tio_internal.h"
-
-/*
- * clock sources for ni e and m series boards,
- * get bits with GI_SRC_SEL()
- */
-#define NI_M_TIMEBASE_1_CLK 0x0 /* 20MHz */
-#define NI_M_PFI_CLK(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
-#define NI_M_RTSI_CLK(x) (((x) == 7) ? 0x1b : (0xb + (x)))
-#define NI_M_TIMEBASE_2_CLK 0x12 /* 100KHz */
-#define NI_M_NEXT_TC_CLK 0x13
-#define NI_M_NEXT_GATE_CLK 0x14 /* Gi_Src_SubSelect=0 */
-#define NI_M_PXI_STAR_TRIGGER_CLK 0x14 /* Gi_Src_SubSelect=1 */
-#define NI_M_PXI10_CLK 0x1d
-#define NI_M_TIMEBASE_3_CLK 0x1e /* 80MHz, Gi_Src_SubSelect=0 */
-#define NI_M_ANALOG_TRIGGER_OUT_CLK 0x1e /* Gi_Src_SubSelect=1 */
-#define NI_M_LOGIC_LOW_CLK 0x1f
-#define NI_M_MAX_PFI_CHAN 15
-#define NI_M_MAX_RTSI_CHAN 7
-
-/*
- * clock sources for ni_660x boards,
- * get bits with GI_SRC_SEL()
- */
-#define NI_660X_TIMEBASE_1_CLK 0x0 /* 20MHz */
-#define NI_660X_SRC_PIN_I_CLK 0x1
-#define NI_660X_SRC_PIN_CLK(x) (0x2 + (x))
-#define NI_660X_NEXT_GATE_CLK 0xa
-#define NI_660X_RTSI_CLK(x) (0xb + (x))
-#define NI_660X_TIMEBASE_2_CLK 0x12 /* 100KHz */
-#define NI_660X_NEXT_TC_CLK 0x13
-#define NI_660X_TIMEBASE_3_CLK 0x1e /* 80MHz */
-#define NI_660X_LOGIC_LOW_CLK 0x1f
-#define NI_660X_MAX_SRC_PIN 7
-#define NI_660X_MAX_RTSI_CHAN 6
-
-/* ni m series gate_select */
-#define NI_M_TIMESTAMP_MUX_GATE_SEL 0x0
-#define NI_M_PFI_GATE_SEL(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
-#define NI_M_RTSI_GATE_SEL(x) (((x) == 7) ? 0x1b : (0xb + (x)))
-#define NI_M_AI_START2_GATE_SEL 0x12
-#define NI_M_PXI_STAR_TRIGGER_GATE_SEL 0x13
-#define NI_M_NEXT_OUT_GATE_SEL 0x14
-#define NI_M_AI_START1_GATE_SEL 0x1c
-#define NI_M_NEXT_SRC_GATE_SEL 0x1d
-#define NI_M_ANALOG_TRIG_OUT_GATE_SEL 0x1e
-#define NI_M_LOGIC_LOW_GATE_SEL 0x1f
-
-/* ni_660x gate select */
-#define NI_660X_SRC_PIN_I_GATE_SEL 0x0
-#define NI_660X_GATE_PIN_I_GATE_SEL 0x1
-#define NI_660X_PIN_GATE_SEL(x) (0x2 + (x))
-#define NI_660X_NEXT_SRC_GATE_SEL 0xa
-#define NI_660X_RTSI_GATE_SEL(x) (0xb + (x))
-#define NI_660X_NEXT_OUT_GATE_SEL 0x14
-#define NI_660X_LOGIC_LOW_GATE_SEL 0x1f
-#define NI_660X_MAX_GATE_PIN 7
-
-/* ni_660x second gate select */
-#define NI_660X_SRC_PIN_I_GATE2_SEL 0x0
-#define NI_660X_UD_PIN_I_GATE2_SEL 0x1
-#define NI_660X_UD_PIN_GATE2_SEL(x) (0x2 + (x))
-#define NI_660X_NEXT_SRC_GATE2_SEL 0xa
-#define NI_660X_RTSI_GATE2_SEL(x) (0xb + (x))
-#define NI_660X_NEXT_OUT_GATE2_SEL 0x14
-#define NI_660X_SELECTED_GATE2_SEL 0x1e
-#define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f
-#define NI_660X_MAX_UP_DOWN_PIN 7
-
-static inline unsigned int GI_PRESCALE_X2(enum ni_gpct_variant variant)
-{
- switch (variant) {
- case ni_gpct_variant_e_series:
- default:
- return 0;
- case ni_gpct_variant_m_series:
- return GI_M_PRESCALE_X2;
- case ni_gpct_variant_660x:
- return GI_660X_PRESCALE_X2;
- }
-}
-
-static inline unsigned int GI_PRESCALE_X8(enum ni_gpct_variant variant)
-{
- switch (variant) {
- case ni_gpct_variant_e_series:
- default:
- return 0;
- case ni_gpct_variant_m_series:
- return GI_M_PRESCALE_X8;
- case ni_gpct_variant_660x:
- return GI_660X_PRESCALE_X8;
- }
-}
-
-static bool ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev)
-{
- switch (counter_dev->variant) {
- case ni_gpct_variant_e_series:
- default:
- return false;
- case ni_gpct_variant_m_series:
- case ni_gpct_variant_660x:
- return true;
- }
-}
-
-/**
- * ni_tio_write() - Write a TIO register using the driver provided callback.
- * @counter: struct ni_gpct counter.
- * @value: the value to write
- * @reg: the register to write.
- */
-void ni_tio_write(struct ni_gpct *counter, unsigned int value,
- enum ni_gpct_register reg)
-{
- if (reg < NITIO_NUM_REGS)
- counter->counter_dev->write(counter, value, reg);
-}
-EXPORT_SYMBOL_GPL(ni_tio_write);
-
-/**
- * ni_tio_read() - Read a TIO register using the driver provided callback.
- * @counter: struct ni_gpct counter.
- * @reg: the register to read.
- */
-unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register reg)
-{
- if (reg < NITIO_NUM_REGS)
- return counter->counter_dev->read(counter, reg);
- return 0;
-}
-EXPORT_SYMBOL_GPL(ni_tio_read);
-
-static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
-{
- unsigned int cidx = counter->counter_index;
-
- ni_tio_write(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx));
-}
-
-static int ni_tio_clock_period_ps(const struct ni_gpct *counter,
- unsigned int generic_clock_source,
- u64 *period_ps)
-{
- u64 clock_period_ps;
-
- switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
- case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- clock_period_ps = 50000;
- break;
- case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- clock_period_ps = 10000000;
- break;
- case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- clock_period_ps = 12500;
- break;
- case NI_GPCT_PXI10_CLOCK_SRC_BITS:
- clock_period_ps = 100000;
- break;
- default:
- /*
- * clock period is specified by user with prescaling
- * already taken into account.
- */
- *period_ps = counter->clock_period_ps;
- return 0;
- }
-
- switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
- case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
- break;
- case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
- clock_period_ps *= 2;
- break;
- case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
- clock_period_ps *= 8;
- break;
- default:
- return -EINVAL;
- }
- *period_ps = clock_period_ps;
- return 0;
-}
-
-static void ni_tio_set_bits_transient(struct ni_gpct *counter,
- enum ni_gpct_register reg,
- unsigned int mask, unsigned int value,
- unsigned int transient)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int chip = counter->chip_index;
- unsigned long flags;
-
- if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) {
- unsigned int *regs = counter_dev->regs[chip];
-
- spin_lock_irqsave(&counter_dev->regs_lock, flags);
- regs[reg] &= ~mask;
- regs[reg] |= (value & mask);
- ni_tio_write(counter, regs[reg] | transient, reg);
- spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
- }
-}
-
-/**
- * ni_tio_set_bits() - Safely write a counter register.
- * @counter: struct ni_gpct counter.
- * @reg: the register to write.
- * @mask: the bits to change.
- * @value: the new bits value.
- *
- * Used to write to, and update the software copy, a register whose bits may
- * be twiddled in interrupt context, or whose software copy may be read in
- * interrupt context.
- */
-void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register reg,
- unsigned int mask, unsigned int value)
-{
- ni_tio_set_bits_transient(counter, reg, mask, value, 0x0);
-}
-EXPORT_SYMBOL_GPL(ni_tio_set_bits);
-
-/**
- * ni_tio_get_soft_copy() - Safely read the software copy of a counter register.
- * @counter: struct ni_gpct counter.
- * @reg: the register to read.
- *
- * Used to get the software copy of a register whose bits might be modified
- * in interrupt context, or whose software copy might need to be read in
- * interrupt context.
- */
-unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter,
- enum ni_gpct_register reg)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int chip = counter->chip_index;
- unsigned int value = 0;
- unsigned long flags;
-
- if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) {
- spin_lock_irqsave(&counter_dev->regs_lock, flags);
- value = counter_dev->regs[chip][reg];
- spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
- }
- return value;
-}
-EXPORT_SYMBOL_GPL(ni_tio_get_soft_copy);
-
-static unsigned int ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int counting_mode_bits =
- ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx));
- unsigned int bits = 0;
-
- if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
- GI_SRC_POL_INVERT)
- bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
- if (counting_mode_bits & GI_PRESCALE_X2(counter_dev->variant))
- bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
- if (counting_mode_bits & GI_PRESCALE_X8(counter_dev->variant))
- bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
- return bits;
-}
-
-static int ni_m_series_clock_src_select(const struct ni_gpct *counter,
- unsigned int *clk_src)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int chip = counter->chip_index;
- unsigned int second_gate_reg = NITIO_GATE2_REG(cidx);
- unsigned int clock_source = 0;
- unsigned int src;
- unsigned int i;
-
- src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
- NITIO_INPUT_SEL_REG(cidx)));
-
- switch (src) {
- case NI_M_TIMEBASE_1_CLK:
- clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
- break;
- case NI_M_TIMEBASE_2_CLK:
- clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
- break;
- case NI_M_TIMEBASE_3_CLK:
- if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL)
- clock_source =
- NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
- else
- clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
- break;
- case NI_M_LOGIC_LOW_CLK:
- clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
- break;
- case NI_M_NEXT_GATE_CLK:
- if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL)
- clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
- else
- clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
- break;
- case NI_M_PXI10_CLK:
- clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
- break;
- case NI_M_NEXT_TC_CLK:
- clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
- break;
- default:
- for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
- if (src == NI_M_RTSI_CLK(i)) {
- clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= NI_M_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
- if (src == NI_M_PFI_CLK(i)) {
- clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= NI_M_MAX_PFI_CHAN)
- break;
- return -EINVAL;
- }
- clock_source |= ni_tio_clock_src_modifiers(counter);
- *clk_src = clock_source;
- return 0;
-}
-
-static int ni_660x_clock_src_select(const struct ni_gpct *counter,
- unsigned int *clk_src)
-{
- unsigned int clock_source = 0;
- unsigned int cidx = counter->counter_index;
- unsigned int src;
- unsigned int i;
-
- src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
- NITIO_INPUT_SEL_REG(cidx)));
-
- switch (src) {
- case NI_660X_TIMEBASE_1_CLK:
- clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
- break;
- case NI_660X_TIMEBASE_2_CLK:
- clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
- break;
- case NI_660X_TIMEBASE_3_CLK:
- clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
- break;
- case NI_660X_LOGIC_LOW_CLK:
- clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
- break;
- case NI_660X_SRC_PIN_I_CLK:
- clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
- break;
- case NI_660X_NEXT_GATE_CLK:
- clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
- break;
- case NI_660X_NEXT_TC_CLK:
- clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
- break;
- default:
- for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
- if (src == NI_660X_RTSI_CLK(i)) {
- clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
- if (src == NI_660X_SRC_PIN_CLK(i)) {
- clock_source =
- NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_SRC_PIN)
- break;
- return -EINVAL;
- }
- clock_source |= ni_tio_clock_src_modifiers(counter);
- *clk_src = clock_source;
- return 0;
-}
-
-static int ni_tio_generic_clock_src_select(const struct ni_gpct *counter,
- unsigned int *clk_src)
-{
- switch (counter->counter_dev->variant) {
- case ni_gpct_variant_e_series:
- case ni_gpct_variant_m_series:
- default:
- return ni_m_series_clock_src_select(counter, clk_src);
- case ni_gpct_variant_660x:
- return ni_660x_clock_src_select(counter, clk_src);
- }
-}
-
-static void ni_tio_set_sync_mode(struct ni_gpct *counter)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- static const u64 min_normal_sync_period_ps = 25000;
- unsigned int mask = 0;
- unsigned int bits = 0;
- unsigned int reg;
- unsigned int mode;
- unsigned int clk_src = 0;
- u64 ps = 0;
- int ret;
- bool force_alt_sync;
-
- /* only m series and 660x variants have counting mode registers */
- switch (counter_dev->variant) {
- case ni_gpct_variant_e_series:
- default:
- return;
- case ni_gpct_variant_m_series:
- mask = GI_M_ALT_SYNC;
- break;
- case ni_gpct_variant_660x:
- mask = GI_660X_ALT_SYNC;
- break;
- }
-
- reg = NITIO_CNT_MODE_REG(cidx);
- mode = ni_tio_get_soft_copy(counter, reg);
- switch (mode & GI_CNT_MODE_MASK) {
- case GI_CNT_MODE_QUADX1:
- case GI_CNT_MODE_QUADX2:
- case GI_CNT_MODE_QUADX4:
- case GI_CNT_MODE_SYNC_SRC:
- force_alt_sync = true;
- break;
- default:
- force_alt_sync = false;
- break;
- }
-
- ret = ni_tio_generic_clock_src_select(counter, &clk_src);
- if (ret)
- return;
- ret = ni_tio_clock_period_ps(counter, clk_src, &ps);
- if (ret)
- return;
- /*
- * It's not clear what we should do if clock_period is unknown, so we
- * are not using the alt sync bit in that case.
- */
- if (force_alt_sync || (ps && ps < min_normal_sync_period_ps))
- bits = mask;
-
- ni_tio_set_bits(counter, reg, mask, bits);
-}
-
-static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int mode_reg_mask;
- unsigned int mode_reg_values;
- unsigned int input_select_bits = 0;
- /* these bits map directly on to the mode register */
- static const unsigned int mode_reg_direct_mask =
- NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK |
- NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK |
- NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
- NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;
-
- mode_reg_mask = mode_reg_direct_mask | GI_RELOAD_SRC_SWITCHING;
- mode_reg_values = mode & mode_reg_direct_mask;
- switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
- case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
- break;
- case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
- mode_reg_values |= GI_RELOAD_SRC_SWITCHING;
- break;
- case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
- input_select_bits |= GI_GATE_SEL_LOAD_SRC;
- mode_reg_mask |= GI_GATING_MODE_MASK;
- mode_reg_values |= GI_LEVEL_GATING;
- break;
- default:
- break;
- }
- ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
- mode_reg_mask, mode_reg_values);
-
- if (ni_tio_counting_mode_registers_present(counter_dev)) {
- unsigned int bits = 0;
-
- bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT);
- bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT));
- if (mode & NI_GPCT_INDEX_ENABLE_BIT)
- bits |= GI_INDEX_MODE;
- ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK |
- GI_INDEX_MODE, bits);
- ni_tio_set_sync_mode(counter);
- }
-
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK,
- GI_CNT_DIR(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT));
-
- if (mode & NI_GPCT_OR_GATE_BIT)
- input_select_bits |= GI_OR_GATE;
- if (mode & NI_GPCT_INVERT_OUTPUT_BIT)
- input_select_bits |= GI_OUTPUT_POL_INVERT;
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- GI_GATE_SEL_LOAD_SRC | GI_OR_GATE |
- GI_OUTPUT_POL_INVERT, input_select_bits);
-
- return 0;
-}
-
-int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int transient_bits = 0;
-
- if (arm) {
- unsigned int mask = 0;
- unsigned int bits = 0;
-
- /* only m series and 660x have counting mode registers */
- switch (counter_dev->variant) {
- case ni_gpct_variant_e_series:
- default:
- break;
- case ni_gpct_variant_m_series:
- mask = GI_M_HW_ARM_SEL_MASK;
- break;
- case ni_gpct_variant_660x:
- mask = GI_660X_HW_ARM_SEL_MASK;
- break;
- }
-
- switch (start_trigger) {
- case NI_GPCT_ARM_IMMEDIATE:
- transient_bits |= GI_ARM;
- break;
- case NI_GPCT_ARM_PAIRED_IMMEDIATE:
- transient_bits |= GI_ARM | GI_ARM_COPY;
- break;
- default:
- /*
- * for m series and 660x, pass-through the least
- * significant bits so we can figure out what select
- * later
- */
- if (mask && (start_trigger & NI_GPCT_ARM_UNKNOWN)) {
- bits |= GI_HW_ARM_ENA |
- (GI_HW_ARM_SEL(start_trigger) & mask);
- } else {
- return -EINVAL;
- }
- break;
- }
-
- if (mask)
- ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- GI_HW_ARM_ENA | mask, bits);
- } else {
- transient_bits |= GI_DISARM;
- }
- ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
- 0, 0, transient_bits);
- return 0;
-}
-EXPORT_SYMBOL_GPL(ni_tio_arm);
-
-static int ni_660x_clk_src(unsigned int clock_source, unsigned int *bits)
-{
- unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
- unsigned int ni_660x_clock;
- unsigned int i;
-
- switch (clk_src) {
- case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660X_TIMEBASE_1_CLK;
- break;
- case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660X_TIMEBASE_2_CLK;
- break;
- case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660X_TIMEBASE_3_CLK;
- break;
- case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660X_LOGIC_LOW_CLK;
- break;
- case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660X_SRC_PIN_I_CLK;
- break;
- case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660X_NEXT_GATE_CLK;
- break;
- case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660X_NEXT_TC_CLK;
- break;
- default:
- for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
- if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
- ni_660x_clock = NI_660X_RTSI_CLK(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
- if (clk_src == NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
- ni_660x_clock = NI_660X_SRC_PIN_CLK(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_SRC_PIN)
- break;
- return -EINVAL;
- }
- *bits = GI_SRC_SEL(ni_660x_clock);
- return 0;
-}
-
-static int ni_m_clk_src(unsigned int clock_source, unsigned int *bits)
-{
- unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
- unsigned int ni_m_series_clock;
- unsigned int i;
-
- switch (clk_src) {
- case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_TIMEBASE_1_CLK;
- break;
- case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_TIMEBASE_2_CLK;
- break;
- case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_TIMEBASE_3_CLK;
- break;
- case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_LOGIC_LOW_CLK;
- break;
- case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_NEXT_GATE_CLK;
- break;
- case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_NEXT_TC_CLK;
- break;
- case NI_GPCT_PXI10_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_PXI10_CLK;
- break;
- case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_PXI_STAR_TRIGGER_CLK;
- break;
- case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_ANALOG_TRIGGER_OUT_CLK;
- break;
- default:
- for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
- if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
- ni_m_series_clock = NI_M_RTSI_CLK(i);
- break;
- }
- }
- if (i <= NI_M_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
- if (clk_src == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
- ni_m_series_clock = NI_M_PFI_CLK(i);
- break;
- }
- }
- if (i <= NI_M_MAX_PFI_CHAN)
- break;
- return -EINVAL;
- }
- *bits = GI_SRC_SEL(ni_m_series_clock);
- return 0;
-};
-
-static void ni_tio_set_source_subselect(struct ni_gpct *counter,
- unsigned int clock_source)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int chip = counter->chip_index;
- unsigned int second_gate_reg = NITIO_GATE2_REG(cidx);
-
- if (counter_dev->variant != ni_gpct_variant_m_series)
- return;
- switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
- /* Gi_Source_Subselect is zero */
- case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
- case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- counter_dev->regs[chip][second_gate_reg] &= ~GI_SRC_SUBSEL;
- break;
- /* Gi_Source_Subselect is one */
- case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
- case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
- counter_dev->regs[chip][second_gate_reg] |= GI_SRC_SUBSEL;
- break;
- /* Gi_Source_Subselect doesn't matter */
- default:
- return;
- }
- ni_tio_write(counter, counter_dev->regs[chip][second_gate_reg],
- second_gate_reg);
-}
-
-static int ni_tio_set_clock_src(struct ni_gpct *counter,
- unsigned int clock_source,
- unsigned int period_ns)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int bits = 0;
- int ret;
-
- switch (counter_dev->variant) {
- case ni_gpct_variant_660x:
- ret = ni_660x_clk_src(clock_source, &bits);
- break;
- case ni_gpct_variant_e_series:
- case ni_gpct_variant_m_series:
- default:
- ret = ni_m_clk_src(clock_source, &bits);
- break;
- }
- if (ret) {
- struct comedi_device *dev = counter_dev->dev;
-
- dev_err(dev->class_dev, "invalid clock source 0x%x\n",
- clock_source);
- return ret;
- }
-
- if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
- bits |= GI_SRC_POL_INVERT;
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- GI_SRC_SEL_MASK | GI_SRC_POL_INVERT, bits);
- ni_tio_set_source_subselect(counter, clock_source);
-
- if (ni_tio_counting_mode_registers_present(counter_dev)) {
- bits = 0;
- switch (clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
- case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
- break;
- case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
- bits |= GI_PRESCALE_X2(counter_dev->variant);
- break;
- case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
- bits |= GI_PRESCALE_X8(counter_dev->variant);
- break;
- default:
- return -EINVAL;
- }
- ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- GI_PRESCALE_X2(counter_dev->variant) |
- GI_PRESCALE_X8(counter_dev->variant), bits);
- }
- counter->clock_period_ps = period_ns * 1000;
- ni_tio_set_sync_mode(counter);
- return 0;
-}
-
-static int ni_tio_get_clock_src(struct ni_gpct *counter,
- unsigned int *clock_source,
- unsigned int *period_ns)
-{
- u64 temp64 = 0;
- int ret;
-
- ret = ni_tio_generic_clock_src_select(counter, clock_source);
- if (ret)
- return ret;
- ret = ni_tio_clock_period_ps(counter, *clock_source, &temp64);
- if (ret)
- return ret;
- do_div(temp64, 1000); /* ps to ns */
- *period_ns = temp64;
- return 0;
-}
-
-static inline void ni_tio_set_gate_raw(struct ni_gpct *counter,
- unsigned int gate_source)
-{
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(counter->counter_index),
- GI_GATE_SEL_MASK, GI_GATE_SEL(gate_source));
-}
-
-static inline void ni_tio_set_gate2_raw(struct ni_gpct *counter,
- unsigned int gate_source)
-{
- ni_tio_set_bits(counter, NITIO_GATE2_REG(counter->counter_index),
- GI_GATE2_SEL_MASK, GI_GATE2_SEL(gate_source));
-}
-
-/* Set the mode bits for gate. */
-static inline void ni_tio_set_gate_mode(struct ni_gpct *counter,
- unsigned int src)
-{
- unsigned int mode_bits = 0;
-
- if (CR_CHAN(src) & NI_GPCT_DISABLED_GATE_SELECT) {
- /*
- * Allowing bitwise comparison here to allow non-zero raw
- * register value to be used for channel when disabling.
- */
- mode_bits = GI_GATING_DISABLED;
- } else {
- if (src & CR_INVERT)
- mode_bits |= GI_GATE_POL_INVERT;
- if (src & CR_EDGE)
- mode_bits |= GI_RISING_EDGE_GATING;
- else
- mode_bits |= GI_LEVEL_GATING;
- }
- ni_tio_set_bits(counter, NITIO_MODE_REG(counter->counter_index),
- GI_GATE_POL_INVERT | GI_GATING_MODE_MASK,
- mode_bits);
-}
-
-/*
- * Set the mode bits for gate2.
- *
- * Previously, the code this function represents did not actually write anything
- * to the register. Rather, writing to this register was reserved for the code
- * ni ni_tio_set_gate2_raw.
- */
-static inline void ni_tio_set_gate2_mode(struct ni_gpct *counter,
- unsigned int src)
-{
- /*
- * The GI_GATE2_MODE bit was previously set in the code that also sets
- * the gate2 source.
- * We'll set mode bits _after_ source bits now, and thus, this function
- * will effectively enable the second gate after all bits are set.
- */
- unsigned int mode_bits = GI_GATE2_MODE;
-
- if (CR_CHAN(src) & NI_GPCT_DISABLED_GATE_SELECT)
- /*
- * Allowing bitwise comparison here to allow non-zero raw
- * register value to be used for channel when disabling.
- */
- mode_bits = GI_GATING_DISABLED;
- if (src & CR_INVERT)
- mode_bits |= GI_GATE2_POL_INVERT;
-
- ni_tio_set_bits(counter, NITIO_GATE2_REG(counter->counter_index),
- GI_GATE2_POL_INVERT | GI_GATE2_MODE, mode_bits);
-}
-
-static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
-{
- unsigned int chan = CR_CHAN(gate_source);
- unsigned int gate_sel;
- unsigned int i;
-
- switch (chan) {
- case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
- gate_sel = NI_660X_NEXT_SRC_GATE_SEL;
- break;
- case NI_GPCT_NEXT_OUT_GATE_SELECT:
- case NI_GPCT_LOGIC_LOW_GATE_SELECT:
- case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
- case NI_GPCT_GATE_PIN_i_GATE_SELECT:
- gate_sel = chan & 0x1f;
- break;
- default:
- for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
- if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
- gate_sel = chan & 0x1f;
- break;
- }
- }
- if (i <= NI_660X_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
- if (chan == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
- gate_sel = chan & 0x1f;
- break;
- }
- }
- if (i <= NI_660X_MAX_GATE_PIN)
- break;
- return -EINVAL;
- }
- ni_tio_set_gate_raw(counter, gate_sel);
- return 0;
-}
-
-static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
-{
- unsigned int chan = CR_CHAN(gate_source);
- unsigned int gate_sel;
- unsigned int i;
-
- switch (chan) {
- case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
- case NI_GPCT_AI_START2_GATE_SELECT:
- case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
- case NI_GPCT_NEXT_OUT_GATE_SELECT:
- case NI_GPCT_AI_START1_GATE_SELECT:
- case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
- case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
- case NI_GPCT_LOGIC_LOW_GATE_SELECT:
- gate_sel = chan & 0x1f;
- break;
- default:
- for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
- if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
- gate_sel = chan & 0x1f;
- break;
- }
- }
- if (i <= NI_M_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
- if (chan == NI_GPCT_PFI_GATE_SELECT(i)) {
- gate_sel = chan & 0x1f;
- break;
- }
- }
- if (i <= NI_M_MAX_PFI_CHAN)
- break;
- return -EINVAL;
- }
- ni_tio_set_gate_raw(counter, gate_sel);
- return 0;
-}
-
-static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
-{
- unsigned int chan = CR_CHAN(gate_source);
- unsigned int gate2_sel;
- unsigned int i;
-
- switch (chan) {
- case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
- case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
- case NI_GPCT_SELECTED_GATE_GATE_SELECT:
- case NI_GPCT_NEXT_OUT_GATE_SELECT:
- case NI_GPCT_LOGIC_LOW_GATE_SELECT:
- gate2_sel = chan & 0x1f;
- break;
- case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
- gate2_sel = NI_660X_NEXT_SRC_GATE2_SEL;
- break;
- default:
- for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
- if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
- gate2_sel = chan & 0x1f;
- break;
- }
- }
- if (i <= NI_660X_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
- if (chan == NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
- gate2_sel = chan & 0x1f;
- break;
- }
- }
- if (i <= NI_660X_MAX_UP_DOWN_PIN)
- break;
- return -EINVAL;
- }
- ni_tio_set_gate2_raw(counter, gate2_sel);
- return 0;
-}
-
-static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
-{
- /*
- * FIXME: We don't know what the m-series second gate codes are,
- * so we'll just pass the bits through for now.
- */
- ni_tio_set_gate2_raw(counter, gate_source);
- return 0;
-}
-
-int ni_tio_set_gate_src_raw(struct ni_gpct *counter,
- unsigned int gate, unsigned int src)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
-
- switch (gate) {
- case 0:
- /* 1. start by disabling gate */
- ni_tio_set_gate_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
- /* 2. set the requested gate source */
- ni_tio_set_gate_raw(counter, src);
- /* 3. reenable & set mode to starts things back up */
- ni_tio_set_gate_mode(counter, src);
- break;
- case 1:
- if (!ni_tio_has_gate2_registers(counter_dev))
- return -EINVAL;
-
- /* 1. start by disabling gate */
- ni_tio_set_gate2_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
- /* 2. set the requested gate source */
- ni_tio_set_gate2_raw(counter, src);
- /* 3. reenable & set mode to starts things back up */
- ni_tio_set_gate2_mode(counter, src);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(ni_tio_set_gate_src_raw);
-
-int ni_tio_set_gate_src(struct ni_gpct *counter,
- unsigned int gate, unsigned int src)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- /*
- * mask off disable flag. This high bit still passes CR_CHAN.
- * Doing this allows one to both set the gate as disabled, but also
- * change the route value of the gate.
- */
- int chan = CR_CHAN(src) & (~NI_GPCT_DISABLED_GATE_SELECT);
- int ret;
-
- switch (gate) {
- case 0:
- /* 1. start by disabling gate */
- ni_tio_set_gate_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
- /* 2. set the requested gate source */
- switch (counter_dev->variant) {
- case ni_gpct_variant_e_series:
- case ni_gpct_variant_m_series:
- ret = ni_m_set_gate(counter, chan);
- break;
- case ni_gpct_variant_660x:
- ret = ni_660x_set_gate(counter, chan);
- break;
- default:
- return -EINVAL;
- }
- if (ret)
- return ret;
- /* 3. reenable & set mode to starts things back up */
- ni_tio_set_gate_mode(counter, src);
- break;
- case 1:
- if (!ni_tio_has_gate2_registers(counter_dev))
- return -EINVAL;
-
- /* 1. start by disabling gate */
- ni_tio_set_gate2_mode(counter, NI_GPCT_DISABLED_GATE_SELECT);
- /* 2. set the requested gate source */
- switch (counter_dev->variant) {
- case ni_gpct_variant_m_series:
- ret = ni_m_set_gate2(counter, chan);
- break;
- case ni_gpct_variant_660x:
- ret = ni_660x_set_gate2(counter, chan);
- break;
- default:
- return -EINVAL;
- }
- if (ret)
- return ret;
- /* 3. reenable & set mode to starts things back up */
- ni_tio_set_gate2_mode(counter, src);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);
-
-static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index,
- unsigned int source)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int chip = counter->chip_index;
- unsigned int abz_reg, shift, mask;
-
- if (counter_dev->variant != ni_gpct_variant_m_series)
- return -EINVAL;
-
- abz_reg = NITIO_ABZ_REG(cidx);
-
- /* allow for new device-global names */
- if (index == NI_GPCT_SOURCE_ENCODER_A ||
- (index >= NI_CtrA(0) && index <= NI_CtrA(-1))) {
- shift = 10;
- } else if (index == NI_GPCT_SOURCE_ENCODER_B ||
- (index >= NI_CtrB(0) && index <= NI_CtrB(-1))) {
- shift = 5;
- } else if (index == NI_GPCT_SOURCE_ENCODER_Z ||
- (index >= NI_CtrZ(0) && index <= NI_CtrZ(-1))) {
- shift = 0;
- } else {
- return -EINVAL;
- }
-
- mask = 0x1f << shift;
- if (source > 0x1f)
- source = 0x1f; /* Disable gate */
-
- counter_dev->regs[chip][abz_reg] &= ~mask;
- counter_dev->regs[chip][abz_reg] |= (source << shift) & mask;
- ni_tio_write(counter, counter_dev->regs[chip][abz_reg], abz_reg);
- return 0;
-}
-
-static int ni_tio_get_other_src(struct ni_gpct *counter, unsigned int index,
- unsigned int *source)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int abz_reg, shift, mask;
-
- if (counter_dev->variant != ni_gpct_variant_m_series)
- /* A,B,Z only valid for m-series */
- return -EINVAL;
-
- abz_reg = NITIO_ABZ_REG(cidx);
-
- /* allow for new device-global names */
- if (index == NI_GPCT_SOURCE_ENCODER_A ||
- (index >= NI_CtrA(0) && index <= NI_CtrA(-1))) {
- shift = 10;
- } else if (index == NI_GPCT_SOURCE_ENCODER_B ||
- (index >= NI_CtrB(0) && index <= NI_CtrB(-1))) {
- shift = 5;
- } else if (index == NI_GPCT_SOURCE_ENCODER_Z ||
- (index >= NI_CtrZ(0) && index <= NI_CtrZ(-1))) {
- shift = 0;
- } else {
- return -EINVAL;
- }
-
- mask = 0x1f;
-
- *source = (ni_tio_get_soft_copy(counter, abz_reg) >> shift) & mask;
- return 0;
-}
-
-static int ni_660x_gate_to_generic_gate(unsigned int gate, unsigned int *src)
-{
- unsigned int source;
- unsigned int i;
-
- switch (gate) {
- case NI_660X_SRC_PIN_I_GATE_SEL:
- source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
- break;
- case NI_660X_GATE_PIN_I_GATE_SEL:
- source = NI_GPCT_GATE_PIN_i_GATE_SELECT;
- break;
- case NI_660X_NEXT_SRC_GATE_SEL:
- source = NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_660X_NEXT_OUT_GATE_SEL:
- source = NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_660X_LOGIC_LOW_GATE_SEL:
- source = NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
- default:
- for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
- if (gate == NI_660X_RTSI_GATE_SEL(i)) {
- source = NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
- if (gate == NI_660X_PIN_GATE_SEL(i)) {
- source = NI_GPCT_GATE_PIN_GATE_SELECT(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_GATE_PIN)
- break;
- return -EINVAL;
- }
- *src = source;
- return 0;
-}
-
-static int ni_m_gate_to_generic_gate(unsigned int gate, unsigned int *src)
-{
- unsigned int source;
- unsigned int i;
-
- switch (gate) {
- case NI_M_TIMESTAMP_MUX_GATE_SEL:
- source = NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
- break;
- case NI_M_AI_START2_GATE_SEL:
- source = NI_GPCT_AI_START2_GATE_SELECT;
- break;
- case NI_M_PXI_STAR_TRIGGER_GATE_SEL:
- source = NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
- break;
- case NI_M_NEXT_OUT_GATE_SEL:
- source = NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_M_AI_START1_GATE_SEL:
- source = NI_GPCT_AI_START1_GATE_SELECT;
- break;
- case NI_M_NEXT_SRC_GATE_SEL:
- source = NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_M_ANALOG_TRIG_OUT_GATE_SEL:
- source = NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
- break;
- case NI_M_LOGIC_LOW_GATE_SEL:
- source = NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
- default:
- for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
- if (gate == NI_M_RTSI_GATE_SEL(i)) {
- source = NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
- }
- if (i <= NI_M_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
- if (gate == NI_M_PFI_GATE_SEL(i)) {
- source = NI_GPCT_PFI_GATE_SELECT(i);
- break;
- }
- }
- if (i <= NI_M_MAX_PFI_CHAN)
- break;
- return -EINVAL;
- }
- *src = source;
- return 0;
-}
-
-static int ni_660x_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
-{
- unsigned int source;
- unsigned int i;
-
- switch (gate) {
- case NI_660X_SRC_PIN_I_GATE2_SEL:
- source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
- break;
- case NI_660X_UD_PIN_I_GATE2_SEL:
- source = NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
- break;
- case NI_660X_NEXT_SRC_GATE2_SEL:
- source = NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_660X_NEXT_OUT_GATE2_SEL:
- source = NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_660X_SELECTED_GATE2_SEL:
- source = NI_GPCT_SELECTED_GATE_GATE_SELECT;
- break;
- case NI_660X_LOGIC_LOW_GATE2_SEL:
- source = NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
- default:
- for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
- if (gate == NI_660X_RTSI_GATE2_SEL(i)) {
- source = NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_RTSI_CHAN)
- break;
- for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
- if (gate == NI_660X_UD_PIN_GATE2_SEL(i)) {
- source = NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
- break;
- }
- }
- if (i <= NI_660X_MAX_UP_DOWN_PIN)
- break;
- return -EINVAL;
- }
- *src = source;
- return 0;
-}
-
-static int ni_m_gate2_to_generic_gate(unsigned int gate, unsigned int *src)
-{
- /*
- * FIXME: the second gate sources for the m series are undocumented,
- * so we just return the raw bits for now.
- */
- *src = gate;
- return 0;
-}
-
-static inline unsigned int ni_tio_get_gate_mode(struct ni_gpct *counter)
-{
- unsigned int mode = ni_tio_get_soft_copy(counter,
- NITIO_MODE_REG(counter->counter_index));
- unsigned int ret = 0;
-
- if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED)
- ret |= NI_GPCT_DISABLED_GATE_SELECT;
- if (mode & GI_GATE_POL_INVERT)
- ret |= CR_INVERT;
- if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
- ret |= CR_EDGE;
-
- return ret;
-}
-
-static inline unsigned int ni_tio_get_gate2_mode(struct ni_gpct *counter)
-{
- unsigned int mode = ni_tio_get_soft_copy(counter,
- NITIO_GATE2_REG(counter->counter_index));
- unsigned int ret = 0;
-
- if (!(mode & GI_GATE2_MODE))
- ret |= NI_GPCT_DISABLED_GATE_SELECT;
- if (mode & GI_GATE2_POL_INVERT)
- ret |= CR_INVERT;
-
- return ret;
-}
-
-static inline unsigned int ni_tio_get_gate_val(struct ni_gpct *counter)
-{
- return GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter,
- NITIO_INPUT_SEL_REG(counter->counter_index)));
-}
-
-static inline unsigned int ni_tio_get_gate2_val(struct ni_gpct *counter)
-{
- return GI_BITS_TO_GATE2(ni_tio_get_soft_copy(counter,
- NITIO_GATE2_REG(counter->counter_index)));
-}
-
-static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index,
- unsigned int *gate_source)
-{
- unsigned int gate;
- int ret;
-
- switch (gate_index) {
- case 0:
- gate = ni_tio_get_gate_val(counter);
- switch (counter->counter_dev->variant) {
- case ni_gpct_variant_e_series:
- case ni_gpct_variant_m_series:
- default:
- ret = ni_m_gate_to_generic_gate(gate, gate_source);
- break;
- case ni_gpct_variant_660x:
- ret = ni_660x_gate_to_generic_gate(gate, gate_source);
- break;
- }
- if (ret)
- return ret;
- *gate_source |= ni_tio_get_gate_mode(counter);
- break;
- case 1:
- gate = ni_tio_get_gate2_val(counter);
- switch (counter->counter_dev->variant) {
- case ni_gpct_variant_e_series:
- case ni_gpct_variant_m_series:
- default:
- ret = ni_m_gate2_to_generic_gate(gate, gate_source);
- break;
- case ni_gpct_variant_660x:
- ret = ni_660x_gate2_to_generic_gate(gate, gate_source);
- break;
- }
- if (ret)
- return ret;
- *gate_source |= ni_tio_get_gate2_mode(counter);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int ni_tio_get_gate_src_raw(struct ni_gpct *counter,
- unsigned int gate_index,
- unsigned int *gate_source)
-{
- switch (gate_index) {
- case 0:
- *gate_source = ni_tio_get_gate_mode(counter)
- | ni_tio_get_gate_val(counter);
- break;
- case 1:
- *gate_source = ni_tio_get_gate2_mode(counter)
- | ni_tio_get_gate2_val(counter);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-int ni_tio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_gpct *counter = s->private;
- unsigned int cidx = counter->counter_index;
- unsigned int status;
- int ret = 0;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_COUNTER_MODE:
- ret = ni_tio_set_counter_mode(counter, data[1]);
- break;
- case INSN_CONFIG_ARM:
- ret = ni_tio_arm(counter, true, data[1]);
- break;
- case INSN_CONFIG_DISARM:
- ret = ni_tio_arm(counter, false, 0);
- break;
- case INSN_CONFIG_GET_COUNTER_STATUS:
- data[1] = 0;
- status = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx));
- if (status & GI_ARMED(cidx)) {
- data[1] |= COMEDI_COUNTER_ARMED;
- if (status & GI_COUNTING(cidx))
- data[1] |= COMEDI_COUNTER_COUNTING;
- }
- data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
- break;
- case INSN_CONFIG_SET_CLOCK_SRC:
- ret = ni_tio_set_clock_src(counter, data[1], data[2]);
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- ret = ni_tio_get_clock_src(counter, &data[1], &data[2]);
- break;
- case INSN_CONFIG_SET_GATE_SRC:
- ret = ni_tio_set_gate_src(counter, data[1], data[2]);
- break;
- case INSN_CONFIG_GET_GATE_SRC:
- ret = ni_tio_get_gate_src(counter, data[1], &data[2]);
- break;
- case INSN_CONFIG_SET_OTHER_SRC:
- ret = ni_tio_set_other_src(counter, data[1], data[2]);
- break;
- case INSN_CONFIG_RESET:
- ni_tio_reset_count_and_disarm(counter);
- break;
- default:
- return -EINVAL;
- }
- return ret ? ret : insn->n;
-}
-EXPORT_SYMBOL_GPL(ni_tio_insn_config);
-
-/**
- * Retrieves the register value of the current source of the output selector for
- * the given destination.
- *
- * If the terminal for the destination is not already configured as an output,
- * this function returns -EINVAL as error.
- *
- * Return: the register value of the destination output selector;
- * -EINVAL if terminal is not configured for output.
- */
-int ni_tio_get_routing(struct ni_gpct_device *counter_dev, unsigned int dest)
-{
- /* we need to know the actual counter below... */
- int ctr_index = (dest - NI_COUNTER_NAMES_BASE) % NI_MAX_COUNTERS;
- struct ni_gpct *counter = &counter_dev->counters[ctr_index];
- int ret = 1;
- unsigned int reg;
-
- if (dest >= NI_CtrA(0) && dest <= NI_CtrZ(-1)) {
- ret = ni_tio_get_other_src(counter, dest, &reg);
- } else if (dest >= NI_CtrGate(0) && dest <= NI_CtrGate(-1)) {
- ret = ni_tio_get_gate_src_raw(counter, 0, &reg);
- } else if (dest >= NI_CtrAux(0) && dest <= NI_CtrAux(-1)) {
- ret = ni_tio_get_gate_src_raw(counter, 1, &reg);
- /*
- * This case is not possible through this interface. A user must use
- * INSN_CONFIG_SET_CLOCK_SRC instead.
- * } else if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1)) {
- * ret = ni_tio_set_clock_src(counter, &reg, &period_ns);
- */
- }
-
- if (ret)
- return -EINVAL;
-
- return reg;
-}
-EXPORT_SYMBOL_GPL(ni_tio_get_routing);
-
-/**
- * Sets the register value of the selector MUX for the given destination.
- * @counter_dev:Pointer to general counter device.
- * @destination:Device-global identifier of route destination.
- * @register_value:
- * The first several bits of this value should store the desired
- * value to write to the register. All other bits are for
- * transmitting information that modify the mode of the particular
- * destination/gate. These mode bits might include a bitwise or of
- * CR_INVERT and CR_EDGE. Note that the calling function should
- * have already validated the correctness of this value.
- */
-int ni_tio_set_routing(struct ni_gpct_device *counter_dev, unsigned int dest,
- unsigned int reg)
-{
- /* we need to know the actual counter below... */
- int ctr_index = (dest - NI_COUNTER_NAMES_BASE) % NI_MAX_COUNTERS;
- struct ni_gpct *counter = &counter_dev->counters[ctr_index];
- int ret;
-
- if (dest >= NI_CtrA(0) && dest <= NI_CtrZ(-1)) {
- ret = ni_tio_set_other_src(counter, dest, reg);
- } else if (dest >= NI_CtrGate(0) && dest <= NI_CtrGate(-1)) {
- ret = ni_tio_set_gate_src_raw(counter, 0, reg);
- } else if (dest >= NI_CtrAux(0) && dest <= NI_CtrAux(-1)) {
- ret = ni_tio_set_gate_src_raw(counter, 1, reg);
- /*
- * This case is not possible through this interface. A user must use
- * INSN_CONFIG_SET_CLOCK_SRC instead.
- * } else if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1)) {
- * ret = ni_tio_set_clock_src(counter, reg, period_ns);
- */
- } else {
- return -EINVAL;
- }
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(ni_tio_set_routing);
-
-/**
- * Sets the given destination MUX to its default value or disable it.
- *
- * Return: 0 if successful; -EINVAL if terminal is unknown.
- */
-int ni_tio_unset_routing(struct ni_gpct_device *counter_dev, unsigned int dest)
-{
- if (dest >= NI_GATES_NAMES_BASE && dest <= NI_GATES_NAMES_MAX)
- /* Disable gate (via mode bits) and set to default 0-value */
- return ni_tio_set_routing(counter_dev, dest,
- NI_GPCT_DISABLED_GATE_SELECT);
- /*
- * This case is not possible through this interface. A user must use
- * INSN_CONFIG_SET_CLOCK_SRC instead.
- * if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1))
- * return ni_tio_set_clock_src(counter, reg, period_ns);
- */
-
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(ni_tio_unset_routing);
-
-static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
- unsigned int cidx = counter->counter_index;
- unsigned int val;
-
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- GI_SAVE_TRACE, GI_SAVE_TRACE);
-
- /*
- * The count doesn't get latched until the next clock edge, so it is
- * possible the count may change (once) while we are reading. Since
- * the read of the SW_Save_Reg isn't atomic (apparently even when it's
- * a 32 bit register according to 660x docs), we need to read twice
- * and make sure the reading hasn't changed. If it has, a third read
- * will be correct since the count value will definitely have latched
- * by then.
- */
- val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx));
- if (val != ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx)))
- val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx));
-
- return val;
-}
-
-int ni_tio_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_gpct *counter = s->private;
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int channel = CR_CHAN(insn->chanspec);
- unsigned int cidx = counter->counter_index;
- unsigned int chip = counter->chip_index;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- switch (channel) {
- case 0:
- data[i] = ni_tio_read_sw_save_reg(dev, s);
- break;
- case 1:
- data[i] =
- counter_dev->regs[chip][NITIO_LOADA_REG(cidx)];
- break;
- case 2:
- data[i] =
- counter_dev->regs[chip][NITIO_LOADB_REG(cidx)];
- break;
- }
- }
- return insn->n;
-}
-EXPORT_SYMBOL_GPL(ni_tio_insn_read);
-
-static unsigned int ni_tio_next_load_register(struct ni_gpct *counter)
-{
- unsigned int cidx = counter->counter_index;
- unsigned int bits = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx));
-
- return (bits & GI_NEXT_LOAD_SRC(cidx))
- ? NITIO_LOADB_REG(cidx)
- : NITIO_LOADA_REG(cidx);
-}
-
-int ni_tio_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_gpct *counter = s->private;
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int channel = CR_CHAN(insn->chanspec);
- unsigned int cidx = counter->counter_index;
- unsigned int chip = counter->chip_index;
- unsigned int load_reg;
- unsigned int load_val;
-
- if (insn->n < 1)
- return 0;
- load_val = data[insn->n - 1];
- switch (channel) {
- case 0:
- /*
- * Unsafe if counter is armed.
- * Should probably check status and return -EBUSY if armed.
- */
-
- /*
- * Don't disturb load source select, just use whichever
- * load register is already selected.
- */
- load_reg = ni_tio_next_load_register(counter);
- ni_tio_write(counter, load_val, load_reg);
- ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
- 0, 0, GI_LOAD);
- /* restore load reg */
- ni_tio_write(counter, counter_dev->regs[chip][load_reg],
- load_reg);
- break;
- case 1:
- counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = load_val;
- ni_tio_write(counter, load_val, NITIO_LOADA_REG(cidx));
- break;
- case 2:
- counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = load_val;
- ni_tio_write(counter, load_val, NITIO_LOADB_REG(cidx));
- break;
- default:
- return -EINVAL;
- }
- return insn->n;
-}
-EXPORT_SYMBOL_GPL(ni_tio_insn_write);
-
-void ni_tio_init_counter(struct ni_gpct *counter)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int chip = counter->chip_index;
-
- ni_tio_reset_count_and_disarm(counter);
-
- /* initialize counter registers */
- counter_dev->regs[chip][NITIO_AUTO_INC_REG(cidx)] = 0x0;
- ni_tio_write(counter, 0x0, NITIO_AUTO_INC_REG(cidx));
-
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- ~0, GI_SYNC_GATE);
-
- ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0);
-
- counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = 0x0;
- ni_tio_write(counter, 0x0, NITIO_LOADA_REG(cidx));
-
- counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = 0x0;
- ni_tio_write(counter, 0x0, NITIO_LOADB_REG(cidx));
-
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0);
-
- if (ni_tio_counting_mode_registers_present(counter_dev))
- ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0);
-
- if (ni_tio_has_gate2_registers(counter_dev)) {
- counter_dev->regs[chip][NITIO_GATE2_REG(cidx)] = 0x0;
- ni_tio_write(counter, 0x0, NITIO_GATE2_REG(cidx));
- }
-
- ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0);
-
- ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0);
-}
-EXPORT_SYMBOL_GPL(ni_tio_init_counter);
-
-struct ni_gpct_device *
-ni_gpct_device_construct(struct comedi_device *dev,
- void (*write)(struct ni_gpct *counter,
- unsigned int value,
- enum ni_gpct_register reg),
- unsigned int (*read)(struct ni_gpct *counter,
- enum ni_gpct_register reg),
- enum ni_gpct_variant variant,
- unsigned int num_counters,
- unsigned int counters_per_chip,
- const struct ni_route_tables *routing_tables)
-{
- struct ni_gpct_device *counter_dev;
- struct ni_gpct *counter;
- unsigned int i;
-
- if (num_counters == 0 || counters_per_chip == 0)
- return NULL;
-
- counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL);
- if (!counter_dev)
- return NULL;
-
- counter_dev->dev = dev;
- counter_dev->write = write;
- counter_dev->read = read;
- counter_dev->variant = variant;
- counter_dev->routing_tables = routing_tables;
-
- spin_lock_init(&counter_dev->regs_lock);
-
- counter_dev->num_counters = num_counters;
- counter_dev->num_chips = DIV_ROUND_UP(num_counters, counters_per_chip);
-
- counter_dev->counters = kcalloc(num_counters, sizeof(*counter),
- GFP_KERNEL);
- counter_dev->regs = kcalloc(counter_dev->num_chips,
- sizeof(*counter_dev->regs), GFP_KERNEL);
- if (!counter_dev->regs || !counter_dev->counters) {
- kfree(counter_dev->regs);
- kfree(counter_dev->counters);
- kfree(counter_dev);
- return NULL;
- }
-
- for (i = 0; i < num_counters; ++i) {
- counter = &counter_dev->counters[i];
- counter->counter_dev = counter_dev;
- counter->chip_index = i / counters_per_chip;
- counter->counter_index = i % counters_per_chip;
- spin_lock_init(&counter->lock);
- }
-
- return counter_dev;
-}
-EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
-
-void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
-{
- if (!counter_dev)
- return;
- kfree(counter_dev->regs);
- kfree(counter_dev->counters);
- kfree(counter_dev);
-}
-EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
-
-static int __init ni_tio_init_module(void)
-{
- return 0;
-}
-module_init(ni_tio_init_module);
-
-static void __exit ni_tio_cleanup_module(void)
-{
-}
-module_exit(ni_tio_cleanup_module);
-
-MODULE_AUTHOR("Comedi <comedi@comedi.org>");
-MODULE_DESCRIPTION("Comedi support for NI general-purpose counters");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
deleted file mode 100644
index e7b05718df9b..000000000000
--- a/drivers/staging/comedi/drivers/ni_tio.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Header file for NI general purpose counter support code (ni_tio.c)
- *
- * COMEDI - Linux Control and Measurement Device Interface
- */
-
-#ifndef _COMEDI_NI_TIO_H
-#define _COMEDI_NI_TIO_H
-
-#include "../comedidev.h"
-
-enum ni_gpct_register {
- NITIO_G0_AUTO_INC,
- NITIO_G1_AUTO_INC,
- NITIO_G2_AUTO_INC,
- NITIO_G3_AUTO_INC,
- NITIO_G0_CMD,
- NITIO_G1_CMD,
- NITIO_G2_CMD,
- NITIO_G3_CMD,
- NITIO_G0_HW_SAVE,
- NITIO_G1_HW_SAVE,
- NITIO_G2_HW_SAVE,
- NITIO_G3_HW_SAVE,
- NITIO_G0_SW_SAVE,
- NITIO_G1_SW_SAVE,
- NITIO_G2_SW_SAVE,
- NITIO_G3_SW_SAVE,
- NITIO_G0_MODE,
- NITIO_G1_MODE,
- NITIO_G2_MODE,
- NITIO_G3_MODE,
- NITIO_G0_LOADA,
- NITIO_G1_LOADA,
- NITIO_G2_LOADA,
- NITIO_G3_LOADA,
- NITIO_G0_LOADB,
- NITIO_G1_LOADB,
- NITIO_G2_LOADB,
- NITIO_G3_LOADB,
- NITIO_G0_INPUT_SEL,
- NITIO_G1_INPUT_SEL,
- NITIO_G2_INPUT_SEL,
- NITIO_G3_INPUT_SEL,
- NITIO_G0_CNT_MODE,
- NITIO_G1_CNT_MODE,
- NITIO_G2_CNT_MODE,
- NITIO_G3_CNT_MODE,
- NITIO_G0_GATE2,
- NITIO_G1_GATE2,
- NITIO_G2_GATE2,
- NITIO_G3_GATE2,
- NITIO_G01_STATUS,
- NITIO_G23_STATUS,
- NITIO_G01_RESET,
- NITIO_G23_RESET,
- NITIO_G01_STATUS1,
- NITIO_G23_STATUS1,
- NITIO_G01_STATUS2,
- NITIO_G23_STATUS2,
- NITIO_G0_DMA_CFG,
- NITIO_G1_DMA_CFG,
- NITIO_G2_DMA_CFG,
- NITIO_G3_DMA_CFG,
- NITIO_G0_DMA_STATUS,
- NITIO_G1_DMA_STATUS,
- NITIO_G2_DMA_STATUS,
- NITIO_G3_DMA_STATUS,
- NITIO_G0_ABZ,
- NITIO_G1_ABZ,
- NITIO_G0_INT_ACK,
- NITIO_G1_INT_ACK,
- NITIO_G2_INT_ACK,
- NITIO_G3_INT_ACK,
- NITIO_G0_STATUS,
- NITIO_G1_STATUS,
- NITIO_G2_STATUS,
- NITIO_G3_STATUS,
- NITIO_G0_INT_ENA,
- NITIO_G1_INT_ENA,
- NITIO_G2_INT_ENA,
- NITIO_G3_INT_ENA,
- NITIO_NUM_REGS,
-};
-
-enum ni_gpct_variant {
- ni_gpct_variant_e_series,
- ni_gpct_variant_m_series,
- ni_gpct_variant_660x
-};
-
-struct ni_gpct {
- struct ni_gpct_device *counter_dev;
- unsigned int counter_index;
- unsigned int chip_index;
- u64 clock_period_ps; /* clock period in picoseconds */
- struct mite_channel *mite_chan;
- spinlock_t lock; /* protects 'mite_chan' */
-};
-
-struct ni_gpct_device {
- struct comedi_device *dev;
- void (*write)(struct ni_gpct *counter, unsigned int value,
- enum ni_gpct_register);
- unsigned int (*read)(struct ni_gpct *counter, enum ni_gpct_register);
- enum ni_gpct_variant variant;
- struct ni_gpct *counters;
- unsigned int num_counters;
- unsigned int num_chips;
- unsigned int (*regs)[NITIO_NUM_REGS]; /* [num_chips][NITIO_NUM_REGS] */
- spinlock_t regs_lock; /* protects 'regs' */
- const struct ni_route_tables *routing_tables; /* link to routes */
-};
-
-struct ni_gpct_device *
-ni_gpct_device_construct(struct comedi_device *dev,
- void (*write)(struct ni_gpct *counter,
- unsigned int value,
- enum ni_gpct_register),
- unsigned int (*read)(struct ni_gpct *counter,
- enum ni_gpct_register),
- enum ni_gpct_variant,
- unsigned int num_counters,
- unsigned int counters_per_chip,
- const struct ni_route_tables *routing_tables);
-void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev);
-void ni_tio_init_counter(struct ni_gpct *counter);
-int ni_tio_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int ni_tio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int ni_tio_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-int ni_tio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-int ni_tio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-int ni_tio_cancel(struct ni_gpct *counter);
-void ni_tio_handle_interrupt(struct ni_gpct *counter,
- struct comedi_subdevice *s);
-void ni_tio_set_mite_channel(struct ni_gpct *counter,
- struct mite_channel *mite_chan);
-void ni_tio_acknowledge(struct ni_gpct *counter);
-
-/*
- * Retrieves the register value of the current source of the output selector for
- * the given destination.
- *
- * If the terminal for the destination is not already configured as an output,
- * this function returns -EINVAL as error.
- *
- * Return: the register value of the destination output selector;
- * -EINVAL if terminal is not configured for output.
- */
-int ni_tio_get_routing(struct ni_gpct_device *counter_dev,
- unsigned int destination);
-
-/*
- * Sets the register value of the selector MUX for the given destination.
- * @counter_dev:Pointer to general counter device.
- * @destination:Device-global identifier of route destination.
- * @register_value:
- * The first several bits of this value should store the desired
- * value to write to the register. All other bits are for
- * transmitting information that modify the mode of the particular
- * destination/gate. These mode bits might include a bitwise or of
- * CR_INVERT and CR_EDGE. Note that the calling function should
- * have already validated the correctness of this value.
- */
-int ni_tio_set_routing(struct ni_gpct_device *counter_dev,
- unsigned int destination, unsigned int register_value);
-
-/*
- * Sets the given destination MUX to its default value or disable it.
- *
- * Return: 0 if successful; -EINVAL if terminal is unknown.
- */
-int ni_tio_unset_routing(struct ni_gpct_device *counter_dev,
- unsigned int destination);
-
-#endif /* _COMEDI_NI_TIO_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
deleted file mode 100644
index 20fcd60038cd..000000000000
--- a/drivers/staging/comedi/drivers/ni_tio_internal.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Header file for NI general purpose counter support code (ni_tio.c and
- * ni_tiocmd.c)
- *
- * COMEDI - Linux Control and Measurement Device Interface
- */
-
-#ifndef _COMEDI_NI_TIO_INTERNAL_H
-#define _COMEDI_NI_TIO_INTERNAL_H
-
-#include "ni_tio.h"
-
-#define NITIO_AUTO_INC_REG(x) (NITIO_G0_AUTO_INC + (x))
-#define GI_AUTO_INC_MASK 0xff
-#define NITIO_CMD_REG(x) (NITIO_G0_CMD + (x))
-#define GI_ARM BIT(0)
-#define GI_SAVE_TRACE BIT(1)
-#define GI_LOAD BIT(2)
-#define GI_DISARM BIT(4)
-#define GI_CNT_DIR(x) (((x) & 0x3) << 5)
-#define GI_CNT_DIR_MASK GI_CNT_DIR(3)
-#define GI_WRITE_SWITCH BIT(7)
-#define GI_SYNC_GATE BIT(8)
-#define GI_LITTLE_BIG_ENDIAN BIT(9)
-#define GI_BANK_SWITCH_START BIT(10)
-#define GI_BANK_SWITCH_MODE BIT(11)
-#define GI_BANK_SWITCH_ENABLE BIT(12)
-#define GI_ARM_COPY BIT(13)
-#define GI_SAVE_TRACE_COPY BIT(14)
-#define GI_DISARM_COPY BIT(15)
-#define NITIO_HW_SAVE_REG(x) (NITIO_G0_HW_SAVE + (x))
-#define NITIO_SW_SAVE_REG(x) (NITIO_G0_SW_SAVE + (x))
-#define NITIO_MODE_REG(x) (NITIO_G0_MODE + (x))
-#define GI_GATING_MODE(x) (((x) & 0x3) << 0)
-#define GI_GATING_DISABLED GI_GATING_MODE(0)
-#define GI_LEVEL_GATING GI_GATING_MODE(1)
-#define GI_RISING_EDGE_GATING GI_GATING_MODE(2)
-#define GI_FALLING_EDGE_GATING GI_GATING_MODE(3)
-#define GI_GATING_MODE_MASK GI_GATING_MODE(3)
-#define GI_GATE_ON_BOTH_EDGES BIT(2)
-#define GI_EDGE_GATE_MODE(x) (((x) & 0x3) << 3)
-#define GI_EDGE_GATE_STARTS_STOPS GI_EDGE_GATE_MODE(0)
-#define GI_EDGE_GATE_STOPS_STARTS GI_EDGE_GATE_MODE(1)
-#define GI_EDGE_GATE_STARTS GI_EDGE_GATE_MODE(2)
-#define GI_EDGE_GATE_NO_STARTS_OR_STOPS GI_EDGE_GATE_MODE(3)
-#define GI_EDGE_GATE_MODE_MASK GI_EDGE_GATE_MODE(3)
-#define GI_STOP_MODE(x) (((x) & 0x3) << 5)
-#define GI_STOP_ON_GATE GI_STOP_MODE(0)
-#define GI_STOP_ON_GATE_OR_TC GI_STOP_MODE(1)
-#define GI_STOP_ON_GATE_OR_SECOND_TC GI_STOP_MODE(2)
-#define GI_STOP_MODE_MASK GI_STOP_MODE(3)
-#define GI_LOAD_SRC_SEL BIT(7)
-#define GI_OUTPUT_MODE(x) (((x) & 0x3) << 8)
-#define GI_OUTPUT_TC_PULSE GI_OUTPUT_MODE(1)
-#define GI_OUTPUT_TC_TOGGLE GI_OUTPUT_MODE(2)
-#define GI_OUTPUT_TC_OR_GATE_TOGGLE GI_OUTPUT_MODE(3)
-#define GI_OUTPUT_MODE_MASK GI_OUTPUT_MODE(3)
-#define GI_COUNTING_ONCE(x) (((x) & 0x3) << 10)
-#define GI_NO_HARDWARE_DISARM GI_COUNTING_ONCE(0)
-#define GI_DISARM_AT_TC GI_COUNTING_ONCE(1)
-#define GI_DISARM_AT_GATE GI_COUNTING_ONCE(2)
-#define GI_DISARM_AT_TC_OR_GATE GI_COUNTING_ONCE(3)
-#define GI_COUNTING_ONCE_MASK GI_COUNTING_ONCE(3)
-#define GI_LOADING_ON_TC BIT(12)
-#define GI_GATE_POL_INVERT BIT(13)
-#define GI_LOADING_ON_GATE BIT(14)
-#define GI_RELOAD_SRC_SWITCHING BIT(15)
-#define NITIO_LOADA_REG(x) (NITIO_G0_LOADA + (x))
-#define NITIO_LOADB_REG(x) (NITIO_G0_LOADB + (x))
-#define NITIO_INPUT_SEL_REG(x) (NITIO_G0_INPUT_SEL + (x))
-#define GI_READ_ACKS_IRQ BIT(0)
-#define GI_WRITE_ACKS_IRQ BIT(1)
-#define GI_BITS_TO_SRC(x) (((x) >> 2) & 0x1f)
-#define GI_SRC_SEL(x) (((x) & 0x1f) << 2)
-#define GI_SRC_SEL_MASK GI_SRC_SEL(0x1f)
-#define GI_BITS_TO_GATE(x) (((x) >> 7) & 0x1f)
-#define GI_GATE_SEL(x) (((x) & 0x1f) << 7)
-#define GI_GATE_SEL_MASK GI_GATE_SEL(0x1f)
-#define GI_GATE_SEL_LOAD_SRC BIT(12)
-#define GI_OR_GATE BIT(13)
-#define GI_OUTPUT_POL_INVERT BIT(14)
-#define GI_SRC_POL_INVERT BIT(15)
-#define NITIO_CNT_MODE_REG(x) (NITIO_G0_CNT_MODE + (x))
-#define GI_CNT_MODE(x) (((x) & 0x7) << 0)
-#define GI_CNT_MODE_NORMAL GI_CNT_MODE(0)
-#define GI_CNT_MODE_QUADX1 GI_CNT_MODE(1)
-#define GI_CNT_MODE_QUADX2 GI_CNT_MODE(2)
-#define GI_CNT_MODE_QUADX4 GI_CNT_MODE(3)
-#define GI_CNT_MODE_TWO_PULSE GI_CNT_MODE(4)
-#define GI_CNT_MODE_SYNC_SRC GI_CNT_MODE(6)
-#define GI_CNT_MODE_MASK GI_CNT_MODE(7)
-#define GI_INDEX_MODE BIT(4)
-#define GI_INDEX_PHASE(x) (((x) & 0x3) << 5)
-#define GI_INDEX_PHASE_MASK GI_INDEX_PHASE(3)
-#define GI_HW_ARM_ENA BIT(7)
-#define GI_HW_ARM_SEL(x) ((x) << 8)
-#define GI_660X_HW_ARM_SEL_MASK GI_HW_ARM_SEL(0x7)
-#define GI_M_HW_ARM_SEL_MASK GI_HW_ARM_SEL(0x1f)
-#define GI_660X_PRESCALE_X8 BIT(12)
-#define GI_M_PRESCALE_X8 BIT(13)
-#define GI_660X_ALT_SYNC BIT(13)
-#define GI_M_ALT_SYNC BIT(14)
-#define GI_660X_PRESCALE_X2 BIT(14)
-#define GI_M_PRESCALE_X2 BIT(15)
-#define NITIO_GATE2_REG(x) (NITIO_G0_GATE2 + (x))
-#define GI_GATE2_MODE BIT(0)
-#define GI_BITS_TO_GATE2(x) (((x) >> 7) & 0x1f)
-#define GI_GATE2_SEL(x) (((x) & 0x1f) << 7)
-#define GI_GATE2_SEL_MASK GI_GATE2_SEL(0x1f)
-#define GI_GATE2_POL_INVERT BIT(13)
-#define GI_GATE2_SUBSEL BIT(14)
-#define GI_SRC_SUBSEL BIT(15)
-#define NITIO_SHARED_STATUS_REG(x) (NITIO_G01_STATUS + ((x) / 2))
-#define GI_SAVE(x) (((x) % 2) ? BIT(1) : BIT(0))
-#define GI_COUNTING(x) (((x) % 2) ? BIT(3) : BIT(2))
-#define GI_NEXT_LOAD_SRC(x) (((x) % 2) ? BIT(5) : BIT(4))
-#define GI_STALE_DATA(x) (((x) % 2) ? BIT(7) : BIT(6))
-#define GI_ARMED(x) (((x) % 2) ? BIT(9) : BIT(8))
-#define GI_NO_LOAD_BETWEEN_GATES(x) (((x) % 2) ? BIT(11) : BIT(10))
-#define GI_TC_ERROR(x) (((x) % 2) ? BIT(13) : BIT(12))
-#define GI_GATE_ERROR(x) (((x) % 2) ? BIT(15) : BIT(14))
-#define NITIO_RESET_REG(x) (NITIO_G01_RESET + ((x) / 2))
-#define GI_RESET(x) BIT(2 + ((x) % 2))
-#define NITIO_STATUS1_REG(x) (NITIO_G01_STATUS1 + ((x) / 2))
-#define NITIO_STATUS2_REG(x) (NITIO_G01_STATUS2 + ((x) / 2))
-#define GI_OUTPUT(x) (((x) % 2) ? BIT(1) : BIT(0))
-#define GI_HW_SAVE(x) (((x) % 2) ? BIT(13) : BIT(12))
-#define GI_PERMANENT_STALE(x) (((x) % 2) ? BIT(15) : BIT(14))
-#define NITIO_DMA_CFG_REG(x) (NITIO_G0_DMA_CFG + (x))
-#define GI_DMA_ENABLE BIT(0)
-#define GI_DMA_WRITE BIT(1)
-#define GI_DMA_INT_ENA BIT(2)
-#define GI_DMA_RESET BIT(3)
-#define GI_DMA_BANKSW_ERROR BIT(4)
-#define NITIO_DMA_STATUS_REG(x) (NITIO_G0_DMA_STATUS + (x))
-#define GI_DMA_READBANK BIT(13)
-#define GI_DRQ_ERROR BIT(14)
-#define GI_DRQ_STATUS BIT(15)
-#define NITIO_ABZ_REG(x) (NITIO_G0_ABZ + (x))
-#define NITIO_INT_ACK_REG(x) (NITIO_G0_INT_ACK + (x))
-#define GI_GATE_ERROR_CONFIRM(x) (((x) % 2) ? BIT(1) : BIT(5))
-#define GI_TC_ERROR_CONFIRM(x) (((x) % 2) ? BIT(2) : BIT(6))
-#define GI_TC_INTERRUPT_ACK BIT(14)
-#define GI_GATE_INTERRUPT_ACK BIT(15)
-#define NITIO_STATUS_REG(x) (NITIO_G0_STATUS + (x))
-#define GI_GATE_INTERRUPT BIT(2)
-#define GI_TC BIT(3)
-#define GI_INTERRUPT BIT(15)
-#define NITIO_INT_ENA_REG(x) (NITIO_G0_INT_ENA + (x))
-#define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(9) : BIT(6))
-#define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(10) : BIT(8))
-
-void ni_tio_write(struct ni_gpct *counter, unsigned int value,
- enum ni_gpct_register);
-unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register);
-
-static inline bool
-ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev)
-{
- /* m series and 660x variants have counting mode registers */
- return counter_dev->variant != ni_gpct_variant_e_series;
-}
-
-void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register reg,
- unsigned int mask, unsigned int value);
-unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter,
- enum ni_gpct_register reg);
-
-int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger);
-int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned int gate,
- unsigned int src);
-int ni_tio_set_gate_src_raw(struct ni_gpct *counter, unsigned int gate,
- unsigned int src);
-
-#endif /* _COMEDI_NI_TIO_INTERNAL_H */
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
deleted file mode 100644
index ab6d9e8269f3..000000000000
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ /dev/null
@@ -1,510 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Command support for NI general purpose counters
- *
- * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
- */
-
-/*
- * Module: ni_tiocmd
- * Description: National Instruments general purpose counters command support
- * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
- * Herman.Bruyninckx@mech.kuleuven.ac.be,
- * Wim.Meeussen@mech.kuleuven.ac.be,
- * Klaas.Gadeyne@mech.kuleuven.ac.be,
- * Frank Mori Hess <fmhess@users.sourceforge.net>
- * Updated: Fri, 11 Apr 2008 12:32:35 +0100
- * Status: works
- *
- * This module is not used directly by end-users. Rather, it
- * is used by other drivers (for example ni_660x and ni_pcimio)
- * to provide command support for NI's general purpose counters.
- * It was originally split out of ni_tio.c to stop the 'ni_tio'
- * module depending on the 'mite' module.
- *
- * References:
- * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
- * DAQ 6601/6602 User Manual (NI 322137B-01)
- * 340934b.pdf DAQ-STC reference manual
- *
- * TODO: Support use of both banks X and Y
- */
-
-#include <linux/module.h>
-#include "ni_tio_internal.h"
-#include "mite.h"
-#include "ni_routes.h"
-
-static void ni_tio_configure_dma(struct ni_gpct *counter,
- bool enable, bool read)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned int cidx = counter->counter_index;
- unsigned int mask;
- unsigned int bits;
-
- mask = GI_READ_ACKS_IRQ | GI_WRITE_ACKS_IRQ;
- bits = 0;
-
- if (enable) {
- if (read)
- bits |= GI_READ_ACKS_IRQ;
- else
- bits |= GI_WRITE_ACKS_IRQ;
- }
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), mask, bits);
-
- switch (counter_dev->variant) {
- case ni_gpct_variant_e_series:
- break;
- case ni_gpct_variant_m_series:
- case ni_gpct_variant_660x:
- mask = GI_DMA_ENABLE | GI_DMA_INT_ENA | GI_DMA_WRITE;
- bits = 0;
-
- if (enable)
- bits |= GI_DMA_ENABLE | GI_DMA_INT_ENA;
- if (!read)
- bits |= GI_DMA_WRITE;
- ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), mask, bits);
- break;
- }
-}
-
-static int ni_tio_input_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct ni_gpct *counter = s->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned long flags;
- int ret = 0;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- spin_lock_irqsave(&counter->lock, flags);
- if (counter->mite_chan)
- mite_dma_arm(counter->mite_chan);
- else
- ret = -EIO;
- spin_unlock_irqrestore(&counter->lock, flags);
- if (ret < 0)
- return ret;
- ret = ni_tio_arm(counter, true, NI_GPCT_ARM_IMMEDIATE);
- s->async->inttrig = NULL;
-
- return ret;
-}
-
-static int ni_tio_input_cmd(struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- const struct ni_route_tables *routing_tables =
- counter_dev->routing_tables;
- unsigned int cidx = counter->counter_index;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- int ret = 0;
-
- /* write alloc the entire buffer */
- comedi_buf_write_alloc(s, async->prealloc_bufsz);
- counter->mite_chan->dir = COMEDI_INPUT;
- switch (counter_dev->variant) {
- case ni_gpct_variant_m_series:
- case ni_gpct_variant_660x:
- mite_prep_dma(counter->mite_chan, 32, 32);
- break;
- case ni_gpct_variant_e_series:
- mite_prep_dma(counter->mite_chan, 16, 32);
- break;
- }
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
- ni_tio_configure_dma(counter, true, true);
-
- if (cmd->start_src == TRIG_INT) {
- async->inttrig = &ni_tio_input_inttrig;
- } else { /* TRIG_NOW || TRIG_EXT || TRIG_OTHER */
- async->inttrig = NULL;
- mite_dma_arm(counter->mite_chan);
-
- if (cmd->start_src == TRIG_NOW)
- ret = ni_tio_arm(counter, true, NI_GPCT_ARM_IMMEDIATE);
- else if (cmd->start_src == TRIG_EXT) {
- int reg = CR_CHAN(cmd->start_arg);
-
- if (reg >= NI_NAMES_BASE) {
- /* using a device-global name. lookup reg */
- reg = ni_get_reg_value(reg,
- NI_CtrArmStartTrigger(cidx),
- routing_tables);
- /* mark this as a raw register value */
- reg |= NI_GPCT_HW_ARM;
- }
- ret = ni_tio_arm(counter, true, reg);
- }
- }
- return ret;
-}
-
-static int ni_tio_output_cmd(struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
-
- dev_err(counter->counter_dev->dev->class_dev,
- "output commands not yet implemented.\n");
- return -ENOTSUPP;
-}
-
-static int ni_tio_cmd_setup(struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- struct ni_gpct *counter = s->private;
- unsigned int cidx = counter->counter_index;
- const struct ni_route_tables *routing_tables =
- counter->counter_dev->routing_tables;
- int set_gate_source = 0;
- unsigned int gate_source;
- int retval = 0;
-
- if (cmd->scan_begin_src == TRIG_EXT) {
- set_gate_source = 1;
- gate_source = cmd->scan_begin_arg;
- } else if (cmd->convert_src == TRIG_EXT) {
- set_gate_source = 1;
- gate_source = cmd->convert_arg;
- }
- if (set_gate_source) {
- if (CR_CHAN(gate_source) >= NI_NAMES_BASE) {
- /* Lookup and use the real register values */
- int reg = ni_get_reg_value(CR_CHAN(gate_source),
- NI_CtrGate(cidx),
- routing_tables);
- if (reg < 0)
- return -EINVAL;
- retval = ni_tio_set_gate_src_raw(counter, 0, reg);
- } else {
- /*
- * This function must be used separately since it does
- * not expect real register values and attempts to
- * convert these to real register values.
- */
- retval = ni_tio_set_gate_src(counter, 0, gate_source);
- }
- }
- if (cmd->flags & CMDF_WAKE_EOS) {
- ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
- GI_GATE_INTERRUPT_ENABLE(cidx),
- GI_GATE_INTERRUPT_ENABLE(cidx));
- }
- return retval;
-}
-
-int ni_tio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_gpct *counter = s->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- int retval = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&counter->lock, flags);
- if (!counter->mite_chan) {
- dev_err(counter->counter_dev->dev->class_dev,
- "commands only supported with DMA. ");
- dev_err(counter->counter_dev->dev->class_dev,
- "Interrupt-driven commands not yet implemented.\n");
- retval = -EIO;
- } else {
- retval = ni_tio_cmd_setup(s);
- if (retval == 0) {
- if (cmd->flags & CMDF_WRITE)
- retval = ni_tio_output_cmd(s);
- else
- retval = ni_tio_input_cmd(s);
- }
- }
- spin_unlock_irqrestore(&counter->lock, flags);
- return retval;
-}
-EXPORT_SYMBOL_GPL(ni_tio_cmd);
-
-int ni_tio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct ni_gpct *counter = s->private;
- unsigned int cidx = counter->counter_index;
- const struct ni_route_tables *routing_tables =
- counter->counter_dev->routing_tables;
- int err = 0;
- unsigned int sources;
-
- /* Step 1 : check if triggers are trivially valid */
-
- sources = TRIG_NOW | TRIG_INT | TRIG_OTHER;
- if (ni_tio_counting_mode_registers_present(counter->counter_dev))
- sources |= TRIG_EXT;
- err |= comedi_check_trigger_src(&cmd->start_src, sources);
-
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_NOW | TRIG_EXT | TRIG_OTHER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
-
- /* Step 2b : and mutually compatible */
-
- if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- case TRIG_INT:
- case TRIG_OTHER:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- /* start_arg is the start_trigger passed to ni_tio_arm() */
- /*
- * This should be done, but we don't yet know the actual
- * register values. These should be tested and then documented
- * in the ni_route_values/ni_*.csv files, with indication of
- * who/when/which/how these were tested.
- * When at least a e/m/660x series have been tested, this code
- * should be uncommented:
- *
- * err |= ni_check_trigger_arg(CR_CHAN(cmd->start_arg),
- * NI_CtrArmStartTrigger(cidx),
- * routing_tables);
- */
- break;
- }
-
- /*
- * It seems that convention is to allow either scan_begin_arg or
- * convert_arg to specify the Gate source, with scan_begin_arg taking
- * precedence.
- */
- if (cmd->scan_begin_src != TRIG_EXT)
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- else
- err |= ni_check_trigger_arg(CR_CHAN(cmd->scan_begin_arg),
- NI_CtrGate(cidx), routing_tables);
-
- if (cmd->convert_src != TRIG_EXT)
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- else
- err |= ni_check_trigger_arg(CR_CHAN(cmd->convert_arg),
- NI_CtrGate(cidx), routing_tables);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ni_tio_cmdtest);
-
-int ni_tio_cancel(struct ni_gpct *counter)
-{
- unsigned int cidx = counter->counter_index;
- unsigned long flags;
-
- ni_tio_arm(counter, false, 0);
- spin_lock_irqsave(&counter->lock, flags);
- if (counter->mite_chan)
- mite_dma_disarm(counter->mite_chan);
- spin_unlock_irqrestore(&counter->lock, flags);
- ni_tio_configure_dma(counter, false, false);
-
- ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
- GI_GATE_INTERRUPT_ENABLE(cidx), 0x0);
- return 0;
-}
-EXPORT_SYMBOL_GPL(ni_tio_cancel);
-
-static int should_ack_gate(struct ni_gpct *counter)
-{
- unsigned long flags;
- int retval = 0;
-
- switch (counter->counter_dev->variant) {
- case ni_gpct_variant_m_series:
- case ni_gpct_variant_660x:
- /*
- * not sure if 660x really supports gate interrupts
- * (the bits are not listed in register-level manual)
- */
- return 1;
- case ni_gpct_variant_e_series:
- /*
- * During buffered input counter operation for e-series,
- * the gate interrupt is acked automatically by the dma
- * controller, due to the Gi_Read/Write_Acknowledges_IRQ
- * bits in the input select register.
- */
- spin_lock_irqsave(&counter->lock, flags);
- {
- if (!counter->mite_chan ||
- counter->mite_chan->dir != COMEDI_INPUT ||
- (mite_done(counter->mite_chan))) {
- retval = 1;
- }
- }
- spin_unlock_irqrestore(&counter->lock, flags);
- break;
- }
- return retval;
-}
-
-static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter,
- int *gate_error,
- int *tc_error,
- int *perm_stale_data)
-{
- unsigned int cidx = counter->counter_index;
- const unsigned short gxx_status = ni_tio_read(counter,
- NITIO_SHARED_STATUS_REG(cidx));
- const unsigned short gi_status = ni_tio_read(counter,
- NITIO_STATUS_REG(cidx));
- unsigned int ack = 0;
-
- if (gate_error)
- *gate_error = 0;
- if (tc_error)
- *tc_error = 0;
- if (perm_stale_data)
- *perm_stale_data = 0;
-
- if (gxx_status & GI_GATE_ERROR(cidx)) {
- ack |= GI_GATE_ERROR_CONFIRM(cidx);
- if (gate_error) {
- /*
- * 660x don't support automatic acknowledgment
- * of gate interrupt via dma read/write
- * and report bogus gate errors
- */
- if (counter->counter_dev->variant !=
- ni_gpct_variant_660x)
- *gate_error = 1;
- }
- }
- if (gxx_status & GI_TC_ERROR(cidx)) {
- ack |= GI_TC_ERROR_CONFIRM(cidx);
- if (tc_error)
- *tc_error = 1;
- }
- if (gi_status & GI_TC)
- ack |= GI_TC_INTERRUPT_ACK;
- if (gi_status & GI_GATE_INTERRUPT) {
- if (should_ack_gate(counter))
- ack |= GI_GATE_INTERRUPT_ACK;
- }
- if (ack)
- ni_tio_write(counter, ack, NITIO_INT_ACK_REG(cidx));
- if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) &
- GI_LOADING_ON_GATE) {
- if (ni_tio_read(counter, NITIO_STATUS2_REG(cidx)) &
- GI_PERMANENT_STALE(cidx)) {
- dev_info(counter->counter_dev->dev->class_dev,
- "%s: Gi_Permanent_Stale_Data detected.\n",
- __func__);
- if (perm_stale_data)
- *perm_stale_data = 1;
- }
- }
-}
-
-void ni_tio_acknowledge(struct ni_gpct *counter)
-{
- ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL);
-}
-EXPORT_SYMBOL_GPL(ni_tio_acknowledge);
-
-void ni_tio_handle_interrupt(struct ni_gpct *counter,
- struct comedi_subdevice *s)
-{
- unsigned int cidx = counter->counter_index;
- unsigned long flags;
- int gate_error;
- int tc_error;
- int perm_stale_data;
-
- ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
- &perm_stale_data);
- if (gate_error) {
- dev_notice(counter->counter_dev->dev->class_dev,
- "%s: Gi_Gate_Error detected.\n", __func__);
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
- if (perm_stale_data)
- s->async->events |= COMEDI_CB_ERROR;
- switch (counter->counter_dev->variant) {
- case ni_gpct_variant_m_series:
- case ni_gpct_variant_660x:
- if (ni_tio_read(counter, NITIO_DMA_STATUS_REG(cidx)) &
- GI_DRQ_ERROR) {
- dev_notice(counter->counter_dev->dev->class_dev,
- "%s: Gi_DRQ_Error detected.\n", __func__);
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
- break;
- case ni_gpct_variant_e_series:
- break;
- }
- spin_lock_irqsave(&counter->lock, flags);
- if (counter->mite_chan)
- mite_ack_linkc(counter->mite_chan, s, true);
- spin_unlock_irqrestore(&counter->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt);
-
-void ni_tio_set_mite_channel(struct ni_gpct *counter,
- struct mite_channel *mite_chan)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&counter->lock, flags);
- counter->mite_chan = mite_chan;
- spin_unlock_irqrestore(&counter->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel);
-
-static int __init ni_tiocmd_init_module(void)
-{
- return 0;
-}
-module_init(ni_tiocmd_init_module);
-
-static void __exit ni_tiocmd_cleanup_module(void)
-{
-}
-module_exit(ni_tiocmd_cleanup_module);
-
-MODULE_AUTHOR("Comedi <comedi@comedi.org>");
-MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c
deleted file mode 100644
index 5b6d9d783b2f..000000000000
--- a/drivers/staging/comedi/drivers/ni_usb6501.c
+++ /dev/null
@@ -1,602 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/ni_usb6501.c
- * Comedi driver for National Instruments USB-6501
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2014 Luca Ellero <luca.ellero@brickedbrain.com>
- */
-
-/*
- * Driver: ni_usb6501
- * Description: National Instruments USB-6501 module
- * Devices: [National Instruments] USB-6501 (ni_usb6501)
- * Author: Luca Ellero <luca.ellero@brickedbrain.com>
- * Updated: 8 Sep 2014
- * Status: works
- *
- *
- * Configuration Options:
- * none
- */
-
-/*
- * NI-6501 - USB PROTOCOL DESCRIPTION
- *
- * Every command is composed by two USB packets:
- * - request (out)
- * - response (in)
- *
- * Every packet is at least 12 bytes long, here is the meaning of
- * every field (all values are hex):
- *
- * byte 0 is always 00
- * byte 1 is always 01
- * byte 2 is always 00
- * byte 3 is the total packet length
- *
- * byte 4 is always 00
- * byte 5 is the total packet length - 4
- * byte 6 is always 01
- * byte 7 is the command
- *
- * byte 8 is 02 (request) or 00 (response)
- * byte 9 is 00 (response) or 10 (port request) or 20 (counter request)
- * byte 10 is always 00
- * byte 11 is 00 (request) or 02 (response)
- *
- * PORT PACKETS
- *
- * CMD: 0xE READ_PORT
- * REQ: 00 01 00 10 00 0C 01 0E 02 10 00 00 00 03 <PORT> 00
- * RES: 00 01 00 10 00 0C 01 00 00 00 00 02 00 03 <BMAP> 00
- *
- * CMD: 0xF WRITE_PORT
- * REQ: 00 01 00 14 00 10 01 0F 02 10 00 00 00 03 <PORT> 00 03 <BMAP> 00 00
- * RES: 00 01 00 0C 00 08 01 00 00 00 00 02
- *
- * CMD: 0x12 SET_PORT_DIR (0 = input, 1 = output)
- * REQ: 00 01 00 18 00 14 01 12 02 10 00 00
- * 00 05 <PORT 0> <PORT 1> <PORT 2> 00 05 00 00 00 00 00
- * RES: 00 01 00 0C 00 08 01 00 00 00 00 02
- *
- * COUNTER PACKETS
- *
- * CMD 0x9: START_COUNTER
- * REQ: 00 01 00 0C 00 08 01 09 02 20 00 00
- * RES: 00 01 00 0C 00 08 01 00 00 00 00 02
- *
- * CMD 0xC: STOP_COUNTER
- * REQ: 00 01 00 0C 00 08 01 0C 02 20 00 00
- * RES: 00 01 00 0C 00 08 01 00 00 00 00 02
- *
- * CMD 0xE: READ_COUNTER
- * REQ: 00 01 00 0C 00 08 01 0E 02 20 00 00
- * RES: 00 01 00 10 00 0C 01 00 00 00 00 02 <u32 counter value, Big Endian>
- *
- * CMD 0xF: WRITE_COUNTER
- * REQ: 00 01 00 10 00 0C 01 0F 02 20 00 00 <u32 counter value, Big Endian>
- * RES: 00 01 00 0C 00 08 01 00 00 00 00 02
- *
- *
- * Please visit https://www.brickedbrain.com if you need
- * additional information or have any questions.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "../comedi_usb.h"
-
-#define NI6501_TIMEOUT 1000
-
-/* Port request packets */
-static const u8 READ_PORT_REQUEST[] = {0x00, 0x01, 0x00, 0x10,
- 0x00, 0x0C, 0x01, 0x0E,
- 0x02, 0x10, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00};
-
-static const u8 WRITE_PORT_REQUEST[] = {0x00, 0x01, 0x00, 0x14,
- 0x00, 0x10, 0x01, 0x0F,
- 0x02, 0x10, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x00};
-
-static const u8 SET_PORT_DIR_REQUEST[] = {0x00, 0x01, 0x00, 0x18,
- 0x00, 0x14, 0x01, 0x12,
- 0x02, 0x10, 0x00, 0x00,
- 0x00, 0x05, 0x00, 0x00,
- 0x00, 0x00, 0x05, 0x00,
- 0x00, 0x00, 0x00, 0x00};
-
-/* Counter request packets */
-static const u8 START_COUNTER_REQUEST[] = {0x00, 0x01, 0x00, 0x0C,
- 0x00, 0x08, 0x01, 0x09,
- 0x02, 0x20, 0x00, 0x00};
-
-static const u8 STOP_COUNTER_REQUEST[] = {0x00, 0x01, 0x00, 0x0C,
- 0x00, 0x08, 0x01, 0x0C,
- 0x02, 0x20, 0x00, 0x00};
-
-static const u8 READ_COUNTER_REQUEST[] = {0x00, 0x01, 0x00, 0x0C,
- 0x00, 0x08, 0x01, 0x0E,
- 0x02, 0x20, 0x00, 0x00};
-
-static const u8 WRITE_COUNTER_REQUEST[] = {0x00, 0x01, 0x00, 0x10,
- 0x00, 0x0C, 0x01, 0x0F,
- 0x02, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
-
-/* Response packets */
-static const u8 GENERIC_RESPONSE[] = {0x00, 0x01, 0x00, 0x0C,
- 0x00, 0x08, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02};
-
-static const u8 READ_PORT_RESPONSE[] = {0x00, 0x01, 0x00, 0x10,
- 0x00, 0x0C, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x03, 0x00, 0x00};
-
-static const u8 READ_COUNTER_RESPONSE[] = {0x00, 0x01, 0x00, 0x10,
- 0x00, 0x0C, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00};
-
-enum commands {
- READ_PORT,
- WRITE_PORT,
- SET_PORT_DIR,
- START_COUNTER,
- STOP_COUNTER,
- READ_COUNTER,
- WRITE_COUNTER
-};
-
-struct ni6501_private {
- struct usb_endpoint_descriptor *ep_rx;
- struct usb_endpoint_descriptor *ep_tx;
- struct mutex mut;
- u8 *usb_rx_buf;
- u8 *usb_tx_buf;
-};
-
-static int ni6501_port_command(struct comedi_device *dev, int command,
- unsigned int val, u8 *bitmap)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct ni6501_private *devpriv = dev->private;
- int request_size, response_size;
- u8 *tx = devpriv->usb_tx_buf;
- int ret;
-
- if (command != SET_PORT_DIR && !bitmap)
- return -EINVAL;
-
- mutex_lock(&devpriv->mut);
-
- switch (command) {
- case READ_PORT:
- request_size = sizeof(READ_PORT_REQUEST);
- response_size = sizeof(READ_PORT_RESPONSE);
- memcpy(tx, READ_PORT_REQUEST, request_size);
- tx[14] = val & 0xff;
- break;
- case WRITE_PORT:
- request_size = sizeof(WRITE_PORT_REQUEST);
- response_size = sizeof(GENERIC_RESPONSE);
- memcpy(tx, WRITE_PORT_REQUEST, request_size);
- tx[14] = val & 0xff;
- tx[17] = *bitmap;
- break;
- case SET_PORT_DIR:
- request_size = sizeof(SET_PORT_DIR_REQUEST);
- response_size = sizeof(GENERIC_RESPONSE);
- memcpy(tx, SET_PORT_DIR_REQUEST, request_size);
- tx[14] = val & 0xff;
- tx[15] = (val >> 8) & 0xff;
- tx[16] = (val >> 16) & 0xff;
- break;
- default:
- ret = -EINVAL;
- goto end;
- }
-
- ret = usb_bulk_msg(usb,
- usb_sndbulkpipe(usb,
- devpriv->ep_tx->bEndpointAddress),
- devpriv->usb_tx_buf,
- request_size,
- NULL,
- NI6501_TIMEOUT);
- if (ret)
- goto end;
-
- ret = usb_bulk_msg(usb,
- usb_rcvbulkpipe(usb,
- devpriv->ep_rx->bEndpointAddress),
- devpriv->usb_rx_buf,
- response_size,
- NULL,
- NI6501_TIMEOUT);
- if (ret)
- goto end;
-
- /* Check if results are valid */
-
- if (command == READ_PORT) {
- *bitmap = devpriv->usb_rx_buf[14];
- /* mask bitmap for comparing */
- devpriv->usb_rx_buf[14] = 0x00;
-
- if (memcmp(devpriv->usb_rx_buf, READ_PORT_RESPONSE,
- sizeof(READ_PORT_RESPONSE))) {
- ret = -EINVAL;
- }
- } else if (memcmp(devpriv->usb_rx_buf, GENERIC_RESPONSE,
- sizeof(GENERIC_RESPONSE))) {
- ret = -EINVAL;
- }
-end:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int ni6501_counter_command(struct comedi_device *dev, int command,
- u32 *val)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct ni6501_private *devpriv = dev->private;
- int request_size, response_size;
- u8 *tx = devpriv->usb_tx_buf;
- int ret;
-
- if ((command == READ_COUNTER || command == WRITE_COUNTER) && !val)
- return -EINVAL;
-
- mutex_lock(&devpriv->mut);
-
- switch (command) {
- case START_COUNTER:
- request_size = sizeof(START_COUNTER_REQUEST);
- response_size = sizeof(GENERIC_RESPONSE);
- memcpy(tx, START_COUNTER_REQUEST, request_size);
- break;
- case STOP_COUNTER:
- request_size = sizeof(STOP_COUNTER_REQUEST);
- response_size = sizeof(GENERIC_RESPONSE);
- memcpy(tx, STOP_COUNTER_REQUEST, request_size);
- break;
- case READ_COUNTER:
- request_size = sizeof(READ_COUNTER_REQUEST);
- response_size = sizeof(READ_COUNTER_RESPONSE);
- memcpy(tx, READ_COUNTER_REQUEST, request_size);
- break;
- case WRITE_COUNTER:
- request_size = sizeof(WRITE_COUNTER_REQUEST);
- response_size = sizeof(GENERIC_RESPONSE);
- memcpy(tx, WRITE_COUNTER_REQUEST, request_size);
- /* Setup tx packet: bytes 12,13,14,15 hold the */
- /* u32 counter value (Big Endian) */
- *((__be32 *)&tx[12]) = cpu_to_be32(*val);
- break;
- default:
- ret = -EINVAL;
- goto end;
- }
-
- ret = usb_bulk_msg(usb,
- usb_sndbulkpipe(usb,
- devpriv->ep_tx->bEndpointAddress),
- devpriv->usb_tx_buf,
- request_size,
- NULL,
- NI6501_TIMEOUT);
- if (ret)
- goto end;
-
- ret = usb_bulk_msg(usb,
- usb_rcvbulkpipe(usb,
- devpriv->ep_rx->bEndpointAddress),
- devpriv->usb_rx_buf,
- response_size,
- NULL,
- NI6501_TIMEOUT);
- if (ret)
- goto end;
-
- /* Check if results are valid */
-
- if (command == READ_COUNTER) {
- int i;
-
- /* Read counter value: bytes 12,13,14,15 of rx packet */
- /* hold the u32 counter value (Big Endian) */
- *val = be32_to_cpu(*((__be32 *)&devpriv->usb_rx_buf[12]));
-
- /* mask counter value for comparing */
- for (i = 12; i < sizeof(READ_COUNTER_RESPONSE); ++i)
- devpriv->usb_rx_buf[i] = 0x00;
-
- if (memcmp(devpriv->usb_rx_buf, READ_COUNTER_RESPONSE,
- sizeof(READ_COUNTER_RESPONSE))) {
- ret = -EINVAL;
- }
- } else if (memcmp(devpriv->usb_rx_buf, GENERIC_RESPONSE,
- sizeof(GENERIC_RESPONSE))) {
- ret = -EINVAL;
- }
-end:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int ni6501_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- ret = ni6501_port_command(dev, SET_PORT_DIR, s->io_bits, NULL);
- if (ret)
- return ret;
-
- return insn->n;
-}
-
-static int ni6501_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
- int ret;
- u8 port;
- u8 bitmap;
-
- mask = comedi_dio_update_state(s, data);
-
- for (port = 0; port < 3; port++) {
- if (mask & (0xFF << port * 8)) {
- bitmap = (s->state >> port * 8) & 0xFF;
- ret = ni6501_port_command(dev, WRITE_PORT,
- port, &bitmap);
- if (ret)
- return ret;
- }
- }
-
- data[1] = 0;
-
- for (port = 0; port < 3; port++) {
- ret = ni6501_port_command(dev, READ_PORT, port, &bitmap);
- if (ret)
- return ret;
- data[1] |= bitmap << port * 8;
- }
-
- return insn->n;
-}
-
-static int ni6501_cnt_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- u32 val = 0;
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- ret = ni6501_counter_command(dev, START_COUNTER, NULL);
- break;
- case INSN_CONFIG_DISARM:
- ret = ni6501_counter_command(dev, STOP_COUNTER, NULL);
- break;
- case INSN_CONFIG_RESET:
- ret = ni6501_counter_command(dev, STOP_COUNTER, NULL);
- if (ret)
- break;
- ret = ni6501_counter_command(dev, WRITE_COUNTER, &val);
- break;
- default:
- return -EINVAL;
- }
-
- return ret ? ret : insn->n;
-}
-
-static int ni6501_cnt_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- u32 val;
- unsigned int i;
-
- for (i = 0; i < insn->n; i++) {
- ret = ni6501_counter_command(dev, READ_COUNTER, &val);
- if (ret)
- return ret;
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int ni6501_cnt_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- if (insn->n) {
- u32 val = data[insn->n - 1];
-
- ret = ni6501_counter_command(dev, WRITE_COUNTER, &val);
- if (ret)
- return ret;
- }
-
- return insn->n;
-}
-
-static int ni6501_alloc_usb_buffers(struct comedi_device *dev)
-{
- struct ni6501_private *devpriv = dev->private;
- size_t size;
-
- size = usb_endpoint_maxp(devpriv->ep_rx);
- devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL);
- if (!devpriv->usb_rx_buf)
- return -ENOMEM;
-
- size = usb_endpoint_maxp(devpriv->ep_tx);
- devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
- if (!devpriv->usb_tx_buf)
- return -ENOMEM;
-
- return 0;
-}
-
-static int ni6501_find_endpoints(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct ni6501_private *devpriv = dev->private;
- struct usb_host_interface *iface_desc = intf->cur_altsetting;
- struct usb_endpoint_descriptor *ep_desc;
- int i;
-
- if (iface_desc->desc.bNumEndpoints != 2) {
- dev_err(dev->class_dev, "Wrong number of endpoints\n");
- return -ENODEV;
- }
-
- for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
- ep_desc = &iface_desc->endpoint[i].desc;
-
- if (usb_endpoint_is_bulk_in(ep_desc)) {
- if (!devpriv->ep_rx)
- devpriv->ep_rx = ep_desc;
- continue;
- }
-
- if (usb_endpoint_is_bulk_out(ep_desc)) {
- if (!devpriv->ep_tx)
- devpriv->ep_tx = ep_desc;
- continue;
- }
- }
-
- if (!devpriv->ep_rx || !devpriv->ep_tx)
- return -ENODEV;
-
- return 0;
-}
-
-static int ni6501_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct ni6501_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- mutex_init(&devpriv->mut);
- usb_set_intfdata(intf, devpriv);
-
- ret = ni6501_find_endpoints(dev);
- if (ret)
- return ret;
-
- ret = ni6501_alloc_usb_buffers(dev);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- /* Digital Input/Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = ni6501_dio_insn_bits;
- s->insn_config = ni6501_dio_insn_config;
-
- /* Counter subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
- s->n_chan = 1;
- s->maxdata = 0xffffffff;
- s->insn_read = ni6501_cnt_insn_read;
- s->insn_write = ni6501_cnt_insn_write;
- s->insn_config = ni6501_cnt_insn_config;
-
- return 0;
-}
-
-static void ni6501_detach(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct ni6501_private *devpriv = dev->private;
-
- if (!devpriv)
- return;
-
- mutex_destroy(&devpriv->mut);
-
- usb_set_intfdata(intf, NULL);
-
- kfree(devpriv->usb_rx_buf);
- kfree(devpriv->usb_tx_buf);
-}
-
-static struct comedi_driver ni6501_driver = {
- .module = THIS_MODULE,
- .driver_name = "ni6501",
- .auto_attach = ni6501_auto_attach,
- .detach = ni6501_detach,
-};
-
-static int ni6501_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return comedi_usb_auto_config(intf, &ni6501_driver, id->driver_info);
-}
-
-static const struct usb_device_id ni6501_usb_table[] = {
- { USB_DEVICE(0x3923, 0x718a) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, ni6501_usb_table);
-
-static struct usb_driver ni6501_usb_driver = {
- .name = "ni6501",
- .id_table = ni6501_usb_table,
- .probe = ni6501_usb_probe,
- .disconnect = comedi_usb_auto_unconfig,
-};
-module_comedi_usb_driver(ni6501_driver, ni6501_usb_driver);
-
-MODULE_AUTHOR("Luca Ellero");
-MODULE_DESCRIPTION("Comedi driver for National Instruments USB-6501");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
deleted file mode 100644
index bd6f42fe9e3c..000000000000
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ /dev/null
@@ -1,513 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * pcl711.c
- * Comedi driver for PC-LabCard PCL-711 and AdSys ACL-8112 and compatibles
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- * Janne Jalkanen <jalkanen@cs.hut.fi>
- * Eric Bunn <ebu@cs.hut.fi>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: pcl711
- * Description: Advantech PCL-711 and 711b, ADLink ACL-8112
- * Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
- * [ADLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
- * Author: David A. Schleef <ds@schleef.org>
- * Janne Jalkanen <jalkanen@cs.hut.fi>
- * Eric Bunn <ebu@cs.hut.fi>
- * Updated:
- * Status: mostly complete
- *
- * Configuration Options:
- * [0] - I/O port base
- * [1] - IRQ, optional
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "comedi_8254.h"
-
-/*
- * I/O port register map
- */
-#define PCL711_TIMER_BASE 0x00
-#define PCL711_AI_LSB_REG 0x04
-#define PCL711_AI_MSB_REG 0x05
-#define PCL711_AI_MSB_DRDY BIT(4)
-#define PCL711_AO_LSB_REG(x) (0x04 + ((x) * 2))
-#define PCL711_AO_MSB_REG(x) (0x05 + ((x) * 2))
-#define PCL711_DI_LSB_REG 0x06
-#define PCL711_DI_MSB_REG 0x07
-#define PCL711_INT_STAT_REG 0x08
-#define PCL711_INT_STAT_CLR (0 << 0) /* any value will work */
-#define PCL711_AI_GAIN_REG 0x09
-#define PCL711_AI_GAIN(x) (((x) & 0xf) << 0)
-#define PCL711_MUX_REG 0x0a
-#define PCL711_MUX_CHAN(x) (((x) & 0xf) << 0)
-#define PCL711_MUX_CS0 BIT(4)
-#define PCL711_MUX_CS1 BIT(5)
-#define PCL711_MUX_DIFF (PCL711_MUX_CS0 | PCL711_MUX_CS1)
-#define PCL711_MODE_REG 0x0b
-#define PCL711_MODE(x) (((x) & 0x7) << 0)
-#define PCL711_MODE_DEFAULT PCL711_MODE(0)
-#define PCL711_MODE_SOFTTRIG PCL711_MODE(1)
-#define PCL711_MODE_EXT PCL711_MODE(2)
-#define PCL711_MODE_EXT_IRQ PCL711_MODE(3)
-#define PCL711_MODE_PACER PCL711_MODE(4)
-#define PCL711_MODE_PACER_IRQ PCL711_MODE(6)
-#define PCL711_MODE_IRQ(x) (((x) & 0x7) << 4)
-#define PCL711_SOFTTRIG_REG 0x0c
-#define PCL711_SOFTTRIG (0 << 0) /* any value will work */
-#define PCL711_DO_LSB_REG 0x0d
-#define PCL711_DO_MSB_REG 0x0e
-
-static const struct comedi_lrange range_pcl711b_ai = {
- 5, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- BIP_RANGE(0.3125)
- }
-};
-
-static const struct comedi_lrange range_acl8112hg_ai = {
- 12, {
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.005),
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01),
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_acl8112dg_ai = {
- 9, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- BIP_RANGE(10)
- }
-};
-
-struct pcl711_board {
- const char *name;
- int n_aichan;
- int n_aochan;
- int maxirq;
- const struct comedi_lrange *ai_range_type;
-};
-
-static const struct pcl711_board boardtypes[] = {
- {
- .name = "pcl711",
- .n_aichan = 8,
- .n_aochan = 1,
- .ai_range_type = &range_bipolar5,
- }, {
- .name = "pcl711b",
- .n_aichan = 8,
- .n_aochan = 1,
- .maxirq = 7,
- .ai_range_type = &range_pcl711b_ai,
- }, {
- .name = "acl8112hg",
- .n_aichan = 16,
- .n_aochan = 2,
- .maxirq = 15,
- .ai_range_type = &range_acl8112hg_ai,
- }, {
- .name = "acl8112dg",
- .n_aichan = 16,
- .n_aochan = 2,
- .maxirq = 15,
- .ai_range_type = &range_acl8112dg_ai,
- },
-};
-
-static void pcl711_ai_set_mode(struct comedi_device *dev, unsigned int mode)
-{
- /*
- * The pcl711b board uses bits in the mode register to select the
- * interrupt. The other boards supported by this driver all use
- * jumpers on the board.
- *
- * Enables the interrupt when needed on the pcl711b board. These
- * bits do nothing on the other boards.
- */
- if (mode == PCL711_MODE_EXT_IRQ || mode == PCL711_MODE_PACER_IRQ)
- mode |= PCL711_MODE_IRQ(dev->irq);
-
- outb(mode, dev->iobase + PCL711_MODE_REG);
-}
-
-static unsigned int pcl711_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- val = inb(dev->iobase + PCL711_AI_MSB_REG) << 8;
- val |= inb(dev->iobase + PCL711_AI_LSB_REG);
-
- return val & s->maxdata;
-}
-
-static int pcl711_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
- pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
- return 0;
-}
-
-static irqreturn_t pcl711_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned short data;
-
- if (!dev->attached) {
- dev_err(dev->class_dev, "spurious interrupt\n");
- return IRQ_HANDLED;
- }
-
- data = pcl711_ai_get_sample(dev, s);
-
- outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
-
- comedi_buf_write_samples(s, &data, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static void pcl711_set_changain(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chanspec)
-{
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
- unsigned int mux = 0;
-
- outb(PCL711_AI_GAIN(range), dev->iobase + PCL711_AI_GAIN_REG);
-
- if (s->n_chan > 8) {
- /* Select the correct MPC508A chip */
- if (aref == AREF_DIFF) {
- chan &= 0x7;
- mux |= PCL711_MUX_DIFF;
- } else {
- if (chan < 8)
- mux |= PCL711_MUX_CS0;
- else
- mux |= PCL711_MUX_CS1;
- }
- }
- outb(mux | PCL711_MUX_CHAN(chan), dev->iobase + PCL711_MUX_REG);
-}
-
-static int pcl711_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + PCL711_AI_MSB_REG);
- if ((status & PCL711_AI_MSB_DRDY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int pcl711_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
- int i;
-
- pcl711_set_changain(dev, s, insn->chanspec);
-
- pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
-
- for (i = 0; i < insn->n; i++) {
- outb(PCL711_SOFTTRIG, dev->iobase + PCL711_SOFTTRIG_REG);
-
- ret = comedi_timeout(dev, s, insn, pcl711_ai_eoc, 0);
- if (ret)
- return ret;
-
- data[i] = pcl711_ai_get_sample(dev, s);
- }
-
- return insn->n;
-}
-
-static int pcl711_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_EXT) {
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- } else {
-#define MAX_SPEED 1000
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- MAX_SPEED);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4 */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- unsigned int arg = cmd->scan_begin_arg;
-
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- pcl711_set_changain(dev, s, cmd->chanlist[0]);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
- pcl711_ai_set_mode(dev, PCL711_MODE_PACER_IRQ);
- } else {
- pcl711_ai_set_mode(dev, PCL711_MODE_EXT_IRQ);
- }
-
- return 0;
-}
-
-static void pcl711_ao_write(struct comedi_device *dev,
- unsigned int chan, unsigned int val)
-{
- outb(val & 0xff, dev->iobase + PCL711_AO_LSB_REG(chan));
- outb((val >> 8) & 0xff, dev->iobase + PCL711_AO_MSB_REG(chan));
-}
-
-static int pcl711_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- pcl711_ao_write(dev, chan, val);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pcl711_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int val;
-
- val = inb(dev->iobase + PCL711_DI_LSB_REG);
- val |= (inb(dev->iobase + PCL711_DI_MSB_REG) << 8);
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int pcl711_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0x00ff)
- outb(s->state & 0xff, dev->iobase + PCL711_DO_LSB_REG);
- if (mask & 0xff00)
- outb((s->state >> 8), dev->iobase + PCL711_DO_MSB_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct pcl711_board *board = dev->board_ptr;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- if (it->options[1] && it->options[1] <= board->maxirq) {
- ret = request_irq(it->options[1], pcl711_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- dev->pacer = comedi_8254_init(dev->iobase + PCL711_TIMER_BASE,
- I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- if (board->n_aichan > 8)
- s->subdev_flags |= SDF_DIFF;
- s->n_chan = board->n_aichan;
- s->maxdata = 0xfff;
- s->range_table = board->ai_range_type;
- s->insn_read = pcl711_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 1;
- s->do_cmdtest = pcl711_ai_cmdtest;
- s->do_cmd = pcl711_ai_cmd;
- s->cancel = pcl711_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->n_aochan;
- s->maxdata = 0xfff;
- s->range_table = &range_bipolar5;
- s->insn_write = pcl711_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl711_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl711_do_insn_bits;
-
- /* clear DAC */
- pcl711_ao_write(dev, 0, 0x0);
- pcl711_ao_write(dev, 1, 0x0);
-
- return 0;
-}
-
-static struct comedi_driver pcl711_driver = {
- .driver_name = "pcl711",
- .module = THIS_MODULE,
- .attach = pcl711_attach,
- .detach = comedi_legacy_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct pcl711_board),
-};
-module_comedi_driver(pcl711_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for PCL-711 compatible boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
deleted file mode 100644
index 1a5799278a7a..000000000000
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ /dev/null
@@ -1,153 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * pcl724.c
- * Comedi driver for 8255 based ISA and PC/104 DIO boards
- *
- * Michal Dobes <dobes@tesnet.cz>
- */
-
-/*
- * Driver: pcl724
- * Description: Comedi driver for 8255 based ISA DIO boards
- * Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
- * [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio),
- * [WinSystems] PCM-IO48 (pcmio48),
- * [Diamond Systems] ONYX-MM-DIO (onyx-mm-dio)
- * Author: Michal Dobes <dobes@tesnet.cz>
- * Status: untested
- *
- * Configuration options:
- * [0] - IO Base
- * [1] - IRQ (not supported)
- * [2] - number of DIO (pcl722 and acl7122 boards)
- * 0, 144: 144 DIO configuration
- * 1, 96: 96 DIO configuration
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include "8255.h"
-
-struct pcl724_board {
- const char *name;
- unsigned int io_range;
- unsigned int can_have96:1;
- unsigned int is_pet48:1;
- int numofports;
-};
-
-static const struct pcl724_board boardtypes[] = {
- {
- .name = "pcl724",
- .io_range = 0x04,
- .numofports = 1, /* 24 DIO channels */
- }, {
- .name = "pcl722",
- .io_range = 0x20,
- .can_have96 = 1,
- .numofports = 6, /* 144 (or 96) DIO channels */
- }, {
- .name = "pcl731",
- .io_range = 0x08,
- .numofports = 2, /* 48 DIO channels */
- }, {
- .name = "acl7122",
- .io_range = 0x20,
- .can_have96 = 1,
- .numofports = 6, /* 144 (or 96) DIO channels */
- }, {
- .name = "acl7124",
- .io_range = 0x04,
- .numofports = 1, /* 24 DIO channels */
- }, {
- .name = "pet48dio",
- .io_range = 0x02,
- .is_pet48 = 1,
- .numofports = 2, /* 48 DIO channels */
- }, {
- .name = "pcmio48",
- .io_range = 0x08,
- .numofports = 2, /* 48 DIO channels */
- }, {
- .name = "onyx-mm-dio",
- .io_range = 0x10,
- .numofports = 2, /* 48 DIO channels */
- },
-};
-
-static int pcl724_8255mapped_io(struct comedi_device *dev,
- int dir, int port, int data,
- unsigned long iobase)
-{
- int movport = I8255_SIZE * (iobase >> 12);
-
- iobase &= 0x0fff;
-
- outb(port + movport, iobase);
- if (dir) {
- outb(data, iobase + 1);
- return 0;
- }
- return inb(iobase + 1);
-}
-
-static int pcl724_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct pcl724_board *board = dev->board_ptr;
- struct comedi_subdevice *s;
- unsigned long iobase;
- unsigned int iorange;
- int n_subdevices;
- int ret;
- int i;
-
- iorange = board->io_range;
- n_subdevices = board->numofports;
-
- /* Handle PCL-724 in 96 DIO configuration */
- if (board->can_have96 &&
- (it->options[2] == 1 || it->options[2] == 96)) {
- iorange = 0x10;
- n_subdevices = 4;
- }
-
- ret = comedi_request_region(dev, it->options[0], iorange);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, n_subdevices);
- if (ret)
- return ret;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- if (board->is_pet48) {
- iobase = dev->iobase + (i * 0x1000);
- ret = subdev_8255_init(dev, s, pcl724_8255mapped_io,
- iobase);
- } else {
- ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
- }
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct comedi_driver pcl724_driver = {
- .driver_name = "pcl724",
- .module = THIS_MODULE,
- .attach = pcl724_attach,
- .detach = comedi_legacy_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct pcl724_board),
-};
-module_comedi_driver(pcl724_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for 8255 based ISA and PC/104 DIO boards");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
deleted file mode 100644
index 88f25d7e76f7..000000000000
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ /dev/null
@@ -1,425 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * pcl726.c
- * Comedi driver for 6/12-Channel D/A Output and DIO cards
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: pcl726
- * Description: Advantech PCL-726 & compatibles
- * Author: David A. Schleef <ds@schleef.org>
- * Status: untested
- * Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
- * [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
- *
- * Configuration Options:
- * [0] - IO Base
- * [1] - IRQ (ACL-6126 only)
- * [2] - D/A output range for channel 0
- * [3] - D/A output range for channel 1
- *
- * Boards with > 2 analog output channels:
- * [4] - D/A output range for channel 2
- * [5] - D/A output range for channel 3
- * [6] - D/A output range for channel 4
- * [7] - D/A output range for channel 5
- *
- * Boards with > 6 analog output channels:
- * [8] - D/A output range for channel 6
- * [9] - D/A output range for channel 7
- * [10] - D/A output range for channel 8
- * [11] - D/A output range for channel 9
- * [12] - D/A output range for channel 10
- * [13] - D/A output range for channel 11
- *
- * For PCL-726 the D/A output ranges are:
- * 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA, 5: unknown
- *
- * For PCL-727:
- * 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: 4-20mA
- *
- * For PCL-728 and ACL-6128:
- * 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA, 5: 0-20mA
- *
- * For ACL-6126:
- * 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#define PCL726_AO_MSB_REG(x) (0x00 + ((x) * 2))
-#define PCL726_AO_LSB_REG(x) (0x01 + ((x) * 2))
-#define PCL726_DO_MSB_REG 0x0c
-#define PCL726_DO_LSB_REG 0x0d
-#define PCL726_DI_MSB_REG 0x0e
-#define PCL726_DI_LSB_REG 0x0f
-
-#define PCL727_DI_MSB_REG 0x00
-#define PCL727_DI_LSB_REG 0x01
-#define PCL727_DO_MSB_REG 0x18
-#define PCL727_DO_LSB_REG 0x19
-
-static const struct comedi_lrange *const rangelist_726[] = {
- &range_unipolar5,
- &range_unipolar10,
- &range_bipolar5,
- &range_bipolar10,
- &range_4_20mA,
- &range_unknown
-};
-
-static const struct comedi_lrange *const rangelist_727[] = {
- &range_unipolar5,
- &range_unipolar10,
- &range_bipolar5,
- &range_4_20mA
-};
-
-static const struct comedi_lrange *const rangelist_728[] = {
- &range_unipolar5,
- &range_unipolar10,
- &range_bipolar5,
- &range_bipolar10,
- &range_4_20mA,
- &range_0_20mA
-};
-
-struct pcl726_board {
- const char *name;
- unsigned long io_len;
- unsigned int irq_mask;
- const struct comedi_lrange *const *ao_ranges;
- int ao_num_ranges;
- int ao_nchan;
- unsigned int have_dio:1;
- unsigned int is_pcl727:1;
-};
-
-static const struct pcl726_board pcl726_boards[] = {
- {
- .name = "pcl726",
- .io_len = 0x10,
- .ao_ranges = &rangelist_726[0],
- .ao_num_ranges = ARRAY_SIZE(rangelist_726),
- .ao_nchan = 6,
- .have_dio = 1,
- }, {
- .name = "pcl727",
- .io_len = 0x20,
- .ao_ranges = &rangelist_727[0],
- .ao_num_ranges = ARRAY_SIZE(rangelist_727),
- .ao_nchan = 12,
- .have_dio = 1,
- .is_pcl727 = 1,
- }, {
- .name = "pcl728",
- .io_len = 0x08,
- .ao_num_ranges = ARRAY_SIZE(rangelist_728),
- .ao_ranges = &rangelist_728[0],
- .ao_nchan = 2,
- }, {
- .name = "acl6126",
- .io_len = 0x10,
- .irq_mask = 0x96e8,
- .ao_num_ranges = ARRAY_SIZE(rangelist_726),
- .ao_ranges = &rangelist_726[0],
- .ao_nchan = 6,
- .have_dio = 1,
- }, {
- .name = "acl6128",
- .io_len = 0x08,
- .ao_num_ranges = ARRAY_SIZE(rangelist_728),
- .ao_ranges = &rangelist_728[0],
- .ao_nchan = 2,
- },
-};
-
-struct pcl726_private {
- const struct comedi_lrange *rangelist[12];
- unsigned int cmd_running:1;
-};
-
-static int pcl726_intr_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = 0;
- return insn->n;
-}
-
-static int pcl726_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
-
- return 0;
-}
-
-static int pcl726_intr_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl726_private *devpriv = dev->private;
-
- devpriv->cmd_running = 1;
-
- return 0;
-}
-
-static int pcl726_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl726_private *devpriv = dev->private;
-
- devpriv->cmd_running = 0;
-
- return 0;
-}
-
-static irqreturn_t pcl726_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct pcl726_private *devpriv = dev->private;
-
- if (devpriv->cmd_running) {
- unsigned short val = 0;
-
- pcl726_intr_cancel(dev, s);
-
- comedi_buf_write_samples(s, &val, 1);
- comedi_handle_events(dev, s);
- }
-
- return IRQ_HANDLED;
-}
-
-static int pcl726_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- /* bipolar data to the DAC is two's complement */
- if (comedi_chan_range_is_bipolar(s, chan, range))
- val = comedi_offset_munge(s, val);
-
- /* order is important, MSB then LSB */
- outb((val >> 8) & 0xff, dev->iobase + PCL726_AO_MSB_REG(chan));
- outb(val & 0xff, dev->iobase + PCL726_AO_LSB_REG(chan));
- }
-
- return insn->n;
-}
-
-static int pcl726_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct pcl726_board *board = dev->board_ptr;
- unsigned int val;
-
- if (board->is_pcl727) {
- val = inb(dev->iobase + PCL727_DI_LSB_REG);
- val |= (inb(dev->iobase + PCL727_DI_MSB_REG) << 8);
- } else {
- val = inb(dev->iobase + PCL726_DI_LSB_REG);
- val |= (inb(dev->iobase + PCL726_DI_MSB_REG) << 8);
- }
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int pcl726_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct pcl726_board *board = dev->board_ptr;
- unsigned long io = dev->iobase;
- unsigned int mask;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (board->is_pcl727) {
- if (mask & 0x00ff)
- outb(s->state & 0xff, io + PCL727_DO_LSB_REG);
- if (mask & 0xff00)
- outb((s->state >> 8), io + PCL727_DO_MSB_REG);
- } else {
- if (mask & 0x00ff)
- outb(s->state & 0xff, io + PCL726_DO_LSB_REG);
- if (mask & 0xff00)
- outb((s->state >> 8), io + PCL726_DO_MSB_REG);
- }
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int pcl726_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct pcl726_board *board = dev->board_ptr;
- struct pcl726_private *devpriv;
- struct comedi_subdevice *s;
- int subdev;
- int ret;
- int i;
-
- ret = comedi_request_region(dev, it->options[0], board->io_len);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- /*
- * Hook up the external trigger source interrupt only if the
- * user config option is valid and the board supports interrupts.
- */
- if (it->options[1] && (board->irq_mask & (1 << it->options[1]))) {
- ret = request_irq(it->options[1], pcl726_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0) {
- /* External trigger source is from Pin-17 of CN3 */
- dev->irq = it->options[1];
- }
- }
-
- /* setup the per-channel analog output range_table_list */
- for (i = 0; i < 12; i++) {
- unsigned int opt = it->options[2 + i];
-
- if (opt < board->ao_num_ranges && i < board->ao_nchan)
- devpriv->rangelist[i] = board->ao_ranges[opt];
- else
- devpriv->rangelist[i] = &range_unknown;
- }
-
- subdev = board->have_dio ? 3 : 1;
- if (dev->irq)
- subdev++;
- ret = comedi_alloc_subdevices(dev, subdev);
- if (ret)
- return ret;
-
- subdev = 0;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = board->ao_nchan;
- s->maxdata = 0x0fff;
- s->range_table_list = devpriv->rangelist;
- s->insn_write = pcl726_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- if (board->have_dio) {
- /* Digital Input subdevice */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->insn_bits = pcl726_di_insn_bits;
- s->range_table = &range_digital;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->insn_bits = pcl726_do_insn_bits;
- s->range_table = &range_digital;
- }
-
- if (dev->irq) {
- /* Digital Input subdevice - Interrupt support */
- s = &dev->subdevices[subdev++];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl726_intr_insn_bits;
- s->len_chanlist = 1;
- s->do_cmdtest = pcl726_intr_cmdtest;
- s->do_cmd = pcl726_intr_cmd;
- s->cancel = pcl726_intr_cancel;
- }
-
- return 0;
-}
-
-static struct comedi_driver pcl726_driver = {
- .driver_name = "pcl726",
- .module = THIS_MODULE,
- .attach = pcl726_attach,
- .detach = comedi_legacy_detach,
- .board_name = &pcl726_boards[0].name,
- .num_names = ARRAY_SIZE(pcl726_boards),
- .offset = sizeof(struct pcl726_board),
-};
-module_comedi_driver(pcl726_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Advantech PCL-726 & compatibles");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
deleted file mode 100644
index 32a29129e6e8..000000000000
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ /dev/null
@@ -1,350 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * comedi/drivers/pcl730.c
- * Driver for Advantech PCL-730 and clones
- * José Luis Sánchez
- */
-
-/*
- * Driver: pcl730
- * Description: Advantech PCL-730 (& compatibles)
- * Devices: [Advantech] PCL-730 (pcl730), PCM-3730 (pcm3730), PCL-725 (pcl725),
- * PCL-733 (pcl733), PCL-734 (pcl734),
- * [ADLink] ACL-7130 (acl7130), ACL-7225b (acl7225b),
- * [ICP] ISO-730 (iso730), P8R8-DIO (p8r8dio), P16R16-DIO (p16r16dio),
- * [Diamond Systems] OPMM-1616-XT (opmm-1616-xt), PEARL-MM-P (pearl-mm-p),
- * IR104-PBF (ir104-pbf),
- * Author: José Luis Sánchez (jsanchezv@teleline.es)
- * Status: untested
- *
- * Configuration options:
- * [0] - I/O port base
- *
- * Interrupts are not supported.
- * The ACL-7130 card has an 8254 timer/counter not supported by this driver.
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-/*
- * Register map
- *
- * The register map varies slightly depending on the board type but
- * all registers are 8-bit.
- *
- * The boardinfo 'io_range' is used to allow comedi to request the
- * proper range required by the board.
- *
- * The comedi_subdevice 'private' data is used to pass the register
- * offset to the (*insn_bits) functions to read/write the correct
- * registers.
- *
- * The basic register mapping looks like this:
- *
- * BASE+0 Isolated outputs 0-7 (write) / inputs 0-7 (read)
- * BASE+1 Isolated outputs 8-15 (write) / inputs 8-15 (read)
- * BASE+2 TTL outputs 0-7 (write) / inputs 0-7 (read)
- * BASE+3 TTL outputs 8-15 (write) / inputs 8-15 (read)
- *
- * The pcm3730 board does not have register BASE+1.
- *
- * The pcl725 and p8r8dio only have registers BASE+0 and BASE+1:
- *
- * BASE+0 Isolated outputs 0-7 (write) (read back on p8r8dio)
- * BASE+1 Isolated inputs 0-7 (read)
- *
- * The acl7225b and p16r16dio boards have this register mapping:
- *
- * BASE+0 Isolated outputs 0-7 (write) (read back)
- * BASE+1 Isolated outputs 8-15 (write) (read back)
- * BASE+2 Isolated inputs 0-7 (read)
- * BASE+3 Isolated inputs 8-15 (read)
- *
- * The pcl733 and pcl733 boards have this register mapping:
- *
- * BASE+0 Isolated outputs 0-7 (write) or inputs 0-7 (read)
- * BASE+1 Isolated outputs 8-15 (write) or inputs 8-15 (read)
- * BASE+2 Isolated outputs 16-23 (write) or inputs 16-23 (read)
- * BASE+3 Isolated outputs 24-31 (write) or inputs 24-31 (read)
- *
- * The opmm-1616-xt board has this register mapping:
- *
- * BASE+0 Isolated outputs 0-7 (write) (read back)
- * BASE+1 Isolated outputs 8-15 (write) (read back)
- * BASE+2 Isolated inputs 0-7 (read)
- * BASE+3 Isolated inputs 8-15 (read)
- *
- * These registers are not currently supported:
- *
- * BASE+2 Relay select register (write)
- * BASE+3 Board reset control register (write)
- * BASE+4 Interrupt control register (write)
- * BASE+4 Change detect 7-0 status register (read)
- * BASE+5 LED control register (write)
- * BASE+5 Change detect 15-8 status register (read)
- *
- * The pearl-mm-p board has this register mapping:
- *
- * BASE+0 Isolated outputs 0-7 (write)
- * BASE+1 Isolated outputs 8-15 (write)
- *
- * The ir104-pbf board has this register mapping:
- *
- * BASE+0 Isolated outputs 0-7 (write) (read back)
- * BASE+1 Isolated outputs 8-15 (write) (read back)
- * BASE+2 Isolated outputs 16-19 (write) (read back)
- * BASE+4 Isolated inputs 0-7 (read)
- * BASE+5 Isolated inputs 8-15 (read)
- * BASE+6 Isolated inputs 16-19 (read)
- */
-
-struct pcl730_board {
- const char *name;
- unsigned int io_range;
- unsigned is_pcl725:1;
- unsigned is_acl7225b:1;
- unsigned is_ir104:1;
- unsigned has_readback:1;
- unsigned has_ttl_io:1;
- int n_subdevs;
- int n_iso_out_chan;
- int n_iso_in_chan;
- int n_ttl_chan;
-};
-
-static const struct pcl730_board pcl730_boards[] = {
- {
- .name = "pcl730",
- .io_range = 0x04,
- .has_ttl_io = 1,
- .n_subdevs = 4,
- .n_iso_out_chan = 16,
- .n_iso_in_chan = 16,
- .n_ttl_chan = 16,
- }, {
- .name = "iso730",
- .io_range = 0x04,
- .n_subdevs = 4,
- .n_iso_out_chan = 16,
- .n_iso_in_chan = 16,
- .n_ttl_chan = 16,
- }, {
- .name = "acl7130",
- .io_range = 0x08,
- .has_ttl_io = 1,
- .n_subdevs = 4,
- .n_iso_out_chan = 16,
- .n_iso_in_chan = 16,
- .n_ttl_chan = 16,
- }, {
- .name = "pcm3730",
- .io_range = 0x04,
- .has_ttl_io = 1,
- .n_subdevs = 4,
- .n_iso_out_chan = 8,
- .n_iso_in_chan = 8,
- .n_ttl_chan = 16,
- }, {
- .name = "pcl725",
- .io_range = 0x02,
- .is_pcl725 = 1,
- .n_subdevs = 2,
- .n_iso_out_chan = 8,
- .n_iso_in_chan = 8,
- }, {
- .name = "p8r8dio",
- .io_range = 0x02,
- .is_pcl725 = 1,
- .has_readback = 1,
- .n_subdevs = 2,
- .n_iso_out_chan = 8,
- .n_iso_in_chan = 8,
- }, {
- .name = "acl7225b",
- .io_range = 0x08, /* only 4 are used */
- .is_acl7225b = 1,
- .has_readback = 1,
- .n_subdevs = 2,
- .n_iso_out_chan = 16,
- .n_iso_in_chan = 16,
- }, {
- .name = "p16r16dio",
- .io_range = 0x04,
- .is_acl7225b = 1,
- .has_readback = 1,
- .n_subdevs = 2,
- .n_iso_out_chan = 16,
- .n_iso_in_chan = 16,
- }, {
- .name = "pcl733",
- .io_range = 0x04,
- .n_subdevs = 1,
- .n_iso_in_chan = 32,
- }, {
- .name = "pcl734",
- .io_range = 0x04,
- .n_subdevs = 1,
- .n_iso_out_chan = 32,
- }, {
- .name = "opmm-1616-xt",
- .io_range = 0x10,
- .is_acl7225b = 1,
- .has_readback = 1,
- .n_subdevs = 2,
- .n_iso_out_chan = 16,
- .n_iso_in_chan = 16,
- }, {
- .name = "pearl-mm-p",
- .io_range = 0x02,
- .n_subdevs = 1,
- .n_iso_out_chan = 16,
- }, {
- .name = "ir104-pbf",
- .io_range = 0x08,
- .is_ir104 = 1,
- .has_readback = 1,
- .n_iso_out_chan = 20,
- .n_iso_in_chan = 20,
- },
-};
-
-static int pcl730_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long reg = (unsigned long)s->private;
- unsigned int mask;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- if (mask & 0x00ff)
- outb(s->state & 0xff, dev->iobase + reg);
- if ((mask & 0xff00) && (s->n_chan > 8))
- outb((s->state >> 8) & 0xff, dev->iobase + reg + 1);
- if ((mask & 0xff0000) && (s->n_chan > 16))
- outb((s->state >> 16) & 0xff, dev->iobase + reg + 2);
- if ((mask & 0xff000000) && (s->n_chan > 24))
- outb((s->state >> 24) & 0xff, dev->iobase + reg + 3);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static unsigned int pcl730_get_bits(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned long reg = (unsigned long)s->private;
- unsigned int val;
-
- val = inb(dev->iobase + reg);
- if (s->n_chan > 8)
- val |= (inb(dev->iobase + reg + 1) << 8);
- if (s->n_chan > 16)
- val |= (inb(dev->iobase + reg + 2) << 16);
- if (s->n_chan > 24)
- val |= (inb(dev->iobase + reg + 3) << 24);
-
- return val;
-}
-
-static int pcl730_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = pcl730_get_bits(dev, s);
-
- return insn->n;
-}
-
-static int pcl730_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct pcl730_board *board = dev->board_ptr;
- struct comedi_subdevice *s;
- int subdev;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], board->io_range);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, board->n_subdevs);
- if (ret)
- return ret;
-
- subdev = 0;
-
- if (board->n_iso_out_chan) {
- /* Isolated Digital Outputs */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->n_iso_out_chan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl730_do_insn_bits;
- s->private = (void *)0;
-
- /* get the initial state if supported */
- if (board->has_readback)
- s->state = pcl730_get_bits(dev, s);
- }
-
- if (board->n_iso_in_chan) {
- /* Isolated Digital Inputs */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = board->n_iso_in_chan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl730_di_insn_bits;
- s->private = board->is_ir104 ? (void *)4 :
- board->is_acl7225b ? (void *)2 :
- board->is_pcl725 ? (void *)1 : (void *)0;
- }
-
- if (board->has_ttl_io) {
- /* TTL Digital Outputs */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = board->n_ttl_chan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl730_do_insn_bits;
- s->private = (void *)2;
-
- /* TTL Digital Inputs */
- s = &dev->subdevices[subdev++];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = board->n_ttl_chan;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl730_di_insn_bits;
- s->private = (void *)2;
- }
-
- return 0;
-}
-
-static struct comedi_driver pcl730_driver = {
- .driver_name = "pcl730",
- .module = THIS_MODULE,
- .attach = pcl730_attach,
- .detach = comedi_legacy_detach,
- .board_name = &pcl730_boards[0].name,
- .num_names = ARRAY_SIZE(pcl730_boards),
- .offset = sizeof(struct pcl730_board),
-};
-module_comedi_driver(pcl730_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
deleted file mode 100644
index b87ab3840eee..000000000000
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ /dev/null
@@ -1,1336 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * comedi/drivers/pcl812.c
- *
- * Author: Michal Dobes <dobes@tesnet.cz>
- *
- * hardware driver for Advantech cards
- * card: PCL-812, PCL-812PG, PCL-813, PCL-813B
- * driver: pcl812, pcl812pg, pcl813, pcl813b
- * and for ADlink cards
- * card: ACL-8112DG, ACL-8112HG, ACL-8112PG, ACL-8113, ACL-8216
- * driver: acl8112dg, acl8112hg, acl8112pg, acl8113, acl8216
- * and for ICP DAS cards
- * card: ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL,
- * driver: iso813, a821pgh, a-821pgl, a-821pglnda, a822pgh, a822pgl,
- * card: A-823PGH, A-823PGL, A-826PG
- * driver: a823pgh, a823pgl, a826pg
- */
-
-/*
- * Driver: pcl812
- * Description: Advantech PCL-812/PG, PCL-813/B,
- * ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216,
- * ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG,
- * ICP DAS ISO-813
- * Author: Michal Dobes <dobes@tesnet.cz>
- * Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg),
- * PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg),
- * ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216),
- * [ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl),
- * A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl),
- * A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg)
- * Updated: Mon, 06 Aug 2007 12:03:15 +0100
- * Status: works (I hope. My board fire up under my hands
- * and I cann't test all features.)
- *
- * This driver supports insn and cmd interfaces. Some boards support only insn
- * because their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813).
- * Data transfer over DMA is supported only when you measure only one
- * channel, this is too hardware limitation of these boards.
- *
- * Options for PCL-812:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
- * [2] - DMA (0=disable, 1, 3)
- * [3] - 0=trigger source is internal 8253 with 2MHz clock
- * 1=trigger source is external
- * [4] - 0=A/D input range is +/-10V
- * 1=A/D input range is +/-5V
- * 2=A/D input range is +/-2.5V
- * 3=A/D input range is +/-1.25V
- * 4=A/D input range is +/-0.625V
- * 5=A/D input range is +/-0.3125V
- * [5] - 0=D/A outputs 0-5V (internal reference -5V)
- * 1=D/A outputs 0-10V (internal reference -10V)
- * 2=D/A outputs unknown (external reference)
- *
- * Options for PCL-812PG, ACL-8112PG:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
- * [2] - DMA (0=disable, 1, 3)
- * [3] - 0=trigger source is internal 8253 with 2MHz clock
- * 1=trigger source is external
- * [4] - 0=A/D have max +/-5V input
- * 1=A/D have max +/-10V input
- * [5] - 0=D/A outputs 0-5V (internal reference -5V)
- * 1=D/A outputs 0-10V (internal reference -10V)
- * 2=D/A outputs unknown (external reference)
- *
- * Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
- * [2] - DMA (0=disable, 1, 3)
- * [3] - 0=trigger source is internal 8253 with 2MHz clock
- * 1=trigger source is external
- * [4] - 0=A/D channels are S.E.
- * 1=A/D channels are DIFF
- * [5] - 0=D/A outputs 0-5V (internal reference -5V)
- * 1=D/A outputs 0-10V (internal reference -10V)
- * 2=D/A outputs unknown (external reference)
- *
- * Options for A-821PGL/PGH:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- * [2] - 0=A/D channels are S.E.
- * 1=A/D channels are DIFF
- * [3] - 0=D/A output 0-5V (internal reference -5V)
- * 1=D/A output 0-10V (internal reference -10V)
- *
- * Options for A-821PGL-NDA:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- * [2] - 0=A/D channels are S.E.
- * 1=A/D channels are DIFF
- *
- * Options for PCL-813:
- * [0] - IO Base
- *
- * Options for PCL-813B:
- * [0] - IO Base
- * [1] - 0= bipolar inputs
- * 1= unipolar inputs
- *
- * Options for ACL-8113, ISO-813:
- * [0] - IO Base
- * [1] - 0= 10V bipolar inputs
- * 1= 10V unipolar inputs
- * 2= 20V bipolar inputs
- * 3= 20V unipolar inputs
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/gfp.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-#include "comedi_8254.h"
-
-/*
- * Register I/O map
- */
-#define PCL812_TIMER_BASE 0x00
-#define PCL812_AI_LSB_REG 0x04
-#define PCL812_AI_MSB_REG 0x05
-#define PCL812_AI_MSB_DRDY BIT(4)
-#define PCL812_AO_LSB_REG(x) (0x04 + ((x) * 2))
-#define PCL812_AO_MSB_REG(x) (0x05 + ((x) * 2))
-#define PCL812_DI_LSB_REG 0x06
-#define PCL812_DI_MSB_REG 0x07
-#define PCL812_STATUS_REG 0x08
-#define PCL812_STATUS_DRDY BIT(5)
-#define PCL812_RANGE_REG 0x09
-#define PCL812_MUX_REG 0x0a
-#define PCL812_MUX_CHAN(x) ((x) << 0)
-#define PCL812_MUX_CS0 BIT(4)
-#define PCL812_MUX_CS1 BIT(5)
-#define PCL812_CTRL_REG 0x0b
-#define PCL812_CTRL_TRIG(x) (((x) & 0x7) << 0)
-#define PCL812_CTRL_DISABLE_TRIG PCL812_CTRL_TRIG(0)
-#define PCL812_CTRL_SOFT_TRIG PCL812_CTRL_TRIG(1)
-#define PCL812_CTRL_PACER_DMA_TRIG PCL812_CTRL_TRIG(2)
-#define PCL812_CTRL_PACER_EOC_TRIG PCL812_CTRL_TRIG(6)
-#define PCL812_SOFTTRIG_REG 0x0c
-#define PCL812_DO_LSB_REG 0x0d
-#define PCL812_DO_MSB_REG 0x0e
-
-#define MAX_CHANLIST_LEN 256 /* length of scan list */
-
-static const struct comedi_lrange range_pcl812pg_ai = {
- 5, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- BIP_RANGE(0.3125)
- }
-};
-
-static const struct comedi_lrange range_pcl812pg2_ai = {
- 5, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range812_bipolar1_25 = {
- 1, {
- BIP_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range812_bipolar0_625 = {
- 1, {
- BIP_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range812_bipolar0_3125 = {
- 1, {
- BIP_RANGE(0.3125)
- }
-};
-
-static const struct comedi_lrange range_pcl813b_ai = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range_pcl813b2_ai = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_iso813_1_ai = {
- 5, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- BIP_RANGE(0.3125)
- }
-};
-
-static const struct comedi_lrange range_iso813_1_2_ai = {
- 5, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- UNI_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range_iso813_2_ai = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range_iso813_2_2_ai = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_acl8113_1_ai = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range_acl8113_1_2_ai = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_acl8113_2_ai = {
- 3, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range_acl8113_2_2_ai = {
- 3, {
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5)
- }
-};
-
-static const struct comedi_lrange range_acl8112dg_ai = {
- 9, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- BIP_RANGE(10)
- }
-};
-
-static const struct comedi_lrange range_acl8112hg_ai = {
- 12, {
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.005),
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01),
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_a821pgh_ai = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.005)
- }
-};
-
-enum pcl812_boardtype {
- BOARD_PCL812PG = 0, /* and ACL-8112PG */
- BOARD_PCL813B = 1,
- BOARD_PCL812 = 2,
- BOARD_PCL813 = 3,
- BOARD_ISO813 = 5,
- BOARD_ACL8113 = 6,
- BOARD_ACL8112 = 7, /* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */
- BOARD_ACL8216 = 8, /* and ICP DAS A-826PG */
- BOARD_A821 = 9, /* PGH, PGL, PGL/NDA versions */
-};
-
-struct pcl812_board {
- const char *name;
- enum pcl812_boardtype board_type;
- int n_aichan;
- int n_aochan;
- unsigned int ai_ns_min;
- const struct comedi_lrange *rangelist_ai;
- unsigned int irq_bits;
- unsigned int has_dma:1;
- unsigned int has_16bit_ai:1;
- unsigned int has_mpc508_mux:1;
- unsigned int has_dio:1;
-};
-
-static const struct pcl812_board boardtypes[] = {
- {
- .name = "pcl812",
- .board_type = BOARD_PCL812,
- .n_aichan = 16,
- .n_aochan = 2,
- .ai_ns_min = 33000,
- .rangelist_ai = &range_bipolar10,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_dio = 1,
- }, {
- .name = "pcl812pg",
- .board_type = BOARD_PCL812PG,
- .n_aichan = 16,
- .n_aochan = 2,
- .ai_ns_min = 33000,
- .rangelist_ai = &range_pcl812pg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_dio = 1,
- }, {
- .name = "acl8112pg",
- .board_type = BOARD_PCL812PG,
- .n_aichan = 16,
- .n_aochan = 2,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_pcl812pg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_dio = 1,
- }, {
- .name = "acl8112dg",
- .board_type = BOARD_ACL8112,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_acl8112dg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_mpc508_mux = 1,
- .has_dio = 1,
- }, {
- .name = "acl8112hg",
- .board_type = BOARD_ACL8112,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_acl8112hg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_mpc508_mux = 1,
- .has_dio = 1,
- }, {
- .name = "a821pgl",
- .board_type = BOARD_A821,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 1,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_pcl813b_ai,
- .irq_bits = 0x000c,
- .has_dio = 1,
- }, {
- .name = "a821pglnda",
- .board_type = BOARD_A821,
- .n_aichan = 16, /* 8 differential */
- .ai_ns_min = 10000,
- .rangelist_ai = &range_pcl813b_ai,
- .irq_bits = 0x000c,
- }, {
- .name = "a821pgh",
- .board_type = BOARD_A821,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 1,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_a821pgh_ai,
- .irq_bits = 0x000c,
- .has_dio = 1,
- }, {
- .name = "a822pgl",
- .board_type = BOARD_ACL8112,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_acl8112dg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_dio = 1,
- }, {
- .name = "a822pgh",
- .board_type = BOARD_ACL8112,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_acl8112hg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_dio = 1,
- }, {
- .name = "a823pgl",
- .board_type = BOARD_ACL8112,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 8000,
- .rangelist_ai = &range_acl8112dg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_dio = 1,
- }, {
- .name = "a823pgh",
- .board_type = BOARD_ACL8112,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 8000,
- .rangelist_ai = &range_acl8112hg_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_dio = 1,
- }, {
- .name = "pcl813",
- .board_type = BOARD_PCL813,
- .n_aichan = 32,
- .rangelist_ai = &range_pcl813b_ai,
- }, {
- .name = "pcl813b",
- .board_type = BOARD_PCL813B,
- .n_aichan = 32,
- .rangelist_ai = &range_pcl813b_ai,
- }, {
- .name = "acl8113",
- .board_type = BOARD_ACL8113,
- .n_aichan = 32,
- .rangelist_ai = &range_acl8113_1_ai,
- }, {
- .name = "iso813",
- .board_type = BOARD_ISO813,
- .n_aichan = 32,
- .rangelist_ai = &range_iso813_1_ai,
- }, {
- .name = "acl8216",
- .board_type = BOARD_ACL8216,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_pcl813b2_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_16bit_ai = 1,
- .has_mpc508_mux = 1,
- .has_dio = 1,
- }, {
- .name = "a826pg",
- .board_type = BOARD_ACL8216,
- .n_aichan = 16, /* 8 differential */
- .n_aochan = 2,
- .ai_ns_min = 10000,
- .rangelist_ai = &range_pcl813b2_ai,
- .irq_bits = 0xdcfc,
- .has_dma = 1,
- .has_16bit_ai = 1,
- .has_dio = 1,
- },
-};
-
-struct pcl812_private {
- struct comedi_isadma *dma;
- unsigned char range_correction; /* =1 we must add 1 to range number */
- unsigned int last_ai_chanspec;
- unsigned char mode_reg_int; /* stored INT number for some cards */
- unsigned int ai_poll_ptr; /* how many samples transfer poll */
- unsigned int max_812_ai_mode0_rangewait; /* settling time for gain */
- unsigned int use_diff:1;
- unsigned int use_mpc508:1;
- unsigned int use_ext_trg:1;
- unsigned int ai_dma:1;
- unsigned int ai_eos:1;
-};
-
-static void pcl812_ai_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int unread_samples)
-{
- struct pcl812_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned int bytes;
- unsigned int max_samples;
- unsigned int nsamples;
-
- comedi_isadma_disable(dma->chan);
-
- /* if using EOS, adapt DMA buffer to one scan */
- bytes = devpriv->ai_eos ? comedi_bytes_per_scan(s) : desc->maxsize;
- max_samples = comedi_bytes_to_samples(s, bytes);
-
- /*
- * Determine dma size based on the buffer size plus the number of
- * unread samples and the number of samples remaining in the command.
- */
- nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
- if (nsamples > unread_samples) {
- nsamples -= unread_samples;
- desc->size = comedi_samples_to_bytes(s, nsamples);
- comedi_isadma_program(desc);
- }
-}
-
-static void pcl812_ai_set_chan_range(struct comedi_device *dev,
- unsigned int chanspec, char wait)
-{
- struct pcl812_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int mux = 0;
-
- if (chanspec == devpriv->last_ai_chanspec)
- return;
-
- devpriv->last_ai_chanspec = chanspec;
-
- if (devpriv->use_mpc508) {
- if (devpriv->use_diff) {
- mux |= PCL812_MUX_CS0 | PCL812_MUX_CS1;
- } else {
- if (chan < 8)
- mux |= PCL812_MUX_CS0;
- else
- mux |= PCL812_MUX_CS1;
- }
- }
-
- outb(mux | PCL812_MUX_CHAN(chan), dev->iobase + PCL812_MUX_REG);
- outb(range + devpriv->range_correction, dev->iobase + PCL812_RANGE_REG);
-
- if (wait)
- /*
- * XXX this depends on selected range and can be very long for
- * some high gain ranges!
- */
- udelay(devpriv->max_812_ai_mode0_rangewait);
-}
-
-static void pcl812_ai_clear_eoc(struct comedi_device *dev)
-{
- /* writing any value clears the interrupt request */
- outb(0, dev->iobase + PCL812_STATUS_REG);
-}
-
-static void pcl812_ai_soft_trig(struct comedi_device *dev)
-{
- /* writing any value triggers a software conversion */
- outb(255, dev->iobase + PCL812_SOFTTRIG_REG);
-}
-
-static unsigned int pcl812_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- val = inb(dev->iobase + PCL812_AI_MSB_REG) << 8;
- val |= inb(dev->iobase + PCL812_AI_LSB_REG);
-
- return val & s->maxdata;
-}
-
-static int pcl812_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- if (s->maxdata > 0x0fff) {
- status = inb(dev->iobase + PCL812_STATUS_REG);
- if ((status & PCL812_STATUS_DRDY) == 0)
- return 0;
- } else {
- status = inb(dev->iobase + PCL812_AI_MSB_REG);
- if ((status & PCL812_AI_MSB_DRDY) == 0)
- return 0;
- }
- return -EBUSY;
-}
-
-static int pcl812_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- const struct pcl812_board *board = dev->board_ptr;
- struct pcl812_private *devpriv = dev->private;
- int err = 0;
- unsigned int flags;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
-
- if (devpriv->use_ext_trg)
- flags = TRIG_EXT;
- else
- flags = TRIG_TIMER;
- err |= comedi_check_trigger_src(&cmd->convert_src, flags);
-
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ai_ns_min);
- } else { /* TRIG_EXT */
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- }
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- unsigned int arg = cmd->convert_arg;
-
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcl812_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int ctrl = 0;
- unsigned int i;
-
- pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1);
-
- if (dma) { /* check if we can use DMA transfer */
- devpriv->ai_dma = 1;
- for (i = 1; i < cmd->chanlist_len; i++)
- if (cmd->chanlist[0] != cmd->chanlist[i]) {
- /* we cann't use DMA :-( */
- devpriv->ai_dma = 0;
- break;
- }
- } else {
- devpriv->ai_dma = 0;
- }
-
- devpriv->ai_poll_ptr = 0;
-
- /* don't we want wake up every scan? */
- if (cmd->flags & CMDF_WAKE_EOS) {
- devpriv->ai_eos = 1;
-
- /* DMA is useless for this situation */
- if (cmd->chanlist_len == 1)
- devpriv->ai_dma = 0;
- }
-
- if (devpriv->ai_dma) {
- /* setup and enable dma for the first buffer */
- dma->cur_dma = 0;
- pcl812_ai_setup_dma(dev, s, 0);
- }
-
- switch (cmd->convert_src) {
- case TRIG_TIMER:
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- break;
- }
-
- if (devpriv->ai_dma)
- ctrl |= PCL812_CTRL_PACER_DMA_TRIG;
- else
- ctrl |= PCL812_CTRL_PACER_EOC_TRIG;
- outb(devpriv->mode_reg_int | ctrl, dev->iobase + PCL812_CTRL_REG);
-
- return 0;
-}
-
-static bool pcl812_ai_next_chan(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg) {
- s->async->events |= COMEDI_CB_EOA;
- return false;
- }
-
- return true;
-}
-
-static void pcl812_handle_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int chan = s->async->cur_chan;
- unsigned int next_chan;
- unsigned short val;
-
- if (pcl812_ai_eoc(dev, s, NULL, 0)) {
- dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n");
- s->async->events |= COMEDI_CB_ERROR;
- return;
- }
-
- val = pcl812_ai_get_sample(dev, s);
- comedi_buf_write_samples(s, &val, 1);
-
- /* Set up next channel. Added by abbotti 2010-01-20, but untested. */
- next_chan = s->async->cur_chan;
- if (cmd->chanlist[chan] != cmd->chanlist[next_chan])
- pcl812_ai_set_chan_range(dev, cmd->chanlist[next_chan], 0);
-
- pcl812_ai_next_chan(dev, s);
-}
-
-static void transfer_from_dma_buf(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned short *ptr,
- unsigned int bufptr, unsigned int len)
-{
- unsigned int i;
- unsigned short val;
-
- for (i = len; i; i--) {
- val = ptr[bufptr++];
- comedi_buf_write_samples(s, &val, 1);
-
- if (!pcl812_ai_next_chan(dev, s))
- break;
- }
-}
-
-static void pcl812_handle_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl812_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned int nsamples;
- int bufptr;
-
- nsamples = comedi_bytes_to_samples(s, desc->size) -
- devpriv->ai_poll_ptr;
- bufptr = devpriv->ai_poll_ptr;
- devpriv->ai_poll_ptr = 0;
-
- /* restart dma with the next buffer */
- dma->cur_dma = 1 - dma->cur_dma;
- pcl812_ai_setup_dma(dev, s, nsamples);
-
- transfer_from_dma_buf(dev, s, desc->virt_addr, bufptr, nsamples);
-}
-
-static irqreturn_t pcl812_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct pcl812_private *devpriv = dev->private;
-
- if (!dev->attached) {
- pcl812_ai_clear_eoc(dev);
- return IRQ_HANDLED;
- }
-
- if (devpriv->ai_dma)
- pcl812_handle_dma(dev, s);
- else
- pcl812_handle_eoc(dev, s);
-
- pcl812_ai_clear_eoc(dev);
-
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcl812_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc;
- unsigned long flags;
- unsigned int poll;
- int ret;
-
- /* poll is valid only for DMA transfer */
- if (!devpriv->ai_dma)
- return 0;
-
- spin_lock_irqsave(&dev->spinlock, flags);
-
- poll = comedi_isadma_poll(dma);
- poll = comedi_bytes_to_samples(s, poll);
- if (poll > devpriv->ai_poll_ptr) {
- desc = &dma->desc[dma->cur_dma];
- transfer_from_dma_buf(dev, s, desc->virt_addr,
- devpriv->ai_poll_ptr,
- poll - devpriv->ai_poll_ptr);
- /* new buffer position */
- devpriv->ai_poll_ptr = poll;
-
- ret = comedi_buf_n_bytes_ready(s);
- } else {
- /* no new samples */
- ret = 0;
- }
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return ret;
-}
-
-static int pcl812_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl812_private *devpriv = dev->private;
-
- if (devpriv->ai_dma)
- comedi_isadma_disable(devpriv->dma->chan);
-
- outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
- dev->iobase + PCL812_CTRL_REG);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
- pcl812_ai_clear_eoc(dev);
- return 0;
-}
-
-static int pcl812_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pcl812_private *devpriv = dev->private;
- int ret = 0;
- int i;
-
- outb(devpriv->mode_reg_int | PCL812_CTRL_SOFT_TRIG,
- dev->iobase + PCL812_CTRL_REG);
-
- pcl812_ai_set_chan_range(dev, insn->chanspec, 1);
-
- for (i = 0; i < insn->n; i++) {
- pcl812_ai_clear_eoc(dev);
- pcl812_ai_soft_trig(dev);
-
- ret = comedi_timeout(dev, s, insn, pcl812_ai_eoc, 0);
- if (ret)
- break;
-
- data[i] = pcl812_ai_get_sample(dev, s);
- }
- outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
- dev->iobase + PCL812_CTRL_REG);
- pcl812_ai_clear_eoc(dev);
-
- return ret ? ret : insn->n;
-}
-
-static int pcl812_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outb(val & 0xff, dev->iobase + PCL812_AO_LSB_REG(chan));
- outb((val >> 8) & 0x0f, dev->iobase + PCL812_AO_MSB_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pcl812_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + PCL812_DI_LSB_REG) |
- (inb(dev->iobase + PCL812_DI_MSB_REG) << 8);
-
- return insn->n;
-}
-
-static int pcl812_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- outb(s->state & 0xff, dev->iobase + PCL812_DO_LSB_REG);
- outb((s->state >> 8), dev->iobase + PCL812_DO_MSB_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void pcl812_reset(struct comedi_device *dev)
-{
- const struct pcl812_board *board = dev->board_ptr;
- struct pcl812_private *devpriv = dev->private;
- unsigned int chan;
-
- /* disable analog input trigger */
- outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
- dev->iobase + PCL812_CTRL_REG);
- pcl812_ai_clear_eoc(dev);
-
- /*
- * Invalidate last_ai_chanspec then set analog input to
- * known channel/range.
- */
- devpriv->last_ai_chanspec = CR_PACK(16, 0, 0);
- pcl812_ai_set_chan_range(dev, CR_PACK(0, 0, 0), 0);
-
- /* set analog output channels to 0V */
- for (chan = 0; chan < board->n_aochan; chan++) {
- outb(0, dev->iobase + PCL812_AO_LSB_REG(chan));
- outb(0, dev->iobase + PCL812_AO_MSB_REG(chan));
- }
-
- /* set all digital outputs low */
- if (board->has_dio) {
- outb(0, dev->iobase + PCL812_DO_MSB_REG);
- outb(0, dev->iobase + PCL812_DO_LSB_REG);
- }
-}
-
-static void pcl812_set_ai_range_table(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_devconfig *it)
-{
- const struct pcl812_board *board = dev->board_ptr;
- struct pcl812_private *devpriv = dev->private;
-
- switch (board->board_type) {
- case BOARD_PCL812PG:
- if (it->options[4] == 1)
- s->range_table = &range_pcl812pg2_ai;
- else
- s->range_table = board->rangelist_ai;
- break;
- case BOARD_PCL812:
- switch (it->options[4]) {
- case 0:
- s->range_table = &range_bipolar10;
- break;
- case 1:
- s->range_table = &range_bipolar5;
- break;
- case 2:
- s->range_table = &range_bipolar2_5;
- break;
- case 3:
- s->range_table = &range812_bipolar1_25;
- break;
- case 4:
- s->range_table = &range812_bipolar0_625;
- break;
- case 5:
- s->range_table = &range812_bipolar0_3125;
- break;
- default:
- s->range_table = &range_bipolar10;
- break;
- }
- break;
- case BOARD_PCL813B:
- if (it->options[1] == 1)
- s->range_table = &range_pcl813b2_ai;
- else
- s->range_table = board->rangelist_ai;
- break;
- case BOARD_ISO813:
- switch (it->options[1]) {
- case 0:
- s->range_table = &range_iso813_1_ai;
- break;
- case 1:
- s->range_table = &range_iso813_1_2_ai;
- break;
- case 2:
- s->range_table = &range_iso813_2_ai;
- devpriv->range_correction = 1;
- break;
- case 3:
- s->range_table = &range_iso813_2_2_ai;
- devpriv->range_correction = 1;
- break;
- default:
- s->range_table = &range_iso813_1_ai;
- break;
- }
- break;
- case BOARD_ACL8113:
- switch (it->options[1]) {
- case 0:
- s->range_table = &range_acl8113_1_ai;
- break;
- case 1:
- s->range_table = &range_acl8113_1_2_ai;
- break;
- case 2:
- s->range_table = &range_acl8113_2_ai;
- devpriv->range_correction = 1;
- break;
- case 3:
- s->range_table = &range_acl8113_2_2_ai;
- devpriv->range_correction = 1;
- break;
- default:
- s->range_table = &range_acl8113_1_ai;
- break;
- }
- break;
- default:
- s->range_table = board->rangelist_ai;
- break;
- }
-}
-
-static void pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
-{
- struct pcl812_private *devpriv = dev->private;
-
- /* only DMA channels 3 and 1 are valid */
- if (!(dma_chan == 3 || dma_chan == 1))
- return;
-
- /* DMA uses two 8K buffers */
- devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
- PAGE_SIZE * 2, COMEDI_ISADMA_READ);
-}
-
-static void pcl812_free_dma(struct comedi_device *dev)
-{
- struct pcl812_private *devpriv = dev->private;
-
- if (devpriv)
- comedi_isadma_free(devpriv->dma);
-}
-
-static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct pcl812_board *board = dev->board_ptr;
- struct pcl812_private *devpriv;
- struct comedi_subdevice *s;
- int n_subdevices;
- int subdev;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- if (board->irq_bits) {
- dev->pacer = comedi_8254_init(dev->iobase + PCL812_TIMER_BASE,
- I8254_OSC_BASE_2MHZ,
- I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- if ((1 << it->options[1]) & board->irq_bits) {
- ret = request_irq(it->options[1], pcl812_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
- }
-
- /* we need an IRQ to do DMA on channel 3 or 1 */
- if (dev->irq && board->has_dma)
- pcl812_alloc_dma(dev, it->options[2]);
-
- /* differential analog inputs? */
- switch (board->board_type) {
- case BOARD_A821:
- if (it->options[2] == 1)
- devpriv->use_diff = 1;
- break;
- case BOARD_ACL8112:
- case BOARD_ACL8216:
- if (it->options[4] == 1)
- devpriv->use_diff = 1;
- break;
- default:
- break;
- }
-
- n_subdevices = 1; /* all boardtypes have analog inputs */
- if (board->n_aochan > 0)
- n_subdevices++;
- if (board->has_dio)
- n_subdevices += 2;
-
- ret = comedi_alloc_subdevices(dev, n_subdevices);
- if (ret)
- return ret;
-
- subdev = 0;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE;
- if (devpriv->use_diff) {
- s->subdev_flags |= SDF_DIFF;
- s->n_chan = board->n_aichan / 2;
- } else {
- s->subdev_flags |= SDF_GROUND;
- s->n_chan = board->n_aichan;
- }
- s->maxdata = board->has_16bit_ai ? 0xffff : 0x0fff;
-
- pcl812_set_ai_range_table(dev, s, it);
-
- s->insn_read = pcl812_ai_insn_read;
-
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = MAX_CHANLIST_LEN;
- s->do_cmdtest = pcl812_ai_cmdtest;
- s->do_cmd = pcl812_ai_cmd;
- s->poll = pcl812_ai_poll;
- s->cancel = pcl812_ai_cancel;
- }
-
- devpriv->use_mpc508 = board->has_mpc508_mux;
-
- subdev++;
-
- /* analog output */
- if (board->n_aochan > 0) {
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = board->n_aochan;
- s->maxdata = 0xfff;
- switch (board->board_type) {
- case BOARD_A821:
- if (it->options[3] == 1)
- s->range_table = &range_unipolar10;
- else
- s->range_table = &range_unipolar5;
- break;
- case BOARD_PCL812:
- case BOARD_ACL8112:
- case BOARD_PCL812PG:
- case BOARD_ACL8216:
- switch (it->options[5]) {
- case 1:
- s->range_table = &range_unipolar10;
- break;
- case 2:
- s->range_table = &range_unknown;
- break;
- default:
- s->range_table = &range_unipolar5;
- break;
- }
- break;
- default:
- s->range_table = &range_unipolar5;
- break;
- }
- s->insn_write = pcl812_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- subdev++;
- }
-
- if (board->has_dio) {
- /* Digital Input subdevice */
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl812_di_insn_bits;
- subdev++;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[subdev];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl812_do_insn_bits;
- subdev++;
- }
-
- switch (board->board_type) {
- case BOARD_ACL8216:
- case BOARD_PCL812PG:
- case BOARD_PCL812:
- case BOARD_ACL8112:
- devpriv->max_812_ai_mode0_rangewait = 1;
- if (it->options[3] > 0)
- /* we use external trigger */
- devpriv->use_ext_trg = 1;
- break;
- case BOARD_A821:
- devpriv->max_812_ai_mode0_rangewait = 1;
- devpriv->mode_reg_int = (dev->irq << 4) & 0xf0;
- break;
- case BOARD_PCL813B:
- case BOARD_PCL813:
- case BOARD_ISO813:
- case BOARD_ACL8113:
- /* maybe there must by greatest timeout */
- devpriv->max_812_ai_mode0_rangewait = 5;
- break;
- }
-
- pcl812_reset(dev);
-
- return 0;
-}
-
-static void pcl812_detach(struct comedi_device *dev)
-{
- pcl812_free_dma(dev);
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver pcl812_driver = {
- .driver_name = "pcl812",
- .module = THIS_MODULE,
- .attach = pcl812_attach,
- .detach = pcl812_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct pcl812_board),
-};
-module_comedi_driver(pcl812_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
deleted file mode 100644
index c368a337a0ae..000000000000
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ /dev/null
@@ -1,696 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * pcl816.c
- * Comedi driver for Advantech PCL-816 cards
- *
- * Author: Juan Grigera <juan@grigera.com.ar>
- * based on pcl818 by Michal Dobes <dobes@tesnet.cz> and bits of pcl812
- */
-
-/*
- * Driver: pcl816
- * Description: Advantech PCL-816 cards, PCL-814
- * Devices: [Advantech] PCL-816 (pcl816), PCL-814B (pcl814b)
- * Author: Juan Grigera <juan@grigera.com.ar>
- * Status: works
- * Updated: Tue, 2 Apr 2002 23:15:21 -0800
- *
- * PCL 816 and 814B have 16 SE/DIFF ADCs, 16 DACs, 16 DI and 16 DO.
- * Differences are at resolution (16 vs 12 bits).
- *
- * The driver support AI command mode, other subdevices not written.
- *
- * Analog output and digital input and output are not supported.
- *
- * Configuration Options:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- * [2] - DMA (0=disable, 1, 3)
- * [3] - 0, 10=10MHz clock for 8254
- * 1= 1MHz clock for 8254
- */
-
-#include <linux/module.h>
-#include <linux/gfp.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-#include "comedi_8254.h"
-
-/*
- * Register I/O map
- */
-#define PCL816_DO_DI_LSB_REG 0x00
-#define PCL816_DO_DI_MSB_REG 0x01
-#define PCL816_TIMER_BASE 0x04
-#define PCL816_AI_LSB_REG 0x08
-#define PCL816_AI_MSB_REG 0x09
-#define PCL816_RANGE_REG 0x09
-#define PCL816_CLRINT_REG 0x0a
-#define PCL816_MUX_REG 0x0b
-#define PCL816_MUX_SCAN(_first, _last) (((_last) << 4) | (_first))
-#define PCL816_CTRL_REG 0x0c
-#define PCL816_CTRL_SOFT_TRIG BIT(0)
-#define PCL816_CTRL_PACER_TRIG BIT(1)
-#define PCL816_CTRL_EXT_TRIG BIT(2)
-#define PCL816_CTRL_POE BIT(3)
-#define PCL816_CTRL_DMAEN BIT(4)
-#define PCL816_CTRL_INTEN BIT(5)
-#define PCL816_CTRL_DMASRC_SLOT(x) (((x) & 0x3) << 6)
-#define PCL816_STATUS_REG 0x0d
-#define PCL816_STATUS_NEXT_CHAN_MASK (0xf << 0)
-#define PCL816_STATUS_INTSRC_SLOT(x) (((x) & 0x3) << 4)
-#define PCL816_STATUS_INTSRC_DMA PCL816_STATUS_INTSRC_SLOT(3)
-#define PCL816_STATUS_INTSRC_MASK PCL816_STATUS_INTSRC_SLOT(3)
-#define PCL816_STATUS_INTACT BIT(6)
-#define PCL816_STATUS_DRDY BIT(7)
-
-#define MAGIC_DMA_WORD 0x5a5a
-
-static const struct comedi_lrange range_pcl816 = {
- 8, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25)
- }
-};
-
-struct pcl816_board {
- const char *name;
- int ai_maxdata;
- int ai_chanlist;
-};
-
-static const struct pcl816_board boardtypes[] = {
- {
- .name = "pcl816",
- .ai_maxdata = 0xffff,
- .ai_chanlist = 1024,
- }, {
- .name = "pcl814b",
- .ai_maxdata = 0x3fff,
- .ai_chanlist = 1024,
- },
-};
-
-struct pcl816_private {
- struct comedi_isadma *dma;
- unsigned int ai_poll_ptr; /* how many sampes transfer poll */
- unsigned int ai_cmd_running:1;
- unsigned int ai_cmd_canceled:1;
-};
-
-static void pcl816_ai_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int unread_samples)
-{
- struct pcl816_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
- unsigned int nsamples;
-
- comedi_isadma_disable(dma->chan);
-
- /*
- * Determine dma size based on the buffer maxsize plus the number of
- * unread samples and the number of samples remaining in the command.
- */
- nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
- if (nsamples > unread_samples) {
- nsamples -= unread_samples;
- desc->size = comedi_samples_to_bytes(s, nsamples);
- comedi_isadma_program(desc);
- }
-}
-
-static void pcl816_ai_set_chan_range(struct comedi_device *dev,
- unsigned int chan,
- unsigned int range)
-{
- outb(chan, dev->iobase + PCL816_MUX_REG);
- outb(range, dev->iobase + PCL816_RANGE_REG);
-}
-
-static void pcl816_ai_set_chan_scan(struct comedi_device *dev,
- unsigned int first_chan,
- unsigned int last_chan)
-{
- outb(PCL816_MUX_SCAN(first_chan, last_chan),
- dev->iobase + PCL816_MUX_REG);
-}
-
-static void pcl816_ai_setup_chanlist(struct comedi_device *dev,
- unsigned int *chanlist,
- unsigned int seglen)
-{
- unsigned int first_chan = CR_CHAN(chanlist[0]);
- unsigned int last_chan;
- unsigned int range;
- unsigned int i;
-
- /* store range list to card */
- for (i = 0; i < seglen; i++) {
- last_chan = CR_CHAN(chanlist[i]);
- range = CR_RANGE(chanlist[i]);
-
- pcl816_ai_set_chan_range(dev, last_chan, range);
- }
-
- udelay(1);
-
- pcl816_ai_set_chan_scan(dev, first_chan, last_chan);
-}
-
-static void pcl816_ai_clear_eoc(struct comedi_device *dev)
-{
- /* writing any value clears the interrupt request */
- outb(0, dev->iobase + PCL816_CLRINT_REG);
-}
-
-static void pcl816_ai_soft_trig(struct comedi_device *dev)
-{
- /* writing any value triggers a software conversion */
- outb(0, dev->iobase + PCL816_AI_LSB_REG);
-}
-
-static unsigned int pcl816_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- val = inb(dev->iobase + PCL816_AI_MSB_REG) << 8;
- val |= inb(dev->iobase + PCL816_AI_LSB_REG);
-
- return val & s->maxdata;
-}
-
-static int pcl816_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + PCL816_STATUS_REG);
- if ((status & PCL816_STATUS_DRDY) == 0)
- return 0;
- return -EBUSY;
-}
-
-static bool pcl816_ai_next_chan(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg) {
- s->async->events |= COMEDI_CB_EOA;
- return false;
- }
-
- return true;
-}
-
-static void transfer_from_dma_buf(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned short *ptr,
- unsigned int bufptr, unsigned int len)
-{
- unsigned short val;
- int i;
-
- for (i = 0; i < len; i++) {
- val = ptr[bufptr++];
- comedi_buf_write_samples(s, &val, 1);
-
- if (!pcl816_ai_next_chan(dev, s))
- return;
- }
-}
-
-static irqreturn_t pcl816_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct pcl816_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned int nsamples;
- unsigned int bufptr;
-
- if (!dev->attached || !devpriv->ai_cmd_running) {
- pcl816_ai_clear_eoc(dev);
- return IRQ_HANDLED;
- }
-
- if (devpriv->ai_cmd_canceled) {
- devpriv->ai_cmd_canceled = 0;
- pcl816_ai_clear_eoc(dev);
- return IRQ_HANDLED;
- }
-
- nsamples = comedi_bytes_to_samples(s, desc->size) -
- devpriv->ai_poll_ptr;
- bufptr = devpriv->ai_poll_ptr;
- devpriv->ai_poll_ptr = 0;
-
- /* restart dma with the next buffer */
- dma->cur_dma = 1 - dma->cur_dma;
- pcl816_ai_setup_dma(dev, s, nsamples);
-
- transfer_from_dma_buf(dev, s, desc->virt_addr, bufptr, nsamples);
-
- pcl816_ai_clear_eoc(dev);
-
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static int check_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chanlist,
- unsigned int chanlen)
-{
- unsigned int chansegment[16];
- unsigned int i, nowmustbechan, seglen;
-
- /* correct channel and range number check itself comedi/range.c */
- if (chanlen < 1) {
- dev_err(dev->class_dev, "range/channel list is empty!\n");
- return 0;
- }
-
- if (chanlen > 1) {
- /* first channel is every time ok */
- chansegment[0] = chanlist[0];
- for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
- /* we detect loop, this must by finish */
- if (chanlist[0] == chanlist[i])
- break;
- nowmustbechan =
- (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
- if (nowmustbechan != CR_CHAN(chanlist[i])) {
- /* channel list isn't continuous :-( */
- dev_dbg(dev->class_dev,
- "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
- i, CR_CHAN(chanlist[i]), nowmustbechan,
- CR_CHAN(chanlist[0]));
- return 0;
- }
- /* well, this is next correct channel in list */
- chansegment[i] = chanlist[i];
- }
-
- /* check whole chanlist */
- for (i = 0; i < chanlen; i++) {
- if (chanlist[i] != chansegment[i % seglen]) {
- dev_dbg(dev->class_dev,
- "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
- i, CR_CHAN(chansegment[i]),
- CR_RANGE(chansegment[i]),
- CR_AREF(chansegment[i]),
- CR_CHAN(chanlist[i % seglen]),
- CR_RANGE(chanlist[i % seglen]),
- CR_AREF(chansegment[i % seglen]));
- return 0; /* chan/gain list is strange */
- }
- }
- } else {
- seglen = 1;
- }
-
- return seglen; /* we can serve this with MUX logic */
-}
-
-static int pcl816_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_EXT | TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER)
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
- else /* TRIG_EXT */
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
- if (cmd->convert_src == TRIG_TIMER) {
- unsigned int arg = cmd->convert_arg;
-
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* step 5: complain about special chanlist considerations */
-
- if (cmd->chanlist) {
- if (!check_channel_list(dev, s, cmd->chanlist,
- cmd->chanlist_len))
- return 5; /* incorrect channels list */
- }
-
- return 0;
-}
-
-static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcl816_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int ctrl;
- unsigned int seglen;
-
- if (devpriv->ai_cmd_running)
- return -EBUSY;
-
- seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
- if (seglen < 1)
- return -EINVAL;
- pcl816_ai_setup_chanlist(dev, cmd->chanlist, seglen);
- udelay(1);
-
- devpriv->ai_cmd_running = 1;
- devpriv->ai_poll_ptr = 0;
- devpriv->ai_cmd_canceled = 0;
-
- /* setup and enable dma for the first buffer */
- dma->cur_dma = 0;
- pcl816_ai_setup_dma(dev, s, 0);
-
- comedi_8254_set_mode(dev->pacer, 0, I8254_MODE1 | I8254_BINARY);
- comedi_8254_write(dev->pacer, 0, 0x0ff);
- udelay(1);
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
-
- ctrl = PCL816_CTRL_INTEN | PCL816_CTRL_DMAEN |
- PCL816_CTRL_DMASRC_SLOT(0);
- if (cmd->convert_src == TRIG_TIMER)
- ctrl |= PCL816_CTRL_PACER_TRIG;
- else /* TRIG_EXT */
- ctrl |= PCL816_CTRL_EXT_TRIG;
-
- outb(ctrl, dev->iobase + PCL816_CTRL_REG);
- outb((dma->chan << 4) | dev->irq,
- dev->iobase + PCL816_STATUS_REG);
-
- return 0;
-}
-
-static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcl816_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc;
- unsigned long flags;
- unsigned int poll;
- int ret;
-
- spin_lock_irqsave(&dev->spinlock, flags);
-
- poll = comedi_isadma_poll(dma);
- poll = comedi_bytes_to_samples(s, poll);
- if (poll > devpriv->ai_poll_ptr) {
- desc = &dma->desc[dma->cur_dma];
- transfer_from_dma_buf(dev, s, desc->virt_addr,
- devpriv->ai_poll_ptr,
- poll - devpriv->ai_poll_ptr);
- /* new buffer position */
- devpriv->ai_poll_ptr = poll;
-
- comedi_handle_events(dev, s);
-
- ret = comedi_buf_n_bytes_ready(s);
- } else {
- /* no new samples */
- ret = 0;
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return ret;
-}
-
-static int pcl816_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl816_private *devpriv = dev->private;
-
- if (!devpriv->ai_cmd_running)
- return 0;
-
- outb(0, dev->iobase + PCL816_CTRL_REG);
- pcl816_ai_clear_eoc(dev);
-
- comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
-
- devpriv->ai_cmd_running = 0;
- devpriv->ai_cmd_canceled = 1;
-
- return 0;
-}
-
-static int pcl816_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int ret = 0;
- int i;
-
- outb(PCL816_CTRL_SOFT_TRIG, dev->iobase + PCL816_CTRL_REG);
-
- pcl816_ai_set_chan_range(dev, chan, range);
- pcl816_ai_set_chan_scan(dev, chan, chan);
-
- for (i = 0; i < insn->n; i++) {
- pcl816_ai_clear_eoc(dev);
- pcl816_ai_soft_trig(dev);
-
- ret = comedi_timeout(dev, s, insn, pcl816_ai_eoc, 0);
- if (ret)
- break;
-
- data[i] = pcl816_ai_get_sample(dev, s);
- }
- outb(0, dev->iobase + PCL816_CTRL_REG);
- pcl816_ai_clear_eoc(dev);
-
- return ret ? ret : insn->n;
-}
-
-static int pcl816_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + PCL816_DO_DI_LSB_REG) |
- (inb(dev->iobase + PCL816_DO_DI_MSB_REG) << 8);
-
- return insn->n;
-}
-
-static int pcl816_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- outb(s->state & 0xff, dev->iobase + PCL816_DO_DI_LSB_REG);
- outb((s->state >> 8), dev->iobase + PCL816_DO_DI_MSB_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void pcl816_reset(struct comedi_device *dev)
-{
- outb(0, dev->iobase + PCL816_CTRL_REG);
- pcl816_ai_set_chan_range(dev, 0, 0);
- pcl816_ai_clear_eoc(dev);
-
- /* set all digital outputs low */
- outb(0, dev->iobase + PCL816_DO_DI_LSB_REG);
- outb(0, dev->iobase + PCL816_DO_DI_MSB_REG);
-}
-
-static void pcl816_alloc_irq_and_dma(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct pcl816_private *devpriv = dev->private;
- unsigned int irq_num = it->options[1];
- unsigned int dma_chan = it->options[2];
-
- /* only IRQs 2-7 and DMA channels 3 and 1 are valid */
- if (!(irq_num >= 2 && irq_num <= 7) ||
- !(dma_chan == 3 || dma_chan == 1))
- return;
-
- if (request_irq(irq_num, pcl816_interrupt, 0, dev->board_name, dev))
- return;
-
- /* DMA uses two 16K buffers */
- devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
- PAGE_SIZE * 4, COMEDI_ISADMA_READ);
- if (!devpriv->dma)
- free_irq(irq_num, dev);
- else
- dev->irq = irq_num;
-}
-
-static void pcl816_free_dma(struct comedi_device *dev)
-{
- struct pcl816_private *devpriv = dev->private;
-
- if (devpriv)
- comedi_isadma_free(devpriv->dma);
-}
-
-static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct pcl816_board *board = dev->board_ptr;
- struct pcl816_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- /* an IRQ and DMA are required to support async commands */
- pcl816_alloc_irq_and_dma(dev, it);
-
- dev->pacer = comedi_8254_init(dev->iobase + PCL816_TIMER_BASE,
- I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_CMD_READ | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = board->ai_maxdata;
- s->range_table = &range_pcl816;
- s->insn_read = pcl816_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = board->ai_chanlist;
- s->do_cmdtest = pcl816_ai_cmdtest;
- s->do_cmd = pcl816_ai_cmd;
- s->poll = pcl816_ai_poll;
- s->cancel = pcl816_ai_cancel;
- }
-
- /* Piggyback Slot1 subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_UNUSED;
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl816_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl816_do_insn_bits;
-
- pcl816_reset(dev);
-
- return 0;
-}
-
-static void pcl816_detach(struct comedi_device *dev)
-{
- if (dev->private) {
- pcl816_ai_cancel(dev, dev->read_subdev);
- pcl816_reset(dev);
- }
- pcl816_free_dma(dev);
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver pcl816_driver = {
- .driver_name = "pcl816",
- .module = THIS_MODULE,
- .attach = pcl816_attach,
- .detach = pcl816_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct pcl816_board),
-};
-module_comedi_driver(pcl816_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
deleted file mode 100644
index f4b4a686c710..000000000000
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ /dev/null
@@ -1,1137 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * comedi/drivers/pcl818.c
- *
- * Driver: pcl818
- * Description: Advantech PCL-818 cards, PCL-718
- * Author: Michal Dobes <dobes@tesnet.cz>
- * Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
- * PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
- * PCL-718 (pcl718)
- * Status: works
- *
- * All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
- * Differences are only at maximal sample speed, range list and FIFO
- * support.
- * The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
- * only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
- * PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
- * but this code is untested.
- * A word or two about DMA. Driver support DMA operations at two ways:
- * 1) DMA uses two buffers and after one is filled then is generated
- * INT and DMA restart with second buffer. With this mode I'm unable run
- * more that 80Ksamples/secs without data dropouts on K6/233.
- * 2) DMA uses one buffer and run in autoinit mode and the data are
- * from DMA buffer moved on the fly with 2kHz interrupts from RTC.
- * This mode is used if the interrupt 8 is available for allocation.
- * If not, then first DMA mode is used. With this I can run at
- * full speed one card (100ksamples/secs) or two cards with
- * 60ksamples/secs each (more is problem on account of ISA limitations).
- * To use this mode you must have compiled kernel with disabled
- * "Enhanced Real Time Clock Support".
- * Maybe you can have problems if you use xntpd or similar.
- * If you've data dropouts with DMA mode 2 then:
- * a) disable IDE DMA
- * b) switch text mode console to fb.
- *
- * Options for PCL-818L:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- * [2] - DMA (0=disable, 1, 3)
- * [3] - 0, 10=10MHz clock for 8254
- * 1= 1MHz clock for 8254
- * [4] - 0, 5=A/D input -5V.. +5V
- * 1, 10=A/D input -10V..+10V
- * [5] - 0, 5=D/A output 0-5V (internal reference -5V)
- * 1, 10=D/A output 0-10V (internal reference -10V)
- * 2 =D/A output unknown (external reference)
- *
- * Options for PCL-818, PCL-818H:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- * [2] - DMA (0=disable, 1, 3)
- * [3] - 0, 10=10MHz clock for 8254
- * 1= 1MHz clock for 8254
- * [4] - 0, 5=D/A output 0-5V (internal reference -5V)
- * 1, 10=D/A output 0-10V (internal reference -10V)
- * 2 =D/A output unknown (external reference)
- *
- * Options for PCL-818HD, PCL-818HG:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- * [2] - DMA/FIFO (-1=use FIFO, 0=disable both FIFO and DMA,
- * 1=use DMA ch 1, 3=use DMA ch 3)
- * [3] - 0, 10=10MHz clock for 8254
- * 1= 1MHz clock for 8254
- * [4] - 0, 5=D/A output 0-5V (internal reference -5V)
- * 1, 10=D/A output 0-10V (internal reference -10V)
- * 2 =D/A output unknown (external reference)
- *
- * Options for PCL-718:
- * [0] - IO Base
- * [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
- * [2] - DMA (0=disable, 1, 3)
- * [3] - 0, 10=10MHz clock for 8254
- * 1= 1MHz clock for 8254
- * [4] - 0=A/D Range is +/-10V
- * 1= +/-5V
- * 2= +/-2.5V
- * 3= +/-1V
- * 4= +/-0.5V
- * 5= user defined bipolar
- * 6= 0-10V
- * 7= 0-5V
- * 8= 0-2V
- * 9= 0-1V
- * 10= user defined unipolar
- * [5] - 0, 5=D/A outputs 0-5V (internal reference -5V)
- * 1, 10=D/A outputs 0-10V (internal reference -10V)
- * 2=D/A outputs unknown (external reference)
- * [6] - 0, 60=max 60kHz A/D sampling
- * 1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
- *
- */
-
-#include <linux/module.h>
-#include <linux/gfp.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "comedi_isadma.h"
-#include "comedi_8254.h"
-
-/*
- * Register I/O map
- */
-#define PCL818_AI_LSB_REG 0x00
-#define PCL818_AI_MSB_REG 0x01
-#define PCL818_RANGE_REG 0x01
-#define PCL818_MUX_REG 0x02
-#define PCL818_MUX_SCAN(_first, _last) (((_last) << 4) | (_first))
-#define PCL818_DO_DI_LSB_REG 0x03
-#define PCL818_AO_LSB_REG(x) (0x04 + ((x) * 2))
-#define PCL818_AO_MSB_REG(x) (0x05 + ((x) * 2))
-#define PCL818_STATUS_REG 0x08
-#define PCL818_STATUS_NEXT_CHAN_MASK (0xf << 0)
-#define PCL818_STATUS_INT BIT(4)
-#define PCL818_STATUS_MUX BIT(5)
-#define PCL818_STATUS_UNI BIT(6)
-#define PCL818_STATUS_EOC BIT(7)
-#define PCL818_CTRL_REG 0x09
-#define PCL818_CTRL_TRIG(x) (((x) & 0x3) << 0)
-#define PCL818_CTRL_DISABLE_TRIG PCL818_CTRL_TRIG(0)
-#define PCL818_CTRL_SOFT_TRIG PCL818_CTRL_TRIG(1)
-#define PCL818_CTRL_EXT_TRIG PCL818_CTRL_TRIG(2)
-#define PCL818_CTRL_PACER_TRIG PCL818_CTRL_TRIG(3)
-#define PCL818_CTRL_DMAE BIT(2)
-#define PCL818_CTRL_IRQ(x) ((x) << 4)
-#define PCL818_CTRL_INTE BIT(7)
-#define PCL818_CNTENABLE_REG 0x0a
-#define PCL818_CNTENABLE_PACER_TRIG0 BIT(0)
-#define PCL818_CNTENABLE_CNT0_INT_CLK BIT(1) /* 0=ext clk */
-#define PCL818_DO_DI_MSB_REG 0x0b
-#define PCL818_TIMER_BASE 0x0c
-
-/* W: fifo enable/disable */
-#define PCL818_FI_ENABLE 6
-/* W: fifo interrupt clear */
-#define PCL818_FI_INTCLR 20
-/* W: fifo interrupt clear */
-#define PCL818_FI_FLUSH 25
-/* R: fifo status */
-#define PCL818_FI_STATUS 25
-/* R: one record from FIFO */
-#define PCL818_FI_DATALO 23
-#define PCL818_FI_DATAHI 24
-
-#define MAGIC_DMA_WORD 0x5a5a
-
-static const struct comedi_lrange range_pcl818h_ai = {
- 9, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625),
- UNI_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(2.5),
- UNI_RANGE(1.25),
- BIP_RANGE(10)
- }
-};
-
-static const struct comedi_lrange range_pcl818hg_ai = {
- 10, {
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.005),
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.01),
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_pcl818l_l_ai = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25),
- BIP_RANGE(0.625)
- }
-};
-
-static const struct comedi_lrange range_pcl818l_h_ai = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-
-static const struct comedi_lrange range718_bipolar1 = {
- 1, {
- BIP_RANGE(1)
- }
-};
-
-static const struct comedi_lrange range718_bipolar0_5 = {
- 1, {
- BIP_RANGE(0.5)
- }
-};
-
-static const struct comedi_lrange range718_unipolar2 = {
- 1, {
- UNI_RANGE(2)
- }
-};
-
-static const struct comedi_lrange range718_unipolar1 = {
- 1, {
- BIP_RANGE(1)
- }
-};
-
-struct pcl818_board {
- const char *name;
- unsigned int ns_min;
- int n_aochan;
- const struct comedi_lrange *ai_range_type;
- unsigned int has_dma:1;
- unsigned int has_fifo:1;
- unsigned int is_818:1;
-};
-
-static const struct pcl818_board boardtypes[] = {
- {
- .name = "pcl818l",
- .ns_min = 25000,
- .n_aochan = 1,
- .ai_range_type = &range_pcl818l_l_ai,
- .has_dma = 1,
- .is_818 = 1,
- }, {
- .name = "pcl818h",
- .ns_min = 10000,
- .n_aochan = 1,
- .ai_range_type = &range_pcl818h_ai,
- .has_dma = 1,
- .is_818 = 1,
- }, {
- .name = "pcl818hd",
- .ns_min = 10000,
- .n_aochan = 1,
- .ai_range_type = &range_pcl818h_ai,
- .has_dma = 1,
- .has_fifo = 1,
- .is_818 = 1,
- }, {
- .name = "pcl818hg",
- .ns_min = 10000,
- .n_aochan = 1,
- .ai_range_type = &range_pcl818hg_ai,
- .has_dma = 1,
- .has_fifo = 1,
- .is_818 = 1,
- }, {
- .name = "pcl818",
- .ns_min = 10000,
- .n_aochan = 2,
- .ai_range_type = &range_pcl818h_ai,
- .has_dma = 1,
- .is_818 = 1,
- }, {
- .name = "pcl718",
- .ns_min = 16000,
- .n_aochan = 2,
- .ai_range_type = &range_unipolar5,
- .has_dma = 1,
- }, {
- .name = "pcm3718",
- .ns_min = 10000,
- .ai_range_type = &range_pcl818h_ai,
- .has_dma = 1,
- .is_818 = 1,
- },
-};
-
-struct pcl818_private {
- struct comedi_isadma *dma;
- /* manimal allowed delay between samples (in us) for actual card */
- unsigned int ns_min;
- /* MUX setting for actual AI operations */
- unsigned int act_chanlist[16];
- unsigned int act_chanlist_len; /* how long is actual MUX list */
- unsigned int act_chanlist_pos; /* actual position in MUX list */
- unsigned int usefifo:1;
- unsigned int ai_cmd_running:1;
- unsigned int ai_cmd_canceled:1;
-};
-
-static void pcl818_ai_setup_dma(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int unread_samples)
-{
- struct pcl818_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
- unsigned int nsamples;
-
- comedi_isadma_disable(dma->chan);
-
- /*
- * Determine dma size based on the buffer maxsize plus the number of
- * unread samples and the number of samples remaining in the command.
- */
- nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
- if (nsamples > unread_samples) {
- nsamples -= unread_samples;
- desc->size = comedi_samples_to_bytes(s, nsamples);
- comedi_isadma_program(desc);
- }
-}
-
-static void pcl818_ai_set_chan_range(struct comedi_device *dev,
- unsigned int chan,
- unsigned int range)
-{
- outb(chan, dev->iobase + PCL818_MUX_REG);
- outb(range, dev->iobase + PCL818_RANGE_REG);
-}
-
-static void pcl818_ai_set_chan_scan(struct comedi_device *dev,
- unsigned int first_chan,
- unsigned int last_chan)
-{
- outb(PCL818_MUX_SCAN(first_chan, last_chan),
- dev->iobase + PCL818_MUX_REG);
-}
-
-static void pcl818_ai_setup_chanlist(struct comedi_device *dev,
- unsigned int *chanlist,
- unsigned int seglen)
-{
- struct pcl818_private *devpriv = dev->private;
- unsigned int first_chan = CR_CHAN(chanlist[0]);
- unsigned int last_chan;
- unsigned int range;
- int i;
-
- devpriv->act_chanlist_len = seglen;
- devpriv->act_chanlist_pos = 0;
-
- /* store range list to card */
- for (i = 0; i < seglen; i++) {
- last_chan = CR_CHAN(chanlist[i]);
- range = CR_RANGE(chanlist[i]);
-
- devpriv->act_chanlist[i] = last_chan;
-
- pcl818_ai_set_chan_range(dev, last_chan, range);
- }
-
- udelay(1);
-
- pcl818_ai_set_chan_scan(dev, first_chan, last_chan);
-}
-
-static void pcl818_ai_clear_eoc(struct comedi_device *dev)
-{
- /* writing any value clears the interrupt request */
- outb(0, dev->iobase + PCL818_STATUS_REG);
-}
-
-static void pcl818_ai_soft_trig(struct comedi_device *dev)
-{
- /* writing any value triggers a software conversion */
- outb(0, dev->iobase + PCL818_AI_LSB_REG);
-}
-
-static unsigned int pcl818_ai_get_fifo_sample(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chan)
-{
- unsigned int val;
-
- val = inb(dev->iobase + PCL818_FI_DATALO);
- val |= (inb(dev->iobase + PCL818_FI_DATAHI) << 8);
-
- if (chan)
- *chan = val & 0xf;
-
- return (val >> 4) & s->maxdata;
-}
-
-static unsigned int pcl818_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chan)
-{
- unsigned int val;
-
- val = inb(dev->iobase + PCL818_AI_MSB_REG) << 8;
- val |= inb(dev->iobase + PCL818_AI_LSB_REG);
-
- if (chan)
- *chan = val & 0xf;
-
- return (val >> 4) & s->maxdata;
-}
-
-static int pcl818_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + PCL818_STATUS_REG);
- if (status & PCL818_STATUS_INT)
- return 0;
- return -EBUSY;
-}
-
-static bool pcl818_ai_write_sample(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chan, unsigned short val)
-{
- struct pcl818_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int expected_chan;
-
- expected_chan = devpriv->act_chanlist[devpriv->act_chanlist_pos];
- if (chan != expected_chan) {
- dev_dbg(dev->class_dev,
- "A/D mode1/3 %s - channel dropout %d!=%d !\n",
- (devpriv->dma) ? "DMA" :
- (devpriv->usefifo) ? "FIFO" : "IRQ",
- chan, expected_chan);
- s->async->events |= COMEDI_CB_ERROR;
- return false;
- }
-
- comedi_buf_write_samples(s, &val, 1);
-
- devpriv->act_chanlist_pos++;
- if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
- devpriv->act_chanlist_pos = 0;
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg) {
- s->async->events |= COMEDI_CB_EOA;
- return false;
- }
-
- return true;
-}
-
-static void pcl818_handle_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int chan;
- unsigned int val;
-
- if (pcl818_ai_eoc(dev, s, NULL, 0)) {
- dev_err(dev->class_dev, "A/D mode1/3 IRQ without DRDY!\n");
- s->async->events |= COMEDI_CB_ERROR;
- return;
- }
-
- val = pcl818_ai_get_sample(dev, s, &chan);
- pcl818_ai_write_sample(dev, s, chan, val);
-}
-
-static void pcl818_handle_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl818_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
- unsigned short *ptr = desc->virt_addr;
- unsigned int nsamples = comedi_bytes_to_samples(s, desc->size);
- unsigned int chan;
- unsigned int val;
- int i;
-
- /* restart dma with the next buffer */
- dma->cur_dma = 1 - dma->cur_dma;
- pcl818_ai_setup_dma(dev, s, nsamples);
-
- for (i = 0; i < nsamples; i++) {
- val = ptr[i];
- chan = val & 0xf;
- val = (val >> 4) & s->maxdata;
- if (!pcl818_ai_write_sample(dev, s, chan, val))
- break;
- }
-}
-
-static void pcl818_handle_fifo(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int status;
- unsigned int chan;
- unsigned int val;
- int i, len;
-
- status = inb(dev->iobase + PCL818_FI_STATUS);
-
- if (status & 4) {
- dev_err(dev->class_dev, "A/D mode1/3 FIFO overflow!\n");
- s->async->events |= COMEDI_CB_ERROR;
- return;
- }
-
- if (status & 1) {
- dev_err(dev->class_dev,
- "A/D mode1/3 FIFO interrupt without data!\n");
- s->async->events |= COMEDI_CB_ERROR;
- return;
- }
-
- if (status & 2)
- len = 512;
- else
- len = 0;
-
- for (i = 0; i < len; i++) {
- val = pcl818_ai_get_fifo_sample(dev, s, &chan);
- if (!pcl818_ai_write_sample(dev, s, chan, val))
- break;
- }
-}
-
-static irqreturn_t pcl818_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct pcl818_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (!dev->attached || !devpriv->ai_cmd_running) {
- pcl818_ai_clear_eoc(dev);
- return IRQ_HANDLED;
- }
-
- if (devpriv->ai_cmd_canceled) {
- /*
- * The cleanup from ai_cancel() has been delayed
- * until now because the card doesn't seem to like
- * being reprogrammed while a DMA transfer is in
- * progress.
- */
- s->async->scans_done = cmd->stop_arg;
- s->cancel(dev, s);
- return IRQ_HANDLED;
- }
-
- if (devpriv->dma)
- pcl818_handle_dma(dev, s);
- else if (devpriv->usefifo)
- pcl818_handle_fifo(dev, s);
- else
- pcl818_handle_eoc(dev, s);
-
- pcl818_ai_clear_eoc(dev);
-
- comedi_handle_events(dev, s);
- return IRQ_HANDLED;
-}
-
-static int check_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chanlist, unsigned int n_chan)
-{
- unsigned int chansegment[16];
- unsigned int i, nowmustbechan, seglen;
-
- /* correct channel and range number check itself comedi/range.c */
- if (n_chan < 1) {
- dev_err(dev->class_dev, "range/channel list is empty!\n");
- return 0;
- }
-
- if (n_chan > 1) {
- /* first channel is every time ok */
- chansegment[0] = chanlist[0];
- /* build part of chanlist */
- for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
- /* we detect loop, this must by finish */
-
- if (chanlist[0] == chanlist[i])
- break;
- nowmustbechan =
- (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
- if (nowmustbechan != CR_CHAN(chanlist[i])) {
- /* channel list isn't continuous :-( */
- dev_dbg(dev->class_dev,
- "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
- i, CR_CHAN(chanlist[i]), nowmustbechan,
- CR_CHAN(chanlist[0]));
- return 0;
- }
- /* well, this is next correct channel in list */
- chansegment[i] = chanlist[i];
- }
-
- /* check whole chanlist */
- for (i = 0; i < n_chan; i++) {
- if (chanlist[i] != chansegment[i % seglen]) {
- dev_dbg(dev->class_dev,
- "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
- i, CR_CHAN(chansegment[i]),
- CR_RANGE(chansegment[i]),
- CR_AREF(chansegment[i]),
- CR_CHAN(chanlist[i % seglen]),
- CR_RANGE(chanlist[i % seglen]),
- CR_AREF(chansegment[i % seglen]));
- return 0; /* chan/gain list is strange */
- }
- }
- } else {
- seglen = 1;
- }
- return seglen;
-}
-
-static int check_single_ended(unsigned int port)
-{
- if (inb(port + PCL818_STATUS_REG) & PCL818_STATUS_MUX)
- return 1;
- return 0;
-}
-
-static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- const struct pcl818_board *board = dev->board_ptr;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- board->ns_min);
- } else { /* TRIG_EXT */
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- unsigned int arg = cmd->convert_arg;
-
- comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (err)
- return 4;
-
- /* step 5: complain about special chanlist considerations */
-
- if (cmd->chanlist) {
- if (!check_channel_list(dev, s, cmd->chanlist,
- cmd->chanlist_len))
- return 5; /* incorrect channels list */
- }
-
- return 0;
-}
-
-static int pcl818_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl818_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int ctrl = 0;
- unsigned int seglen;
-
- if (devpriv->ai_cmd_running)
- return -EBUSY;
-
- seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
- if (seglen < 1)
- return -EINVAL;
- pcl818_ai_setup_chanlist(dev, cmd->chanlist, seglen);
-
- devpriv->ai_cmd_running = 1;
- devpriv->ai_cmd_canceled = 0;
- devpriv->act_chanlist_pos = 0;
-
- if (cmd->convert_src == TRIG_TIMER)
- ctrl |= PCL818_CTRL_PACER_TRIG;
- else
- ctrl |= PCL818_CTRL_EXT_TRIG;
-
- outb(0, dev->iobase + PCL818_CNTENABLE_REG);
-
- if (dma) {
- /* setup and enable dma for the first buffer */
- dma->cur_dma = 0;
- pcl818_ai_setup_dma(dev, s, 0);
-
- ctrl |= PCL818_CTRL_INTE | PCL818_CTRL_IRQ(dev->irq) |
- PCL818_CTRL_DMAE;
- } else if (devpriv->usefifo) {
- /* enable FIFO */
- outb(1, dev->iobase + PCL818_FI_ENABLE);
- } else {
- ctrl |= PCL818_CTRL_INTE | PCL818_CTRL_IRQ(dev->irq);
- }
- outb(ctrl, dev->iobase + PCL818_CTRL_REG);
-
- if (cmd->convert_src == TRIG_TIMER) {
- comedi_8254_update_divisors(dev->pacer);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
- }
-
- return 0;
-}
-
-static int pcl818_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl818_private *devpriv = dev->private;
- struct comedi_isadma *dma = devpriv->dma;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (!devpriv->ai_cmd_running)
- return 0;
-
- if (dma) {
- if (cmd->stop_src == TRIG_NONE ||
- (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done < cmd->stop_arg)) {
- if (!devpriv->ai_cmd_canceled) {
- /*
- * Wait for running dma transfer to end,
- * do cleanup in interrupt.
- */
- devpriv->ai_cmd_canceled = 1;
- return 0;
- }
- }
- comedi_isadma_disable(dma->chan);
- }
-
- outb(PCL818_CTRL_DISABLE_TRIG, dev->iobase + PCL818_CTRL_REG);
- comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
- pcl818_ai_clear_eoc(dev);
-
- if (devpriv->usefifo) { /* FIFO shutdown */
- outb(0, dev->iobase + PCL818_FI_INTCLR);
- outb(0, dev->iobase + PCL818_FI_FLUSH);
- outb(0, dev->iobase + PCL818_FI_ENABLE);
- }
- devpriv->ai_cmd_running = 0;
- devpriv->ai_cmd_canceled = 0;
-
- return 0;
-}
-
-static int pcl818_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int ret = 0;
- int i;
-
- outb(PCL818_CTRL_SOFT_TRIG, dev->iobase + PCL818_CTRL_REG);
-
- pcl818_ai_set_chan_range(dev, chan, range);
- pcl818_ai_set_chan_scan(dev, chan, chan);
-
- for (i = 0; i < insn->n; i++) {
- pcl818_ai_clear_eoc(dev);
- pcl818_ai_soft_trig(dev);
-
- ret = comedi_timeout(dev, s, insn, pcl818_ai_eoc, 0);
- if (ret)
- break;
-
- data[i] = pcl818_ai_get_sample(dev, s, NULL);
- }
- pcl818_ai_clear_eoc(dev);
-
- return ret ? ret : insn->n;
-}
-
-static int pcl818_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- int i;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outb((val & 0x000f) << 4,
- dev->iobase + PCL818_AO_LSB_REG(chan));
- outb((val & 0x0ff0) >> 4,
- dev->iobase + PCL818_AO_MSB_REG(chan));
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pcl818_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + PCL818_DO_DI_LSB_REG) |
- (inb(dev->iobase + PCL818_DO_DI_MSB_REG) << 8);
-
- return insn->n;
-}
-
-static int pcl818_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- outb(s->state & 0xff, dev->iobase + PCL818_DO_DI_LSB_REG);
- outb((s->state >> 8), dev->iobase + PCL818_DO_DI_MSB_REG);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static void pcl818_reset(struct comedi_device *dev)
-{
- const struct pcl818_board *board = dev->board_ptr;
- unsigned int chan;
-
- /* flush and disable the FIFO */
- if (board->has_fifo) {
- outb(0, dev->iobase + PCL818_FI_INTCLR);
- outb(0, dev->iobase + PCL818_FI_FLUSH);
- outb(0, dev->iobase + PCL818_FI_ENABLE);
- }
-
- /* disable analog input trigger */
- outb(PCL818_CTRL_DISABLE_TRIG, dev->iobase + PCL818_CTRL_REG);
- pcl818_ai_clear_eoc(dev);
-
- pcl818_ai_set_chan_range(dev, 0, 0);
-
- /* stop pacer */
- outb(0, dev->iobase + PCL818_CNTENABLE_REG);
-
- /* set analog output channels to 0V */
- for (chan = 0; chan < board->n_aochan; chan++) {
- outb(0, dev->iobase + PCL818_AO_LSB_REG(chan));
- outb(0, dev->iobase + PCL818_AO_MSB_REG(chan));
- }
-
- /* set all digital outputs low */
- outb(0, dev->iobase + PCL818_DO_DI_MSB_REG);
- outb(0, dev->iobase + PCL818_DO_DI_LSB_REG);
-}
-
-static void pcl818_set_ai_range_table(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_devconfig *it)
-{
- const struct pcl818_board *board = dev->board_ptr;
-
- /* default to the range table from the boardinfo */
- s->range_table = board->ai_range_type;
-
- /* now check the user config option based on the boardtype */
- if (board->is_818) {
- if (it->options[4] == 1 || it->options[4] == 10) {
- /* secondary range list jumper selectable */
- s->range_table = &range_pcl818l_h_ai;
- }
- } else {
- switch (it->options[4]) {
- case 0:
- s->range_table = &range_bipolar10;
- break;
- case 1:
- s->range_table = &range_bipolar5;
- break;
- case 2:
- s->range_table = &range_bipolar2_5;
- break;
- case 3:
- s->range_table = &range718_bipolar1;
- break;
- case 4:
- s->range_table = &range718_bipolar0_5;
- break;
- case 6:
- s->range_table = &range_unipolar10;
- break;
- case 7:
- s->range_table = &range_unipolar5;
- break;
- case 8:
- s->range_table = &range718_unipolar2;
- break;
- case 9:
- s->range_table = &range718_unipolar1;
- break;
- default:
- s->range_table = &range_unknown;
- break;
- }
- }
-}
-
-static void pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
-{
- struct pcl818_private *devpriv = dev->private;
-
- /* only DMA channels 3 and 1 are valid */
- if (!(dma_chan == 3 || dma_chan == 1))
- return;
-
- /* DMA uses two 16K buffers */
- devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
- PAGE_SIZE * 4, COMEDI_ISADMA_READ);
-}
-
-static void pcl818_free_dma(struct comedi_device *dev)
-{
- struct pcl818_private *devpriv = dev->private;
-
- if (devpriv)
- comedi_isadma_free(devpriv->dma);
-}
-
-static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct pcl818_board *board = dev->board_ptr;
- struct pcl818_private *devpriv;
- struct comedi_subdevice *s;
- unsigned int osc_base;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0],
- board->has_fifo ? 0x20 : 0x10);
- if (ret)
- return ret;
-
- /* we can use IRQ 2-7 for async command support */
- if (it->options[1] >= 2 && it->options[1] <= 7) {
- ret = request_irq(it->options[1], pcl818_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- /* should we use the FIFO? */
- if (dev->irq && board->has_fifo && it->options[2] == -1)
- devpriv->usefifo = 1;
-
- /* we need an IRQ to do DMA on channel 3 or 1 */
- if (dev->irq && board->has_dma)
- pcl818_alloc_dma(dev, it->options[2]);
-
- /* use 1MHz or 10MHz oscilator */
- if ((it->options[3] == 0) || (it->options[3] == 10))
- osc_base = I8254_OSC_BASE_10MHZ;
- else
- osc_base = I8254_OSC_BASE_1MHZ;
-
- dev->pacer = comedi_8254_init(dev->iobase + PCL818_TIMER_BASE,
- osc_base, I8254_IO8, 0);
- if (!dev->pacer)
- return -ENOMEM;
-
- /* max sampling speed */
- devpriv->ns_min = board->ns_min;
- if (!board->is_818) {
- /* extended PCL718 to 100kHz DAC */
- if ((it->options[6] == 1) || (it->options[6] == 100))
- devpriv->ns_min = 10000;
- }
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE;
- if (check_single_ended(dev->iobase)) {
- s->n_chan = 16;
- s->subdev_flags |= SDF_COMMON | SDF_GROUND;
- } else {
- s->n_chan = 8;
- s->subdev_flags |= SDF_DIFF;
- }
- s->maxdata = 0x0fff;
-
- pcl818_set_ai_range_table(dev, s, it);
-
- s->insn_read = pcl818_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = ai_cmdtest;
- s->do_cmd = pcl818_ai_cmd;
- s->cancel = pcl818_ai_cancel;
- }
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- if (board->n_aochan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = board->n_aochan;
- s->maxdata = 0x0fff;
- s->range_table = &range_unipolar5;
- if (board->is_818) {
- if ((it->options[4] == 1) || (it->options[4] == 10))
- s->range_table = &range_unipolar10;
- if (it->options[4] == 2)
- s->range_table = &range_unknown;
- } else {
- if ((it->options[5] == 1) || (it->options[5] == 10))
- s->range_table = &range_unipolar10;
- if (it->options[5] == 2)
- s->range_table = &range_unknown;
- }
- s->insn_write = pcl818_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Digital Input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl818_di_insn_bits;
-
- /* Digital Output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcl818_do_insn_bits;
-
- pcl818_reset(dev);
-
- return 0;
-}
-
-static void pcl818_detach(struct comedi_device *dev)
-{
- struct pcl818_private *devpriv = dev->private;
-
- if (devpriv) {
- pcl818_ai_cancel(dev, dev->read_subdev);
- pcl818_reset(dev);
- }
- pcl818_free_dma(dev);
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver pcl818_driver = {
- .driver_name = "pcl818",
- .module = THIS_MODULE,
- .attach = pcl818_attach,
- .detach = pcl818_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct pcl818_board),
-};
-module_comedi_driver(pcl818_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
deleted file mode 100644
index 0cb1ad060402..000000000000
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ /dev/null
@@ -1,227 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * pcm3724.c
- * Comedi driver for Advantech PCM-3724 Digital I/O board
- *
- * Drew Csillag <drew_csillag@yahoo.com>
- */
-
-/*
- * Driver: pcm3724
- * Description: Advantech PCM-3724
- * Devices: [Advantech] PCM-3724 (pcm3724)
- * Author: Drew Csillag <drew_csillag@yahoo.com>
- * Status: tested
- *
- * This is driver for digital I/O boards PCM-3724 with 48 DIO.
- * It needs 8255.o for operations and only immediate mode is supported.
- * See the source for configuration details.
- *
- * Copy/pasted/hacked from pcm724.c
- *
- * Configuration Options:
- * [0] - I/O port base address
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#include "8255.h"
-
-/*
- * Register I/O Map
- *
- * This board has two standard 8255 devices that provide six 8-bit DIO ports
- * (48 channels total). Six 74HCT245 chips (one for each port) buffer the
- * I/O lines to increase driving capability. Because the 74HCT245 is a
- * bidirectional, tri-state line buffer, two additional I/O ports are used
- * to control the direction of data and the enable of each port.
- */
-#define PCM3724_8255_0_BASE 0x00
-#define PCM3724_8255_1_BASE 0x04
-#define PCM3724_DIO_DIR_REG 0x08
-#define PCM3724_DIO_DIR_C0_OUT BIT(0)
-#define PCM3724_DIO_DIR_B0_OUT BIT(1)
-#define PCM3724_DIO_DIR_A0_OUT BIT(2)
-#define PCM3724_DIO_DIR_C1_OUT BIT(3)
-#define PCM3724_DIO_DIR_B1_OUT BIT(4)
-#define PCM3724_DIO_DIR_A1_OUT BIT(5)
-#define PCM3724_GATE_CTRL_REG 0x09
-#define PCM3724_GATE_CTRL_C0_ENA BIT(0)
-#define PCM3724_GATE_CTRL_B0_ENA BIT(1)
-#define PCM3724_GATE_CTRL_A0_ENA BIT(2)
-#define PCM3724_GATE_CTRL_C1_ENA BIT(3)
-#define PCM3724_GATE_CTRL_B1_ENA BIT(4)
-#define PCM3724_GATE_CTRL_A1_ENA BIT(5)
-
-/* used to track configured dios */
-struct priv_pcm3724 {
- int dio_1;
- int dio_2;
-};
-
-static int compute_buffer(int config, int devno, struct comedi_subdevice *s)
-{
- /* 1 in io_bits indicates output */
- if (s->io_bits & 0x0000ff) {
- if (devno == 0)
- config |= PCM3724_DIO_DIR_A0_OUT;
- else
- config |= PCM3724_DIO_DIR_A1_OUT;
- }
- if (s->io_bits & 0x00ff00) {
- if (devno == 0)
- config |= PCM3724_DIO_DIR_B0_OUT;
- else
- config |= PCM3724_DIO_DIR_B1_OUT;
- }
- if (s->io_bits & 0xff0000) {
- if (devno == 0)
- config |= PCM3724_DIO_DIR_C0_OUT;
- else
- config |= PCM3724_DIO_DIR_C1_OUT;
- }
- return config;
-}
-
-static void do_3724_config(struct comedi_device *dev,
- struct comedi_subdevice *s, int chanspec)
-{
- struct comedi_subdevice *s_dio1 = &dev->subdevices[0];
- struct comedi_subdevice *s_dio2 = &dev->subdevices[1];
- int config;
- int buffer_config;
- unsigned long port_8255_cfg;
-
- config = I8255_CTRL_CW;
- buffer_config = 0;
-
- /* 1 in io_bits indicates output, 1 in config indicates input */
- if (!(s->io_bits & 0x0000ff))
- config |= I8255_CTRL_A_IO;
-
- if (!(s->io_bits & 0x00ff00))
- config |= I8255_CTRL_B_IO;
-
- if (!(s->io_bits & 0xff0000))
- config |= I8255_CTRL_C_HI_IO | I8255_CTRL_C_LO_IO;
-
- buffer_config = compute_buffer(0, 0, s_dio1);
- buffer_config = compute_buffer(buffer_config, 1, s_dio2);
-
- if (s == s_dio1)
- port_8255_cfg = dev->iobase + I8255_CTRL_REG;
- else
- port_8255_cfg = dev->iobase + I8255_SIZE + I8255_CTRL_REG;
-
- outb(buffer_config, dev->iobase + PCM3724_DIO_DIR_REG);
-
- outb(config, port_8255_cfg);
-}
-
-static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s,
- int chanspec)
-{
- struct priv_pcm3724 *priv = dev->private;
- struct comedi_subdevice *s_dio1 = &dev->subdevices[0];
- unsigned int mask;
- int gatecfg;
-
- gatecfg = 0;
-
- mask = 1 << CR_CHAN(chanspec);
- if (s == s_dio1)
- priv->dio_1 |= mask;
- else
- priv->dio_2 |= mask;
-
- if (priv->dio_1 & 0xff0000)
- gatecfg |= PCM3724_GATE_CTRL_C0_ENA;
-
- if (priv->dio_1 & 0xff00)
- gatecfg |= PCM3724_GATE_CTRL_B0_ENA;
-
- if (priv->dio_1 & 0xff)
- gatecfg |= PCM3724_GATE_CTRL_A0_ENA;
-
- if (priv->dio_2 & 0xff0000)
- gatecfg |= PCM3724_GATE_CTRL_C1_ENA;
-
- if (priv->dio_2 & 0xff00)
- gatecfg |= PCM3724_GATE_CTRL_B1_ENA;
-
- if (priv->dio_2 & 0xff)
- gatecfg |= PCM3724_GATE_CTRL_A1_ENA;
-
- outb(gatecfg, dev->iobase + PCM3724_GATE_CTRL_REG);
-}
-
-/* overriding the 8255 insn config */
-static int subdev_3724_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- if (chan < 8)
- mask = 0x0000ff;
- else if (chan < 16)
- mask = 0x00ff00;
- else if (chan < 20)
- mask = 0x0f0000;
- else
- mask = 0xf00000;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- do_3724_config(dev, s, insn->chanspec);
- enable_chan(dev, s, insn->chanspec);
-
- return insn->n;
-}
-
-static int pcm3724_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct priv_pcm3724 *priv;
- struct comedi_subdevice *s;
- int ret, i;
-
- priv = comedi_alloc_devpriv(dev, sizeof(*priv));
- if (!priv)
- return -ENOMEM;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
- if (ret)
- return ret;
- s->insn_config = subdev_3724_insn_config;
- }
- return 0;
-}
-
-static struct comedi_driver pcm3724_driver = {
- .driver_name = "pcm3724",
- .module = THIS_MODULE,
- .attach = pcm3724_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(pcm3724_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Advantech PCM-3724 Digital I/O board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
deleted file mode 100644
index eec89a0afb2f..000000000000
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ /dev/null
@@ -1,149 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * pcmad.c
- * Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: pcmad
- * Description: Winsystems PCM-A/D12, PCM-A/D16
- * Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
- * Author: ds
- * Status: untested
- *
- * This driver was written on a bet that I couldn't write a driver
- * in less than 2 hours. I won the bet, but never got paid. =(
- *
- * Configuration options:
- * [0] - I/O port base
- * [1] - IRQ (unused)
- * [2] - Analog input reference (must match jumpers)
- * 0 = single-ended (16 channels)
- * 1 = differential (8 channels)
- * [3] - Analog input encoding (must match jumpers)
- * 0 = straight binary (0-5V input range)
- * 1 = two's complement (+-10V input range)
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-#define PCMAD_STATUS 0
-#define PCMAD_LSB 1
-#define PCMAD_MSB 2
-#define PCMAD_CONVERT 1
-
-struct pcmad_board_struct {
- const char *name;
- unsigned int ai_maxdata;
-};
-
-static const struct pcmad_board_struct pcmad_boards[] = {
- {
- .name = "pcmad12",
- .ai_maxdata = 0x0fff,
- }, {
- .name = "pcmad16",
- .ai_maxdata = 0xffff,
- },
-};
-
-static int pcmad_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + PCMAD_STATUS);
- if ((status & 0x3) == 0x3)
- return 0;
- return -EBUSY;
-}
-
-static int pcmad_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- int ret;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- outb(chan, dev->iobase + PCMAD_CONVERT);
-
- ret = comedi_timeout(dev, s, insn, pcmad_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inb(dev->iobase + PCMAD_LSB) |
- (inb(dev->iobase + PCMAD_MSB) << 8);
-
- /* data is shifted on the pcmad12, fix it */
- if (s->maxdata == 0x0fff)
- val >>= 4;
-
- if (comedi_range_is_bipolar(s, range)) {
- /* munge the two's complement value */
- val ^= ((s->maxdata + 1) >> 1);
- }
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct pcmad_board_struct *board = dev->board_ptr;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x04);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- if (it->options[1]) {
- /* 8 differential channels */
- s->subdev_flags = SDF_READABLE | AREF_DIFF;
- s->n_chan = 8;
- } else {
- /* 16 single-ended channels */
- s->subdev_flags = SDF_READABLE | AREF_GROUND;
- s->n_chan = 16;
- }
- s->len_chanlist = 1;
- s->maxdata = board->ai_maxdata;
- s->range_table = it->options[2] ? &range_bipolar10 : &range_unipolar5;
- s->insn_read = pcmad_ai_insn_read;
-
- return 0;
-}
-
-static struct comedi_driver pcmad_driver = {
- .driver_name = "pcmad",
- .module = THIS_MODULE,
- .attach = pcmad_attach,
- .detach = comedi_legacy_detach,
- .board_name = &pcmad_boards[0].name,
- .num_names = ARRAY_SIZE(pcmad_boards),
- .offset = sizeof(pcmad_boards[0]),
-};
-module_comedi_driver(pcmad_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
deleted file mode 100644
index 14ab1f0d1e9f..000000000000
--- a/drivers/staging/comedi/drivers/pcmda12.c
+++ /dev/null
@@ -1,165 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * pcmda12.c
- * Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
- */
-
-/*
- * Driver: pcmda12
- * Description: A driver for the Winsystems PCM-D/A-12
- * Devices: [Winsystems] PCM-D/A-12 (pcmda12)
- * Author: Calin Culianu <calin@ajvar.org>
- * Updated: Fri, 13 Jan 2006 12:01:01 -0500
- * Status: works
- *
- * A driver for the relatively straightforward-to-program PCM-D/A-12.
- * This board doesn't support commands, and the only way to set its
- * analog output range is to jumper the board. As such,
- * comedi_data_write() ignores the range value specified.
- *
- * The board uses 16 consecutive I/O addresses starting at the I/O port
- * base address. Each address corresponds to the LSB then MSB of a
- * particular channel from 0-7.
- *
- * Note that the board is not ISA-PNP capable and thus needs the I/O
- * port comedi_config parameter.
- *
- * Note that passing a nonzero value as the second config option will
- * enable "simultaneous xfer" mode for this board, in which AO writes
- * will not take effect until a subsequent read of any AO channel. This
- * is so that one can speed up programming by preloading all AO registers
- * with values before simultaneously setting them to take effect with one
- * read command.
- *
- * Configuration Options:
- * [0] - I/O port base address
- * [1] - Do Simultaneous Xfer (see description)
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-/* AI range is not configurable, it's set by jumpers on the board */
-static const struct comedi_lrange pcmda12_ranges = {
- 3, {
- UNI_RANGE(5),
- UNI_RANGE(10),
- BIP_RANGE(5)
- }
-};
-
-struct pcmda12_private {
- int simultaneous_xfer_mode;
-};
-
-static int pcmda12_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pcmda12_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val = s->readback[chan];
- unsigned long ioreg = dev->iobase + (chan * 2);
- int i;
-
- for (i = 0; i < insn->n; ++i) {
- val = data[i];
- outb(val & 0xff, ioreg);
- outb((val >> 8) & 0xff, ioreg + 1);
-
- /*
- * Initiate transfer if not in simultaneaous xfer
- * mode by reading one of the AO registers.
- */
- if (!devpriv->simultaneous_xfer_mode)
- inb(ioreg);
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int pcmda12_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct pcmda12_private *devpriv = dev->private;
-
- /*
- * Initiate simultaneaous xfer mode by reading one of the
- * AO registers. All analog outputs will then be updated.
- */
- if (devpriv->simultaneous_xfer_mode)
- inb(dev->iobase);
-
- return comedi_readback_insn_read(dev, s, insn, data);
-}
-
-static void pcmda12_ao_reset(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- int i;
-
- for (i = 0; i < s->n_chan; ++i) {
- outb(0, dev->iobase + (i * 2));
- outb(0, dev->iobase + (i * 2) + 1);
- }
- /* Initiate transfer by reading one of the AO registers. */
- inb(dev->iobase);
-}
-
-static int pcmda12_attach(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- struct pcmda12_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- devpriv->simultaneous_xfer_mode = it->options[1];
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 0x0fff;
- s->range_table = &pcmda12_ranges;
- s->insn_write = pcmda12_ao_insn_write;
- s->insn_read = pcmda12_ao_insn_read;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- pcmda12_ao_reset(dev, s);
-
- return 0;
-}
-
-static struct comedi_driver pcmda12_driver = {
- .driver_name = "pcmda12",
- .module = THIS_MODULE,
- .attach = pcmda12_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(pcmda12_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
deleted file mode 100644
index 24a9568d3378..000000000000
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ /dev/null
@@ -1,777 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * pcmmio.c
- * Driver for Winsystems PC-104 based multifunction IO board.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2007 Calin A. Culianu <calin@ajvar.org>
- */
-
-/*
- * Driver: pcmmio
- * Description: A driver for the PCM-MIO multifunction board
- * Devices: [Winsystems] PCM-MIO (pcmmio)
- * Author: Calin Culianu <calin@ajvar.org>
- * Updated: Wed, May 16 2007 16:21:10 -0500
- * Status: works
- *
- * A driver for the PCM-MIO multifunction board from Winsystems. This
- * is a PC-104 based I/O board. It contains four subdevices:
- *
- * subdevice 0 - 16 channels of 16-bit AI
- * subdevice 1 - 8 channels of 16-bit AO
- * subdevice 2 - first 24 channels of the 48 channel of DIO
- * (with edge-triggered interrupt support)
- * subdevice 3 - last 24 channels of the 48 channel DIO
- * (no interrupt support for this bank of channels)
- *
- * Some notes:
- *
- * Synchronous reads and writes are the only things implemented for analog
- * input and output. The hardware itself can do streaming acquisition, etc.
- *
- * Asynchronous I/O for the DIO subdevices *is* implemented, however! They
- * are basically edge-triggered interrupts for any configuration of the
- * channels in subdevice 2.
- *
- * Also note that this interrupt support is untested.
- *
- * A few words about edge-detection IRQ support (commands on DIO):
- *
- * To use edge-detection IRQ support for the DIO subdevice, pass the IRQ
- * of the board to the comedi_config command. The board IRQ is not jumpered
- * but rather configured through software, so any IRQ from 1-15 is OK.
- *
- * Due to the genericity of the comedi API, you need to create a special
- * comedi_command in order to use edge-triggered interrupts for DIO.
- *
- * Use comedi_commands with TRIG_NOW. Your callback will be called each
- * time an edge is detected on the specified DIO line(s), and the data
- * values will be two sample_t's, which should be concatenated to form
- * one 32-bit unsigned int. This value is the mask of channels that had
- * edges detected from your channel list. Note that the bits positions
- * in the mask correspond to positions in your chanlist when you
- * specified the command and *not* channel id's!
- *
- * To set the polarity of the edge-detection interrupts pass a nonzero value
- * for either CR_RANGE or CR_AREF for edge-up polarity, or a zero
- * value for both CR_RANGE and CR_AREF if you want edge-down polarity.
- *
- * Configuration Options:
- * [0] - I/O port base address
- * [1] - IRQ (optional -- for edge-detect interrupt support only,
- * leave out if you don't need this feature)
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include "../comedidev.h"
-
-/*
- * Register I/O map
- */
-#define PCMMIO_AI_LSB_REG 0x00
-#define PCMMIO_AI_MSB_REG 0x01
-#define PCMMIO_AI_CMD_REG 0x02
-#define PCMMIO_AI_CMD_SE BIT(7)
-#define PCMMIO_AI_CMD_ODD_CHAN BIT(6)
-#define PCMMIO_AI_CMD_CHAN_SEL(x) (((x) & 0x3) << 4)
-#define PCMMIO_AI_CMD_RANGE(x) (((x) & 0x3) << 2)
-#define PCMMIO_RESOURCE_REG 0x02
-#define PCMMIO_RESOURCE_IRQ(x) (((x) & 0xf) << 0)
-#define PCMMIO_AI_STATUS_REG 0x03
-#define PCMMIO_AI_STATUS_DATA_READY BIT(7)
-#define PCMMIO_AI_STATUS_DATA_DMA_PEND BIT(6)
-#define PCMMIO_AI_STATUS_CMD_DMA_PEND BIT(5)
-#define PCMMIO_AI_STATUS_IRQ_PEND BIT(4)
-#define PCMMIO_AI_STATUS_DATA_DRQ_ENA BIT(2)
-#define PCMMIO_AI_STATUS_REG_SEL BIT(3)
-#define PCMMIO_AI_STATUS_CMD_DRQ_ENA BIT(1)
-#define PCMMIO_AI_STATUS_IRQ_ENA BIT(0)
-#define PCMMIO_AI_RES_ENA_REG 0x03
-#define PCMMIO_AI_RES_ENA_CMD_REG_ACCESS (0 << 3)
-#define PCMMIO_AI_RES_ENA_AI_RES_ACCESS BIT(3)
-#define PCMMIO_AI_RES_ENA_DIO_RES_ACCESS BIT(4)
-#define PCMMIO_AI_2ND_ADC_OFFSET 0x04
-
-#define PCMMIO_AO_LSB_REG 0x08
-#define PCMMIO_AO_LSB_SPAN(x) (((x) & 0xf) << 0)
-#define PCMMIO_AO_MSB_REG 0x09
-#define PCMMIO_AO_CMD_REG 0x0a
-#define PCMMIO_AO_CMD_WR_SPAN (0x2 << 4)
-#define PCMMIO_AO_CMD_WR_CODE (0x3 << 4)
-#define PCMMIO_AO_CMD_UPDATE (0x4 << 4)
-#define PCMMIO_AO_CMD_UPDATE_ALL (0x5 << 4)
-#define PCMMIO_AO_CMD_WR_SPAN_UPDATE (0x6 << 4)
-#define PCMMIO_AO_CMD_WR_CODE_UPDATE (0x7 << 4)
-#define PCMMIO_AO_CMD_WR_SPAN_UPDATE_ALL (0x8 << 4)
-#define PCMMIO_AO_CMD_WR_CODE_UPDATE_ALL (0x9 << 4)
-#define PCMMIO_AO_CMD_RD_B1_SPAN (0xa << 4)
-#define PCMMIO_AO_CMD_RD_B1_CODE (0xb << 4)
-#define PCMMIO_AO_CMD_RD_B2_SPAN (0xc << 4)
-#define PCMMIO_AO_CMD_RD_B2_CODE (0xd << 4)
-#define PCMMIO_AO_CMD_NOP (0xf << 4)
-#define PCMMIO_AO_CMD_CHAN_SEL(x) (((x) & 0x03) << 1)
-#define PCMMIO_AO_CMD_CHAN_SEL_ALL (0x0f << 0)
-#define PCMMIO_AO_STATUS_REG 0x0b
-#define PCMMIO_AO_STATUS_DATA_READY BIT(7)
-#define PCMMIO_AO_STATUS_DATA_DMA_PEND BIT(6)
-#define PCMMIO_AO_STATUS_CMD_DMA_PEND BIT(5)
-#define PCMMIO_AO_STATUS_IRQ_PEND BIT(4)
-#define PCMMIO_AO_STATUS_DATA_DRQ_ENA BIT(2)
-#define PCMMIO_AO_STATUS_REG_SEL BIT(3)
-#define PCMMIO_AO_STATUS_CMD_DRQ_ENA BIT(1)
-#define PCMMIO_AO_STATUS_IRQ_ENA BIT(0)
-#define PCMMIO_AO_RESOURCE_ENA_REG 0x0b
-#define PCMMIO_AO_2ND_DAC_OFFSET 0x04
-
-/*
- * WinSystems WS16C48
- *
- * Offset Page 0 Page 1 Page 2 Page 3
- * ------ ----------- ----------- ----------- -----------
- * 0x10 Port 0 I/O Port 0 I/O Port 0 I/O Port 0 I/O
- * 0x11 Port 1 I/O Port 1 I/O Port 1 I/O Port 1 I/O
- * 0x12 Port 2 I/O Port 2 I/O Port 2 I/O Port 2 I/O
- * 0x13 Port 3 I/O Port 3 I/O Port 3 I/O Port 3 I/O
- * 0x14 Port 4 I/O Port 4 I/O Port 4 I/O Port 4 I/O
- * 0x15 Port 5 I/O Port 5 I/O Port 5 I/O Port 5 I/O
- * 0x16 INT_PENDING INT_PENDING INT_PENDING INT_PENDING
- * 0x17 Page/Lock Page/Lock Page/Lock Page/Lock
- * 0x18 N/A POL_0 ENAB_0 INT_ID0
- * 0x19 N/A POL_1 ENAB_1 INT_ID1
- * 0x1a N/A POL_2 ENAB_2 INT_ID2
- */
-#define PCMMIO_PORT_REG(x) (0x10 + (x))
-#define PCMMIO_INT_PENDING_REG 0x16
-#define PCMMIO_PAGE_LOCK_REG 0x17
-#define PCMMIO_LOCK_PORT(x) ((1 << (x)) & 0x3f)
-#define PCMMIO_PAGE(x) (((x) & 0x3) << 6)
-#define PCMMIO_PAGE_MASK PCMUIO_PAGE(3)
-#define PCMMIO_PAGE_POL 1
-#define PCMMIO_PAGE_ENAB 2
-#define PCMMIO_PAGE_INT_ID 3
-#define PCMMIO_PAGE_REG(x) (0x18 + (x))
-
-static const struct comedi_lrange pcmmio_ai_ranges = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(10),
- UNI_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-static const struct comedi_lrange pcmmio_ao_ranges = {
- 6, {
- UNI_RANGE(5),
- UNI_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(10),
- BIP_RANGE(2.5),
- RANGE(-2.5, 7.5)
- }
-};
-
-struct pcmmio_private {
- spinlock_t pagelock; /* protects the page registers */
- spinlock_t spinlock; /* protects the member variables */
- unsigned int enabled_mask;
- unsigned int active:1;
-};
-
-static void pcmmio_dio_write(struct comedi_device *dev, unsigned int val,
- int page, int port)
-{
- struct pcmmio_private *devpriv = dev->private;
- unsigned long iobase = dev->iobase;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->pagelock, flags);
- if (page == 0) {
- /* Port registers are valid for any page */
- outb(val & 0xff, iobase + PCMMIO_PORT_REG(port + 0));
- outb((val >> 8) & 0xff, iobase + PCMMIO_PORT_REG(port + 1));
- outb((val >> 16) & 0xff, iobase + PCMMIO_PORT_REG(port + 2));
- } else {
- outb(PCMMIO_PAGE(page), iobase + PCMMIO_PAGE_LOCK_REG);
- outb(val & 0xff, iobase + PCMMIO_PAGE_REG(0));
- outb((val >> 8) & 0xff, iobase + PCMMIO_PAGE_REG(1));
- outb((val >> 16) & 0xff, iobase + PCMMIO_PAGE_REG(2));
- }
- spin_unlock_irqrestore(&devpriv->pagelock, flags);
-}
-
-static unsigned int pcmmio_dio_read(struct comedi_device *dev,
- int page, int port)
-{
- struct pcmmio_private *devpriv = dev->private;
- unsigned long iobase = dev->iobase;
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&devpriv->pagelock, flags);
- if (page == 0) {
- /* Port registers are valid for any page */
- val = inb(iobase + PCMMIO_PORT_REG(port + 0));
- val |= (inb(iobase + PCMMIO_PORT_REG(port + 1)) << 8);
- val |= (inb(iobase + PCMMIO_PORT_REG(port + 2)) << 16);
- } else {
- outb(PCMMIO_PAGE(page), iobase + PCMMIO_PAGE_LOCK_REG);
- val = inb(iobase + PCMMIO_PAGE_REG(0));
- val |= (inb(iobase + PCMMIO_PAGE_REG(1)) << 8);
- val |= (inb(iobase + PCMMIO_PAGE_REG(2)) << 16);
- }
- spin_unlock_irqrestore(&devpriv->pagelock, flags);
-
- return val;
-}
-
-/*
- * Each channel can be individually programmed for input or output.
- * Writing a '0' to a channel causes the corresponding output pin
- * to go to a high-z state (pulled high by an external 10K resistor).
- * This allows it to be used as an input. When used in the input mode,
- * a read reflects the inverted state of the I/O pin, such that a
- * high on the pin will read as a '0' in the register. Writing a '1'
- * to a bit position causes the pin to sink current (up to 12mA),
- * effectively pulling it low.
- */
-static int pcmmio_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- /* subdevice 2 uses ports 0-2, subdevice 3 uses ports 3-5 */
- int port = s->index == 2 ? 0 : 3;
- unsigned int chanmask = (1 << s->n_chan) - 1;
- unsigned int mask;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- /*
- * Outputs are inverted, invert the state and
- * update the channels.
- *
- * The s->io_bits mask makes sure the input channels
- * are '0' so that the outputs pins stay in a high
- * z-state.
- */
- val = ~s->state & chanmask;
- val &= s->io_bits;
- pcmmio_dio_write(dev, val, 0, port);
- }
-
- /* get inverted state of the channels from the port */
- val = pcmmio_dio_read(dev, 0, port);
-
- /* return the true state of the channels */
- data[1] = ~val & chanmask;
-
- return insn->n;
-}
-
-static int pcmmio_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- /* subdevice 2 uses ports 0-2, subdevice 3 uses ports 3-5 */
- int port = s->index == 2 ? 0 : 3;
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- if (data[0] == INSN_CONFIG_DIO_INPUT)
- pcmmio_dio_write(dev, s->io_bits, 0, port);
-
- return insn->n;
-}
-
-static void pcmmio_reset(struct comedi_device *dev)
-{
- /* Clear all the DIO port bits */
- pcmmio_dio_write(dev, 0, 0, 0);
- pcmmio_dio_write(dev, 0, 0, 3);
-
- /* Clear all the paged registers */
- pcmmio_dio_write(dev, 0, PCMMIO_PAGE_POL, 0);
- pcmmio_dio_write(dev, 0, PCMMIO_PAGE_ENAB, 0);
- pcmmio_dio_write(dev, 0, PCMMIO_PAGE_INT_ID, 0);
-}
-
-/* devpriv->spinlock is already locked */
-static void pcmmio_stop_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcmmio_private *devpriv = dev->private;
-
- devpriv->enabled_mask = 0;
- devpriv->active = 0;
- s->async->inttrig = NULL;
-
- /* disable all dio interrupts */
- pcmmio_dio_write(dev, 0, PCMMIO_PAGE_ENAB, 0);
-}
-
-static void pcmmio_handle_dio_intr(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int triggered)
-{
- struct pcmmio_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int val = 0;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&devpriv->spinlock, flags);
-
- if (!devpriv->active)
- goto done;
-
- if (!(triggered & devpriv->enabled_mask))
- goto done;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (triggered & (1 << chan))
- val |= (1 << i);
- }
-
- comedi_buf_write_samples(s, &val, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
-
-done:
- spin_unlock_irqrestore(&devpriv->spinlock, flags);
-
- comedi_handle_events(dev, s);
-}
-
-static irqreturn_t interrupt_pcmmio(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- unsigned int triggered;
- unsigned char int_pend;
-
- /* are there any interrupts pending */
- int_pend = inb(dev->iobase + PCMMIO_INT_PENDING_REG) & 0x07;
- if (!int_pend)
- return IRQ_NONE;
-
- /* get, and clear, the pending interrupts */
- triggered = pcmmio_dio_read(dev, PCMMIO_PAGE_INT_ID, 0);
- pcmmio_dio_write(dev, 0, PCMMIO_PAGE_INT_ID, 0);
-
- pcmmio_handle_dio_intr(dev, s, triggered);
-
- return IRQ_HANDLED;
-}
-
-/* devpriv->spinlock is already locked */
-static void pcmmio_start_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcmmio_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int bits = 0;
- unsigned int pol_bits = 0;
- int i;
-
- devpriv->enabled_mask = 0;
- devpriv->active = 1;
- if (cmd->chanlist) {
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chanspec = cmd->chanlist[i];
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
-
- bits |= (1 << chan);
- pol_bits |= (((aref || range) ? 1 : 0) << chan);
- }
- }
- bits &= ((1 << s->n_chan) - 1);
- devpriv->enabled_mask = bits;
-
- /* set polarity and enable interrupts */
- pcmmio_dio_write(dev, pol_bits, PCMMIO_PAGE_POL, 0);
- pcmmio_dio_write(dev, bits, PCMMIO_PAGE_ENAB, 0);
-}
-
-static int pcmmio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcmmio_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->spinlock, flags);
- if (devpriv->active)
- pcmmio_stop_intr(dev, s);
- spin_unlock_irqrestore(&devpriv->spinlock, flags);
-
- return 0;
-}
-
-static int pcmmio_inttrig_start_intr(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct pcmmio_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned long flags;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- spin_lock_irqsave(&devpriv->spinlock, flags);
- s->async->inttrig = NULL;
- if (devpriv->active)
- pcmmio_start_intr(dev, s);
- spin_unlock_irqrestore(&devpriv->spinlock, flags);
-
- return 1;
-}
-
-/*
- * 'do_cmd' function for an 'INTERRUPT' subdevice.
- */
-static int pcmmio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcmmio_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->spinlock, flags);
- devpriv->active = 1;
-
- /* Set up start of acquisition. */
- if (cmd->start_src == TRIG_INT)
- s->async->inttrig = pcmmio_inttrig_start_intr;
- else /* TRIG_NOW */
- pcmmio_start_intr(dev, s);
-
- spin_unlock_irqrestore(&devpriv->spinlock, flags);
-
- return 0;
-}
-
-static int pcmmio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- /* if (err) return 4; */
-
- return 0;
-}
-
-static int pcmmio_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + PCMMIO_AI_STATUS_REG);
- if (status & PCMMIO_AI_STATUS_DATA_READY)
- return 0;
- return -EBUSY;
-}
-
-static int pcmmio_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long iobase = dev->iobase;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int aref = CR_AREF(insn->chanspec);
- unsigned char cmd = 0;
- unsigned int val;
- int ret;
- int i;
-
- /*
- * The PCM-MIO uses two Linear Tech LTC1859CG 8-channel A/D converters.
- * The devices use a full duplex serial interface which transmits and
- * receives data simultaneously. An 8-bit command is shifted into the
- * ADC interface to configure it for the next conversion. At the same
- * time, the data from the previous conversion is shifted out of the
- * device. Consequently, the conversion result is delayed by one
- * conversion from the command word.
- *
- * Setup the cmd for the conversions then do a dummy conversion to
- * flush the junk data. Then do each conversion requested by the
- * comedi_insn. Note that the last conversion will leave junk data
- * in ADC which will get flushed on the next comedi_insn.
- */
-
- if (chan > 7) {
- chan -= 8;
- iobase += PCMMIO_AI_2ND_ADC_OFFSET;
- }
-
- if (aref == AREF_GROUND)
- cmd |= PCMMIO_AI_CMD_SE;
- if (chan % 2)
- cmd |= PCMMIO_AI_CMD_ODD_CHAN;
- cmd |= PCMMIO_AI_CMD_CHAN_SEL(chan / 2);
- cmd |= PCMMIO_AI_CMD_RANGE(range);
-
- outb(cmd, iobase + PCMMIO_AI_CMD_REG);
-
- ret = comedi_timeout(dev, s, insn, pcmmio_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inb(iobase + PCMMIO_AI_LSB_REG);
- val |= inb(iobase + PCMMIO_AI_MSB_REG) << 8;
-
- for (i = 0; i < insn->n; i++) {
- outb(cmd, iobase + PCMMIO_AI_CMD_REG);
-
- ret = comedi_timeout(dev, s, insn, pcmmio_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inb(iobase + PCMMIO_AI_LSB_REG);
- val |= inb(iobase + PCMMIO_AI_MSB_REG) << 8;
-
- /* bipolar data is two's complement */
- if (comedi_range_is_bipolar(s, range))
- val = comedi_offset_munge(s, val);
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int pcmmio_ao_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + PCMMIO_AO_STATUS_REG);
- if (status & PCMMIO_AO_STATUS_DATA_READY)
- return 0;
- return -EBUSY;
-}
-
-static int pcmmio_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long iobase = dev->iobase;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned char cmd = 0;
- int ret;
- int i;
-
- /*
- * The PCM-MIO has two Linear Tech LTC2704 DAC devices. Each device
- * is a 4-channel converter with software-selectable output range.
- */
-
- if (chan > 3) {
- cmd |= PCMMIO_AO_CMD_CHAN_SEL(chan - 4);
- iobase += PCMMIO_AO_2ND_DAC_OFFSET;
- } else {
- cmd |= PCMMIO_AO_CMD_CHAN_SEL(chan);
- }
-
- /* set the range for the channel */
- outb(PCMMIO_AO_LSB_SPAN(range), iobase + PCMMIO_AO_LSB_REG);
- outb(0, iobase + PCMMIO_AO_MSB_REG);
- outb(cmd | PCMMIO_AO_CMD_WR_SPAN_UPDATE, iobase + PCMMIO_AO_CMD_REG);
-
- ret = comedi_timeout(dev, s, insn, pcmmio_ao_eoc, 0);
- if (ret)
- return ret;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- /* write the data to the channel */
- outb(val & 0xff, iobase + PCMMIO_AO_LSB_REG);
- outb((val >> 8) & 0xff, iobase + PCMMIO_AO_MSB_REG);
- outb(cmd | PCMMIO_AO_CMD_WR_CODE_UPDATE,
- iobase + PCMMIO_AO_CMD_REG);
-
- ret = comedi_timeout(dev, s, insn, pcmmio_ao_eoc, 0);
- if (ret)
- return ret;
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct pcmmio_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 32);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- spin_lock_init(&devpriv->pagelock);
- spin_lock_init(&devpriv->spinlock);
-
- pcmmio_reset(dev);
-
- if (it->options[1]) {
- ret = request_irq(it->options[1], interrupt_pcmmio, 0,
- dev->board_name, dev);
- if (ret == 0) {
- dev->irq = it->options[1];
-
- /* configure the interrupt routing on the board */
- outb(PCMMIO_AI_RES_ENA_DIO_RES_ACCESS,
- dev->iobase + PCMMIO_AI_RES_ENA_REG);
- outb(PCMMIO_RESOURCE_IRQ(dev->irq),
- dev->iobase + PCMMIO_RESOURCE_REG);
- }
- }
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = 0xffff;
- s->range_table = &pcmmio_ai_ranges;
- s->insn_read = pcmmio_ai_insn_read;
-
- /* initialize the resource enable register by clearing it */
- outb(PCMMIO_AI_RES_ENA_CMD_REG_ACCESS,
- dev->iobase + PCMMIO_AI_RES_ENA_REG);
- outb(PCMMIO_AI_RES_ENA_CMD_REG_ACCESS,
- dev->iobase + PCMMIO_AI_RES_ENA_REG + PCMMIO_AI_2ND_ADC_OFFSET);
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->maxdata = 0xffff;
- s->range_table = &pcmmio_ao_ranges;
- s->insn_write = pcmmio_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* initialize the resource enable register by clearing it */
- outb(0, dev->iobase + PCMMIO_AO_RESOURCE_ENA_REG);
- outb(0, dev->iobase + PCMMIO_AO_2ND_DAC_OFFSET +
- PCMMIO_AO_RESOURCE_ENA_REG);
-
- /* Digital I/O subdevice with interrupt support */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->len_chanlist = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcmmio_dio_insn_bits;
- s->insn_config = pcmmio_dio_insn_config;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL | SDF_PACKED;
- s->len_chanlist = s->n_chan;
- s->cancel = pcmmio_cancel;
- s->do_cmd = pcmmio_cmd;
- s->do_cmdtest = pcmmio_cmdtest;
- }
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcmmio_dio_insn_bits;
- s->insn_config = pcmmio_dio_insn_config;
-
- return 0;
-}
-
-static struct comedi_driver pcmmio_driver = {
- .driver_name = "pcmmio",
- .module = THIS_MODULE,
- .attach = pcmmio_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(pcmmio_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Winsystems PCM-MIO PC/104 board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
deleted file mode 100644
index b299d648a0eb..000000000000
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ /dev/null
@@ -1,624 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * pcmuio.c
- * Comedi driver for Winsystems PC-104 based 48/96-channel DIO boards.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
- */
-
-/*
- * Driver: pcmuio
- * Description: Winsystems PC-104 based 48/96-channel DIO boards.
- * Devices: [Winsystems] PCM-UIO48A (pcmuio48), PCM-UIO96A (pcmuio96)
- * Author: Calin Culianu <calin@ajvar.org>
- * Updated: Fri, 13 Jan 2006 12:01:01 -0500
- * Status: works
- *
- * A driver for the relatively straightforward-to-program PCM-UIO48A and
- * PCM-UIO96A boards from Winsystems. These boards use either one or two
- * (in the 96-DIO version) WS16C48 ASIC HighDensity I/O Chips (HDIO). This
- * chip is interesting in that each I/O line is individually programmable
- * for INPUT or OUTPUT (thus comedi_dio_config can be done on a per-channel
- * basis). Also, each chip supports edge-triggered interrupts for the first
- * 24 I/O lines. Of course, since the 96-channel version of the board has
- * two ASICs, it can detect polarity changes on up to 48 I/O lines. Since
- * this is essentially an (non-PnP) ISA board, I/O Address and IRQ selection
- * are done through jumpers on the board. You need to pass that information
- * to this driver as the first and second comedi_config option, respectively.
- * Note that the 48-channel version uses 16 bytes of IO memory and the 96-
- * channel version uses 32-bytes (in case you are worried about conflicts).
- * The 48-channel board is split into two 24-channel comedi subdevices. The
- * 96-channel board is split into 4 24-channel DIO subdevices.
- *
- * Note that IRQ support has been added, but it is untested.
- *
- * To use edge-detection IRQ support, pass the IRQs of both ASICS (for the
- * 96 channel version) or just 1 ASIC (for 48-channel version). Then, use
- * comedi_commands with TRIG_NOW. Your callback will be called each time an
- * edge is triggered, and the data values will be two sample_t's, which
- * should be concatenated to form one 32-bit unsigned int. This value is
- * the mask of channels that had edges detected from your channel list. Note
- * that the bits positions in the mask correspond to positions in your
- * chanlist when you specified the command and *not* channel id's!
- *
- * To set the polarity of the edge-detection interrupts pass a nonzero value
- * for either CR_RANGE or CR_AREF for edge-up polarity, or a zero value for
- * both CR_RANGE and CR_AREF if you want edge-down polarity.
- *
- * In the 48-channel version:
- *
- * On subdev 0, the first 24 channels are edge-detect channels.
- *
- * In the 96-channel board you have the following channels that can do edge
- * detection:
- *
- * subdev 0, channels 0-24 (first 24 channels of 1st ASIC)
- * subdev 2, channels 0-24 (first 24 channels of 2nd ASIC)
- *
- * Configuration Options:
- * [0] - I/O port base address
- * [1] - IRQ (for first ASIC, or first 24 channels)
- * [2] - IRQ (for second ASIC, pcmuio96 only - IRQ for chans 48-72
- * can be the same as first irq!)
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-/*
- * Register I/O map
- *
- * Offset Page 0 Page 1 Page 2 Page 3
- * ------ ----------- ----------- ----------- -----------
- * 0x00 Port 0 I/O Port 0 I/O Port 0 I/O Port 0 I/O
- * 0x01 Port 1 I/O Port 1 I/O Port 1 I/O Port 1 I/O
- * 0x02 Port 2 I/O Port 2 I/O Port 2 I/O Port 2 I/O
- * 0x03 Port 3 I/O Port 3 I/O Port 3 I/O Port 3 I/O
- * 0x04 Port 4 I/O Port 4 I/O Port 4 I/O Port 4 I/O
- * 0x05 Port 5 I/O Port 5 I/O Port 5 I/O Port 5 I/O
- * 0x06 INT_PENDING INT_PENDING INT_PENDING INT_PENDING
- * 0x07 Page/Lock Page/Lock Page/Lock Page/Lock
- * 0x08 N/A POL_0 ENAB_0 INT_ID0
- * 0x09 N/A POL_1 ENAB_1 INT_ID1
- * 0x0a N/A POL_2 ENAB_2 INT_ID2
- */
-#define PCMUIO_PORT_REG(x) (0x00 + (x))
-#define PCMUIO_INT_PENDING_REG 0x06
-#define PCMUIO_PAGE_LOCK_REG 0x07
-#define PCMUIO_LOCK_PORT(x) ((1 << (x)) & 0x3f)
-#define PCMUIO_PAGE(x) (((x) & 0x3) << 6)
-#define PCMUIO_PAGE_MASK PCMUIO_PAGE(3)
-#define PCMUIO_PAGE_POL 1
-#define PCMUIO_PAGE_ENAB 2
-#define PCMUIO_PAGE_INT_ID 3
-#define PCMUIO_PAGE_REG(x) (0x08 + (x))
-
-#define PCMUIO_ASIC_IOSIZE 0x10
-#define PCMUIO_MAX_ASICS 2
-
-struct pcmuio_board {
- const char *name;
- const int num_asics;
-};
-
-static const struct pcmuio_board pcmuio_boards[] = {
- {
- .name = "pcmuio48",
- .num_asics = 1,
- }, {
- .name = "pcmuio96",
- .num_asics = 2,
- },
-};
-
-struct pcmuio_asic {
- spinlock_t pagelock; /* protects the page registers */
- spinlock_t spinlock; /* protects member variables */
- unsigned int enabled_mask;
- unsigned int active:1;
-};
-
-struct pcmuio_private {
- struct pcmuio_asic asics[PCMUIO_MAX_ASICS];
- unsigned int irq2;
-};
-
-static inline unsigned long pcmuio_asic_iobase(struct comedi_device *dev,
- int asic)
-{
- return dev->iobase + (asic * PCMUIO_ASIC_IOSIZE);
-}
-
-static inline int pcmuio_subdevice_to_asic(struct comedi_subdevice *s)
-{
- /*
- * subdevice 0 and 1 are handled by the first asic
- * subdevice 2 and 3 are handled by the second asic
- */
- return s->index / 2;
-}
-
-static inline int pcmuio_subdevice_to_port(struct comedi_subdevice *s)
-{
- /*
- * subdevice 0 and 2 use port registers 0-2
- * subdevice 1 and 3 use port registers 3-5
- */
- return (s->index % 2) ? 3 : 0;
-}
-
-static void pcmuio_write(struct comedi_device *dev, unsigned int val,
- int asic, int page, int port)
-{
- struct pcmuio_private *devpriv = dev->private;
- struct pcmuio_asic *chip = &devpriv->asics[asic];
- unsigned long iobase = pcmuio_asic_iobase(dev, asic);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->pagelock, flags);
- if (page == 0) {
- /* Port registers are valid for any page */
- outb(val & 0xff, iobase + PCMUIO_PORT_REG(port + 0));
- outb((val >> 8) & 0xff, iobase + PCMUIO_PORT_REG(port + 1));
- outb((val >> 16) & 0xff, iobase + PCMUIO_PORT_REG(port + 2));
- } else {
- outb(PCMUIO_PAGE(page), iobase + PCMUIO_PAGE_LOCK_REG);
- outb(val & 0xff, iobase + PCMUIO_PAGE_REG(0));
- outb((val >> 8) & 0xff, iobase + PCMUIO_PAGE_REG(1));
- outb((val >> 16) & 0xff, iobase + PCMUIO_PAGE_REG(2));
- }
- spin_unlock_irqrestore(&chip->pagelock, flags);
-}
-
-static unsigned int pcmuio_read(struct comedi_device *dev,
- int asic, int page, int port)
-{
- struct pcmuio_private *devpriv = dev->private;
- struct pcmuio_asic *chip = &devpriv->asics[asic];
- unsigned long iobase = pcmuio_asic_iobase(dev, asic);
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&chip->pagelock, flags);
- if (page == 0) {
- /* Port registers are valid for any page */
- val = inb(iobase + PCMUIO_PORT_REG(port + 0));
- val |= (inb(iobase + PCMUIO_PORT_REG(port + 1)) << 8);
- val |= (inb(iobase + PCMUIO_PORT_REG(port + 2)) << 16);
- } else {
- outb(PCMUIO_PAGE(page), iobase + PCMUIO_PAGE_LOCK_REG);
- val = inb(iobase + PCMUIO_PAGE_REG(0));
- val |= (inb(iobase + PCMUIO_PAGE_REG(1)) << 8);
- val |= (inb(iobase + PCMUIO_PAGE_REG(2)) << 16);
- }
- spin_unlock_irqrestore(&chip->pagelock, flags);
-
- return val;
-}
-
-/*
- * Each channel can be individually programmed for input or output.
- * Writing a '0' to a channel causes the corresponding output pin
- * to go to a high-z state (pulled high by an external 10K resistor).
- * This allows it to be used as an input. When used in the input mode,
- * a read reflects the inverted state of the I/O pin, such that a
- * high on the pin will read as a '0' in the register. Writing a '1'
- * to a bit position causes the pin to sink current (up to 12mA),
- * effectively pulling it low.
- */
-static int pcmuio_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int asic = pcmuio_subdevice_to_asic(s);
- int port = pcmuio_subdevice_to_port(s);
- unsigned int chanmask = (1 << s->n_chan) - 1;
- unsigned int mask;
- unsigned int val;
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- /*
- * Outputs are inverted, invert the state and
- * update the channels.
- *
- * The s->io_bits mask makes sure the input channels
- * are '0' so that the outputs pins stay in a high
- * z-state.
- */
- val = ~s->state & chanmask;
- val &= s->io_bits;
- pcmuio_write(dev, val, asic, 0, port);
- }
-
- /* get inverted state of the channels from the port */
- val = pcmuio_read(dev, asic, 0, port);
-
- /* return the true state of the channels */
- data[1] = ~val & chanmask;
-
- return insn->n;
-}
-
-static int pcmuio_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int asic = pcmuio_subdevice_to_asic(s);
- int port = pcmuio_subdevice_to_port(s);
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- if (data[0] == INSN_CONFIG_DIO_INPUT)
- pcmuio_write(dev, s->io_bits, asic, 0, port);
-
- return insn->n;
-}
-
-static void pcmuio_reset(struct comedi_device *dev)
-{
- const struct pcmuio_board *board = dev->board_ptr;
- int asic;
-
- for (asic = 0; asic < board->num_asics; ++asic) {
- /* first, clear all the DIO port bits */
- pcmuio_write(dev, 0, asic, 0, 0);
- pcmuio_write(dev, 0, asic, 0, 3);
-
- /* Next, clear all the paged registers for each page */
- pcmuio_write(dev, 0, asic, PCMUIO_PAGE_POL, 0);
- pcmuio_write(dev, 0, asic, PCMUIO_PAGE_ENAB, 0);
- pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0);
- }
-}
-
-/* chip->spinlock is already locked */
-static void pcmuio_stop_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcmuio_private *devpriv = dev->private;
- int asic = pcmuio_subdevice_to_asic(s);
- struct pcmuio_asic *chip = &devpriv->asics[asic];
-
- chip->enabled_mask = 0;
- chip->active = 0;
- s->async->inttrig = NULL;
-
- /* disable all intrs for this subdev.. */
- pcmuio_write(dev, 0, asic, PCMUIO_PAGE_ENAB, 0);
-}
-
-static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int triggered)
-{
- struct pcmuio_private *devpriv = dev->private;
- int asic = pcmuio_subdevice_to_asic(s);
- struct pcmuio_asic *chip = &devpriv->asics[asic];
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int val = 0;
- unsigned long flags;
- unsigned int i;
-
- spin_lock_irqsave(&chip->spinlock, flags);
-
- if (!chip->active)
- goto done;
-
- if (!(triggered & chip->enabled_mask))
- goto done;
-
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- if (triggered & (1 << chan))
- val |= (1 << i);
- }
-
- comedi_buf_write_samples(s, &val, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg)
- s->async->events |= COMEDI_CB_EOA;
-
-done:
- spin_unlock_irqrestore(&chip->spinlock, flags);
-
- comedi_handle_events(dev, s);
-}
-
-static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic)
-{
- /* there are could be two asics so we can't use dev->read_subdev */
- struct comedi_subdevice *s = &dev->subdevices[asic * 2];
- unsigned long iobase = pcmuio_asic_iobase(dev, asic);
- unsigned int val;
-
- /* are there any interrupts pending */
- val = inb(iobase + PCMUIO_INT_PENDING_REG) & 0x07;
- if (!val)
- return 0;
-
- /* get, and clear, the pending interrupts */
- val = pcmuio_read(dev, asic, PCMUIO_PAGE_INT_ID, 0);
- pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0);
-
- /* handle the pending interrupts */
- pcmuio_handle_intr_subdev(dev, s, val);
-
- return 1;
-}
-
-static irqreturn_t pcmuio_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct pcmuio_private *devpriv = dev->private;
- int handled = 0;
-
- if (irq == dev->irq)
- handled += pcmuio_handle_asic_interrupt(dev, 0);
- if (irq == devpriv->irq2)
- handled += pcmuio_handle_asic_interrupt(dev, 1);
-
- return handled ? IRQ_HANDLED : IRQ_NONE;
-}
-
-/* chip->spinlock is already locked */
-static void pcmuio_start_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcmuio_private *devpriv = dev->private;
- int asic = pcmuio_subdevice_to_asic(s);
- struct pcmuio_asic *chip = &devpriv->asics[asic];
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int bits = 0;
- unsigned int pol_bits = 0;
- int i;
-
- chip->enabled_mask = 0;
- chip->active = 1;
- if (cmd->chanlist) {
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chanspec = cmd->chanlist[i];
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
-
- bits |= (1 << chan);
- pol_bits |= ((aref || range) ? 1 : 0) << chan;
- }
- }
- bits &= ((1 << s->n_chan) - 1);
- chip->enabled_mask = bits;
-
- /* set pol and enab intrs for this subdev.. */
- pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0);
- pcmuio_write(dev, bits, asic, PCMUIO_PAGE_ENAB, 0);
-}
-
-static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcmuio_private *devpriv = dev->private;
- int asic = pcmuio_subdevice_to_asic(s);
- struct pcmuio_asic *chip = &devpriv->asics[asic];
- unsigned long flags;
-
- spin_lock_irqsave(&chip->spinlock, flags);
- if (chip->active)
- pcmuio_stop_intr(dev, s);
- spin_unlock_irqrestore(&chip->spinlock, flags);
-
- return 0;
-}
-
-static int pcmuio_inttrig_start_intr(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct pcmuio_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int asic = pcmuio_subdevice_to_asic(s);
- struct pcmuio_asic *chip = &devpriv->asics[asic];
- unsigned long flags;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- spin_lock_irqsave(&chip->spinlock, flags);
- s->async->inttrig = NULL;
- if (chip->active)
- pcmuio_start_intr(dev, s);
-
- spin_unlock_irqrestore(&chip->spinlock, flags);
-
- return 1;
-}
-
-/*
- * 'do_cmd' function for an 'INTERRUPT' subdevice.
- */
-static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct pcmuio_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int asic = pcmuio_subdevice_to_asic(s);
- struct pcmuio_asic *chip = &devpriv->asics[asic];
- unsigned long flags;
-
- spin_lock_irqsave(&chip->spinlock, flags);
- chip->active = 1;
-
- /* Set up start of acquisition. */
- if (cmd->start_src == TRIG_INT)
- s->async->inttrig = pcmuio_inttrig_start_intr;
- else /* TRIG_NOW */
- pcmuio_start_intr(dev, s);
-
- spin_unlock_irqrestore(&chip->spinlock, flags);
-
- return 0;
-}
-
-static int pcmuio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- /* if (err) return 4; */
-
- return 0;
-}
-
-static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct pcmuio_board *board = dev->board_ptr;
- struct comedi_subdevice *s;
- struct pcmuio_private *devpriv;
- int ret;
- int i;
-
- ret = comedi_request_region(dev, it->options[0],
- board->num_asics * PCMUIO_ASIC_IOSIZE);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- for (i = 0; i < PCMUIO_MAX_ASICS; ++i) {
- struct pcmuio_asic *chip = &devpriv->asics[i];
-
- spin_lock_init(&chip->pagelock);
- spin_lock_init(&chip->spinlock);
- }
-
- pcmuio_reset(dev);
-
- if (it->options[1]) {
- /* request the irq for the 1st asic */
- ret = request_irq(it->options[1], pcmuio_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[1];
- }
-
- if (board->num_asics == 2) {
- if (it->options[2] == dev->irq) {
- /* the same irq (or none) is used by both asics */
- devpriv->irq2 = it->options[2];
- } else if (it->options[2]) {
- /* request the irq for the 2nd asic */
- ret = request_irq(it->options[2], pcmuio_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- devpriv->irq2 = it->options[2];
- }
- }
-
- ret = comedi_alloc_subdevices(dev, board->num_asics * 2);
- if (ret)
- return ret;
-
- for (i = 0; i < dev->n_subdevices; ++i) {
- s = &dev->subdevices[i];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pcmuio_dio_insn_bits;
- s->insn_config = pcmuio_dio_insn_config;
-
- /* subdevices 0 and 2 can support interrupts */
- if ((i == 0 && dev->irq) || (i == 2 && devpriv->irq2)) {
- /* setup the interrupt subdevice */
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ | SDF_LSAMPL |
- SDF_PACKED;
- s->len_chanlist = s->n_chan;
- s->cancel = pcmuio_cancel;
- s->do_cmd = pcmuio_cmd;
- s->do_cmdtest = pcmuio_cmdtest;
- }
- }
-
- return 0;
-}
-
-static void pcmuio_detach(struct comedi_device *dev)
-{
- struct pcmuio_private *devpriv = dev->private;
-
- if (devpriv) {
- pcmuio_reset(dev);
-
- /* free the 2nd irq if used, the core will free the 1st one */
- if (devpriv->irq2 && devpriv->irq2 != dev->irq)
- free_irq(devpriv->irq2, dev);
- }
- comedi_legacy_detach(dev);
-}
-
-static struct comedi_driver pcmuio_driver = {
- .driver_name = "pcmuio",
- .module = THIS_MODULE,
- .attach = pcmuio_attach,
- .detach = pcmuio_detach,
- .board_name = &pcmuio_boards[0].name,
- .offset = sizeof(struct pcmuio_board),
- .num_names = ARRAY_SIZE(pcmuio_boards),
-};
-module_comedi_driver(pcmuio_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h
deleted file mode 100644
index e68a7afef025..000000000000
--- a/drivers/staging/comedi/drivers/plx9052.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Definitions for the PLX-9052 PCI interface chip
- *
- * Copyright (C) 2002 MEV Ltd. <https://www.mev.co.uk/>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-#ifndef _PLX9052_H_
-#define _PLX9052_H_
-
-/*
- * INTCSR - Interrupt Control/Status register
- */
-#define PLX9052_INTCSR 0x4c
-#define PLX9052_INTCSR_LI1ENAB BIT(0) /* LI1 enabled */
-#define PLX9052_INTCSR_LI1POL BIT(1) /* LI1 active high */
-#define PLX9052_INTCSR_LI1STAT BIT(2) /* LI1 active */
-#define PLX9052_INTCSR_LI2ENAB BIT(3) /* LI2 enabled */
-#define PLX9052_INTCSR_LI2POL BIT(4) /* LI2 active high */
-#define PLX9052_INTCSR_LI2STAT BIT(5) /* LI2 active */
-#define PLX9052_INTCSR_PCIENAB BIT(6) /* PCIINT enabled */
-#define PLX9052_INTCSR_SOFTINT BIT(7) /* generate soft int */
-#define PLX9052_INTCSR_LI1SEL BIT(8) /* LI1 edge */
-#define PLX9052_INTCSR_LI2SEL BIT(9) /* LI2 edge */
-#define PLX9052_INTCSR_LI1CLRINT BIT(10) /* LI1 clear int */
-#define PLX9052_INTCSR_LI2CLRINT BIT(11) /* LI2 clear int */
-#define PLX9052_INTCSR_ISAMODE BIT(12) /* ISA interface mode */
-
-/*
- * CNTRL - User I/O, Direct Slave Response, Serial EEPROM, and
- * Initialization Control register
- */
-#define PLX9052_CNTRL 0x50
-#define PLX9052_CNTRL_WAITO BIT(0) /* UIO0 or WAITO# select */
-#define PLX9052_CNTRL_UIO0_DIR BIT(1) /* UIO0 direction */
-#define PLX9052_CNTRL_UIO0_DATA BIT(2) /* UIO0 data */
-#define PLX9052_CNTRL_LLOCKO BIT(3) /* UIO1 or LLOCKo# select */
-#define PLX9052_CNTRL_UIO1_DIR BIT(4) /* UIO1 direction */
-#define PLX9052_CNTRL_UIO1_DATA BIT(5) /* UIO1 data */
-#define PLX9052_CNTRL_CS2 BIT(6) /* UIO2 or CS2# select */
-#define PLX9052_CNTRL_UIO2_DIR BIT(7) /* UIO2 direction */
-#define PLX9052_CNTRL_UIO2_DATA BIT(8) /* UIO2 data */
-#define PLX9052_CNTRL_CS3 BIT(9) /* UIO3 or CS3# select */
-#define PLX9052_CNTRL_UIO3_DIR BIT(10) /* UIO3 direction */
-#define PLX9052_CNTRL_UIO3_DATA BIT(11) /* UIO3 data */
-#define PLX9052_CNTRL_PCIBAR(x) (((x) & 0x3) << 12)
-#define PLX9052_CNTRL_PCIBAR01 PLX9052_CNTRL_PCIBAR(0) /* mem and IO */
-#define PLX9052_CNTRL_PCIBAR0 PLX9052_CNTRL_PCIBAR(1) /* mem only */
-#define PLX9052_CNTRL_PCIBAR1 PLX9052_CNTRL_PCIBAR(2) /* IO only */
-#define PLX9052_CNTRL_PCI2_1_FEATURES BIT(14) /* PCI v2.1 features enabled */
-#define PLX9052_CNTRL_PCI_R_W_FLUSH BIT(15) /* read w/write flush mode */
-#define PLX9052_CNTRL_PCI_R_NO_FLUSH BIT(16) /* read no flush mode */
-#define PLX9052_CNTRL_PCI_R_NO_WRITE BIT(17) /* read no write mode */
-#define PLX9052_CNTRL_PCI_W_RELEASE BIT(18) /* write release bus mode */
-#define PLX9052_CNTRL_RETRY_CLKS(x) (((x) & 0xf) << 19) /* retry clks */
-#define PLX9052_CNTRL_LOCK_ENAB BIT(23) /* slave LOCK# enable */
-#define PLX9052_CNTRL_EEPROM_MASK (0x1f << 24) /* EEPROM bits */
-#define PLX9052_CNTRL_EEPROM_CLK BIT(24) /* EEPROM clock */
-#define PLX9052_CNTRL_EEPROM_CS BIT(25) /* EEPROM chip select */
-#define PLX9052_CNTRL_EEPROM_DOUT BIT(26) /* EEPROM write bit */
-#define PLX9052_CNTRL_EEPROM_DIN BIT(27) /* EEPROM read bit */
-#define PLX9052_CNTRL_EEPROM_PRESENT BIT(28) /* EEPROM present */
-#define PLX9052_CNTRL_RELOAD_CFG BIT(29) /* reload configuration */
-#define PLX9052_CNTRL_PCI_RESET BIT(30) /* PCI adapter reset */
-#define PLX9052_CNTRL_MASK_REV BIT(31) /* mask revision */
-
-#endif /* _PLX9052_H_ */
diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h
deleted file mode 100644
index aa0eda5a8093..000000000000
--- a/drivers/staging/comedi/drivers/plx9080.h
+++ /dev/null
@@ -1,656 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * plx9080.h
- *
- * Copyright (C) 2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
- *
- ********************************************************************
- *
- * Copyright (C) 1999 RG Studio s.c.
- * Written by Krzysztof Halasa <khc@rgstudio.com.pl>
- *
- * Portions (C) SBE Inc., used by permission.
- */
-
-#ifndef __COMEDI_PLX9080_H
-#define __COMEDI_PLX9080_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-
-/**
- * struct plx_dma_desc - DMA descriptor format for PLX PCI 9080
- * @pci_start_addr: PCI Bus address for transfer (DMAPADR).
- * @local_start_addr: Local Bus address for transfer (DMALADR).
- * @transfer_size: Transfer size in bytes (max 8 MiB) (DMASIZ).
- * @next: Address of next descriptor + flags (DMADPR).
- *
- * Describes the format of a scatter-gather DMA descriptor for the PLX
- * PCI 9080. All members are raw, little-endian register values that
- * will be transferred by the DMA engine from local or PCI memory into
- * corresponding registers for the DMA channel.
- *
- * The DMA descriptors must be aligned on a 16-byte boundary. Bits 3:0
- * of @next contain flags describing the address space of the next
- * descriptor (local or PCI), an "end of chain" marker, an "interrupt on
- * terminal count" bit, and a data transfer direction.
- */
-struct plx_dma_desc {
- __le32 pci_start_addr;
- __le32 local_start_addr;
- __le32 transfer_size;
- __le32 next;
-};
-
-/*
- * Register Offsets and Bit Definitions
- */
-
-/* Local Address Space 0 Range Register */
-#define PLX_REG_LAS0RR 0x0000
-/* Local Address Space 1 Range Register */
-#define PLX_REG_LAS1RR 0x00f0
-
-#define PLX_LASRR_IO BIT(0) /* Map to: 1=I/O, 0=Mem */
-#define PLX_LASRR_MLOC_ANY32 (BIT(1) * 0) /* Locate anywhere in 32 bit */
-#define PLX_LASRR_MLOC_LT1MB (BIT(1) * 1) /* Locate in 1st meg */
-#define PLX_LASRR_MLOC_ANY64 (BIT(1) * 2) /* Locate anywhere in 64 bit */
-#define PLX_LASRR_MLOC_MASK GENMASK(2, 1) /* Memory location bits */
-#define PLX_LASRR_PREFETCH BIT(3) /* Memory is prefetchable */
-/* bits that specify range for memory space decode bits */
-#define PLX_LASRR_MEM_MASK GENMASK(31, 4)
-/* bits that specify range for i/o space decode bits */
-#define PLX_LASRR_IO_MASK GENMASK(31, 2)
-
-/* Local Address Space 0 Local Base Address (Remap) Register */
-#define PLX_REG_LAS0BA 0x0004
-/* Local Address Space 1 Local Base Address (Remap) Register */
-#define PLX_REG_LAS1BA 0x00f4
-
-#define PLX_LASBA_EN BIT(0) /* Enable slave decode */
-/* bits that specify local base address for memory space */
-#define PLX_LASBA_MEM_MASK GENMASK(31, 4)
-/* bits that specify local base address for i/o space */
-#define PLX_LASBA_IO_MASK GENMASK(31, 2)
-
-/* Mode/Arbitration Register */
-#define PLX_REG_MARBR 0x0008
-/* DMA Arbitration Register (alias of MARBR). */
-#define PLX_REG_DMAARB 0x00ac
-
-/* Local Bus Latency Timer */
-#define PLX_MARBR_LT(x) (BIT(0) * ((x) & 0xff))
-#define PLX_MARBR_LT_MASK GENMASK(7, 0)
-#define PLX_MARBR_TO_LT(r) ((r) & PLX_MARBR_LT_MASK)
-/* Local Bus Pause Timer */
-#define PLX_MARBR_PT(x) (BIT(8) * ((x) & 0xff))
-#define PLX_MARBR_PT_MASK GENMASK(15, 8)
-#define PLX_MARBR_TO_PT(r) (((r) & PLX_MARBR_PT_MASK) >> 8)
-/* Local Bus Latency Timer Enable */
-#define PLX_MARBR_LTEN BIT(16)
-/* Local Bus Pause Timer Enable */
-#define PLX_MARBR_PTEN BIT(17)
-/* Local Bus BREQ Enable */
-#define PLX_MARBR_BREQEN BIT(18)
-/* DMA Channel Priority */
-#define PLX_MARBR_PRIO_ROT (BIT(19) * 0) /* Rotational priority */
-#define PLX_MARBR_PRIO_DMA0 (BIT(19) * 1) /* DMA channel 0 has priority */
-#define PLX_MARBR_PRIO_DMA1 (BIT(19) * 2) /* DMA channel 1 has priority */
-#define PLX_MARBR_PRIO_MASK GENMASK(20, 19)
-/* Local Bus Direct Slave Give Up Bus Mode */
-#define PLX_MARBR_DSGUBM BIT(21)
-/* Direct Slace LLOCKo# Enable */
-#define PLX_MARBR_DSLLOCKOEN BIT(22)
-/* PCI Request Mode */
-#define PLX_MARBR_PCIREQM BIT(23)
-/* PCI Specification v2.1 Mode */
-#define PLX_MARBR_PCIV21M BIT(24)
-/* PCI Read No Write Mode */
-#define PLX_MARBR_PCIRNWM BIT(25)
-/* PCI Read with Write Flush Mode */
-#define PLX_MARBR_PCIRWFM BIT(26)
-/* Gate Local Bus Latency Timer with BREQ */
-#define PLX_MARBR_GLTBREQ BIT(27)
-/* PCI Read No Flush Mode */
-#define PLX_MARBR_PCIRNFM BIT(28)
-/*
- * Make reads from PCI Configuration register 0 return Subsystem ID and
- * Subsystem Vendor ID instead of Device ID and Vendor ID
- */
-#define PLX_MARBR_SUBSYSIDS BIT(29)
-
-/* Big/Little Endian Descriptor Register */
-#define PLX_REG_BIGEND 0x000c
-
-/* Configuration Register Big Endian Mode */
-#define PLX_BIGEND_CONFIG BIT(0)
-/* Direct Master Big Endian Mode */
-#define PLX_BIGEND_DM BIT(1)
-/* Direct Slave Address Space 0 Big Endian Mode */
-#define PLX_BIGEND_DSAS0 BIT(2)
-/* Direct Slave Expansion ROM Big Endian Mode */
-#define PLX_BIGEND_EROM BIT(3)
-/* Big Endian Byte Lane Mode - use most significant byte lanes */
-#define PLX_BIGEND_BEBLM BIT(4)
-/* Direct Slave Address Space 1 Big Endian Mode */
-#define PLX_BIGEND_DSAS1 BIT(5)
-/* DMA Channel 1 Big Endian Mode */
-#define PLX_BIGEND_DMA1 BIT(6)
-/* DMA Channel 0 Big Endian Mode */
-#define PLX_BIGEND_DMA0 BIT(7)
-/* DMA Channel N Big Endian Mode (N <= 1) */
-#define PLX_BIGEND_DMA(n) ((n) ? PLX_BIGEND_DMA1 : PLX_BIGEND_DMA0)
-
-/*
- * Note: The Expansion ROM stuff is only relevant to the PC environment.
- * This expansion ROM code is executed by the host CPU at boot time.
- * For this reason no bit definitions are provided here.
- */
-
-/* Expansion ROM Range Register */
-#define PLX_REG_EROMRR 0x0010
-/* Expansion ROM Local Base Address (Remap) Register */
-#define PLX_REG_EROMBA 0x0014
-
-/* Local Address Space 0/Expansion ROM Bus Region Descriptor Register */
-#define PLX_REG_LBRD0 0x0018
-/* Local Address Space 1 Bus Region Descriptor Register */
-#define PLX_REG_LBRD1 0x00f8
-
-/* Memory Space Local Bus Width */
-#define PLX_LBRD_MSWIDTH_8 (BIT(0) * 0) /* 8 bits wide */
-#define PLX_LBRD_MSWIDTH_16 (BIT(0) * 1) /* 16 bits wide */
-#define PLX_LBRD_MSWIDTH_32 (BIT(0) * 2) /* 32 bits wide */
-#define PLX_LBRD_MSWIDTH_32A (BIT(0) * 3) /* 32 bits wide */
-#define PLX_LBRD_MSWIDTH_MASK GENMASK(1, 0)
-/* Memory Space Internal Wait States */
-#define PLX_LBRD_MSIWS(x) (BIT(2) * ((x) & 0xf))
-#define PLX_LBRD_MSIWS_MASK GENMASK(5, 2)
-#define PLX_LBRD_TO_MSIWS(r) (((r) & PLS_LBRD_MSIWS_MASK) >> 2)
-/* Memory Space Ready Input Enable */
-#define PLX_LBRD_MSREADYIEN BIT(6)
-/* Memory Space BTERM# Input Enable */
-#define PLX_LBRD_MSBTERMIEN BIT(7)
-/* Memory Space 0 Prefetch Disable (LBRD0 only) */
-#define PLX_LBRD0_MSPREDIS BIT(8)
-/* Memory Space 1 Burst Enable (LBRD1 only) */
-#define PLX_LBRD1_MSBURSTEN BIT(8)
-/* Expansion ROM Space Prefetch Disable (LBRD0 only) */
-#define PLX_LBRD0_EROMPREDIS BIT(9)
-/* Memory Space 1 Prefetch Disable (LBRD1 only) */
-#define PLX_LBRD1_MSPREDIS BIT(9)
-/* Read Prefetch Count Enable */
-#define PLX_LBRD_RPFCOUNTEN BIT(10)
-/* Prefetch Counter */
-#define PLX_LBRD_PFCOUNT(x) (BIT(11) * ((x) & 0xf))
-#define PLX_LBRD_PFCOUNT_MASK GENMASK(14, 11)
-#define PLX_LBRD_TO_PFCOUNT(r) (((r) & PLX_LBRD_PFCOUNT_MASK) >> 11)
-/* Expansion ROM Space Local Bus Width (LBRD0 only) */
-#define PLX_LBRD0_EROMWIDTH_8 (BIT(16) * 0) /* 8 bits wide */
-#define PLX_LBRD0_EROMWIDTH_16 (BIT(16) * 1) /* 16 bits wide */
-#define PLX_LBRD0_EROMWIDTH_32 (BIT(16) * 2) /* 32 bits wide */
-#define PLX_LBRD0_EROMWIDTH_32A (BIT(16) * 3) /* 32 bits wide */
-#define PLX_LBRD0_EROMWIDTH_MASK GENMASK(17, 16)
-/* Expansion ROM Space Internal Wait States (LBRD0 only) */
-#define PLX_LBRD0_EROMIWS(x) (BIT(18) * ((x) & 0xf))
-#define PLX_LBRD0_EROMIWS_MASK GENMASK(21, 18)
-#define PLX_LBRD0_TO_EROMIWS(r) (((r) & PLX_LBRD0_EROMIWS_MASK) >> 18)
-/* Expansion ROM Space Ready Input Enable (LBDR0 only) */
-#define PLX_LBRD0_EROMREADYIEN BIT(22)
-/* Expansion ROM Space BTERM# Input Enable (LBRD0 only) */
-#define PLX_LBRD0_EROMBTERMIEN BIT(23)
-/* Memory Space 0 Burst Enable (LBRD0 only) */
-#define PLX_LBRD0_MSBURSTEN BIT(24)
-/* Extra Long Load From Serial EEPROM (LBRD0 only) */
-#define PLX_LBRD0_EELONGLOAD BIT(25)
-/* Expansion ROM Space Burst Enable (LBRD0 only) */
-#define PLX_LBRD0_EROMBURSTEN BIT(26)
-/* Direct Slave PCI Write Mode - assert TRDY# when FIFO full (LBRD0 only) */
-#define PLX_LBRD0_DSWMTRDY BIT(27)
-/* PCI Target Retry Delay Clocks / 8 (LBRD0 only) */
-#define PLX_LBRD0_TRDELAY(x) (BIT(28) * ((x) & 0xF))
-#define PLX_LBRD0_TRDELAY_MASK GENMASK(31, 28)
-#define PLX_LBRD0_TO_TRDELAY(r) (((r) & PLX_LBRD0_TRDELAY_MASK) >> 28)
-
-/* Local Range Register for Direct Master to PCI */
-#define PLX_REG_DMRR 0x001c
-
-/* Local Bus Base Address Register for Direct Master to PCI Memory */
-#define PLX_REG_DMLBAM 0x0020
-
-/* Local Base Address Register for Direct Master to PCI IO/CFG */
-#define PLX_REG_DMLBAI 0x0024
-
-/* PCI Base Address (Remap) Register for Direct Master to PCI Memory */
-#define PLX_REG_DMPBAM 0x0028
-
-/* Direct Master Memory Access Enable */
-#define PLX_DMPBAM_MEMACCEN BIT(0)
-/* Direct Master I/O Access Enable */
-#define PLX_DMPBAM_IOACCEN BIT(1)
-/* LLOCK# Input Enable */
-#define PLX_DMPBAM_LLOCKIEN BIT(2)
-/* Direct Master Read Prefetch Size Control (bits 12, 3) */
-#define PLX_DMPBAM_RPSIZE_CONT ((BIT(12) * 0) | (BIT(3) * 0))
-#define PLX_DMPBAM_RPSIZE_4 ((BIT(12) * 0) | (BIT(3) * 1))
-#define PLX_DMPBAM_RPSIZE_8 ((BIT(12) * 1) | (BIT(3) * 0))
-#define PLX_DMPBAM_RPSIZE_16 ((BIT(12) * 1) | (BIT(3) * 1))
-#define PLX_DMPBAM_RPSIZE_MASK (BIT(12) | BIT(3))
-/* Direct Master PCI Read Mode - deassert IRDY when FIFO full */
-#define PLX_DMPBAM_RMIRDY BIT(4)
-/* Programmable Almost Full Level (bits 10, 8:5) */
-#define PLX_DMPBAM_PAFL(x) ((BIT(10) * !!((x) & 0x10)) | \
- (BIT(5) * ((x) & 0xf)))
-#define PLX_DMPBAM_TO_PAFL(v) ((((BIT(10) & (v)) >> 1) | \
- (GENMASK(8, 5) & (v))) >> 5)
-#define PLX_DMPBAM_PAFL_MASK (BIT(10) | GENMASK(8, 5))
-/* Write And Invalidate Mode */
-#define PLX_DMPBAM_WIM BIT(9)
-/* Direct Master Prefetch Limit */
-#define PLX_DBPBAM_PFLIMIT BIT(11)
-/* I/O Remap Select */
-#define PLX_DMPBAM_IOREMAPSEL BIT(13)
-/* Direct Master Write Delay */
-#define PLX_DMPBAM_WDELAY_NONE (BIT(14) * 0)
-#define PLX_DMPBAM_WDELAY_4 (BIT(14) * 1)
-#define PLX_DMPBAM_WDELAY_8 (BIT(14) * 2)
-#define PLX_DMPBAM_WDELAY_16 (BIT(14) * 3)
-#define PLX_DMPBAM_WDELAY_MASK GENMASK(15, 14)
-/* Remap of Local-to-PCI Space Into PCI Address Space */
-#define PLX_DMPBAM_REMAP_MASK GENMASK(31, 16)
-
-/* PCI Configuration Address Register for Direct Master to PCI IO/CFG */
-#define PLX_REG_DMCFGA 0x002c
-
-/* Congiguration Type */
-#define PLX_DMCFGA_TYPE0 (BIT(0) * 0)
-#define PLX_DMCFGA_TYPE1 (BIT(0) * 1)
-#define PLX_DMCFGA_TYPE_MASK GENMASK(1, 0)
-/* Register Number */
-#define PLX_DMCFGA_REGNUM(x) (BIT(2) * ((x) & 0x3f))
-#define PLX_DMCFGA_REGNUM_MASK GENMASK(7, 2)
-#define PLX_DMCFGA_TO_REGNUM(r) (((r) & PLX_DMCFGA_REGNUM_MASK) >> 2)
-/* Function Number */
-#define PLX_DMCFGA_FUNCNUM(x) (BIT(8) * ((x) & 0x7))
-#define PLX_DMCFGA_FUNCNUM_MASK GENMASK(10, 8)
-#define PLX_DMCFGA_TO_FUNCNUM(r) (((r) & PLX_DMCFGA_FUNCNUM_MASK) >> 8)
-/* Device Number */
-#define PLX_DMCFGA_DEVNUM(x) (BIT(11) * ((x) & 0x1f))
-#define PLX_DMCFGA_DEVNUM_MASK GENMASK(15, 11)
-#define PLX_DMCFGA_TO_DEVNUM(r) (((r) & PLX_DMCFGA_DEVNUM_MASK) >> 11)
-/* Bus Number */
-#define PLX_DMCFGA_BUSNUM(x) (BIT(16) * ((x) & 0xff))
-#define PLX_DMCFGA_BUSNUM_MASK GENMASK(23, 16)
-#define PLX_DMCFGA_TO_BUSNUM(r) (((r) & PLX_DMCFGA_BUSNUM_MASK) >> 16)
-/* Configuration Enable */
-#define PLX_DMCFGA_CONFIGEN BIT(31)
-
-/*
- * Mailbox Register N (N <= 7)
- *
- * Note that if the I2O feature is enabled (QSR[0] is set), Mailbox Register 0
- * is replaced by the Inbound Queue Port, and Mailbox Register 1 is replaced
- * by the Outbound Queue Port. However, Mailbox Register 0 and 1 are always
- * accessible at alternative offsets if the I2O feature is enabled.
- */
-#define PLX_REG_MBOX(n) (0x0040 + (n) * 4)
-#define PLX_REG_MBOX0 PLX_REG_MBOX(0)
-#define PLX_REG_MBOX1 PLX_REG_MBOX(1)
-#define PLX_REG_MBOX2 PLX_REG_MBOX(2)
-#define PLX_REG_MBOX3 PLX_REG_MBOX(3)
-#define PLX_REG_MBOX4 PLX_REG_MBOX(4)
-#define PLX_REG_MBOX5 PLX_REG_MBOX(5)
-#define PLX_REG_MBOX6 PLX_REG_MBOX(6)
-#define PLX_REG_MBOX7 PLX_REG_MBOX(7)
-
-/* Alternative offsets for Mailbox Registers 0 and 1 (in case I2O is enabled) */
-#define PLX_REG_ALT_MBOX(n) ((n) < 2 ? 0x0078 + (n) * 4 : PLX_REG_MBOX(n))
-#define PLX_REG_ALT_MBOX0 PLX_REG_ALT_MBOX(0)
-#define PLX_REG_ALT_MBOX1 PLX_REG_ALT_MBOX(1)
-
-/* PCI-to-Local Doorbell Register */
-#define PLX_REG_P2LDBELL 0x0060
-
-/* Local-to-PCI Doorbell Register */
-#define PLX_REG_L2PDBELL 0x0064
-
-/* Interrupt Control/Status Register */
-#define PLX_REG_INTCSR 0x0068
-
-/* Enable Local Bus LSERR# when PCI Bus Target Abort or Master Abort occurs */
-#define PLX_INTCSR_LSEABORTEN BIT(0)
-/* Enable Local Bus LSERR# when PCI parity error occurs */
-#define PLX_INTCSR_LSEPARITYEN BIT(1)
-/* Generate PCI Bus SERR# when set to 1 */
-#define PLX_INTCSR_GENSERR BIT(2)
-/* Mailbox Interrupt Enable (local bus interrupts on PCI write to MBOX0-3) */
-#define PLX_INTCSR_MBIEN BIT(3)
-/* PCI Interrupt Enable */
-#define PLX_INTCSR_PIEN BIT(8)
-/* PCI Doorbell Interrupt Enable */
-#define PLX_INTCSR_PDBIEN BIT(9)
-/* PCI Abort Interrupt Enable */
-#define PLX_INTCSR_PABORTIEN BIT(10)
-/* PCI Local Interrupt Enable */
-#define PLX_INTCSR_PLIEN BIT(11)
-/* Retry Abort Enable (for diagnostic purposes only) */
-#define PLX_INTCSR_RAEN BIT(12)
-/* PCI Doorbell Interrupt Active (read-only) */
-#define PLX_INTCSR_PDBIA BIT(13)
-/* PCI Abort Interrupt Active (read-only) */
-#define PLX_INTCSR_PABORTIA BIT(14)
-/* Local Interrupt (LINTi#) Active (read-only) */
-#define PLX_INTCSR_PLIA BIT(15)
-/* Local Interrupt Output (LINTo#) Enable */
-#define PLX_INTCSR_LIOEN BIT(16)
-/* Local Doorbell Interrupt Enable */
-#define PLX_INTCSR_LDBIEN BIT(17)
-/* DMA Channel 0 Interrupt Enable */
-#define PLX_INTCSR_DMA0IEN BIT(18)
-/* DMA Channel 1 Interrupt Enable */
-#define PLX_INTCSR_DMA1IEN BIT(19)
-/* DMA Channel N Interrupt Enable (N <= 1) */
-#define PLX_INTCSR_DMAIEN(n) ((n) ? PLX_INTCSR_DMA1IEN : PLX_INTCSR_DMA0IEN)
-/* Local Doorbell Interrupt Active (read-only) */
-#define PLX_INTCSR_LDBIA BIT(20)
-/* DMA Channel 0 Interrupt Active (read-only) */
-#define PLX_INTCSR_DMA0IA BIT(21)
-/* DMA Channel 1 Interrupt Active (read-only) */
-#define PLX_INTCSR_DMA1IA BIT(22)
-/* DMA Channel N Interrupt Active (N <= 1) (read-only) */
-#define PLX_INTCSR_DMAIA(n) ((n) ? PLX_INTCSR_DMA1IA : PLX_INTCSR_DMA0IA)
-/* BIST Interrupt Active (read-only) */
-#define PLX_INTCSR_BISTIA BIT(23)
-/* Direct Master Not Bus Master During Master Or Target Abort (read-only) */
-#define PLX_INTCSR_ABNOTDM BIT(24)
-/* DMA Channel 0 Not Bus Master During Master Or Target Abort (read-only) */
-#define PLX_INTCSR_ABNOTDMA0 BIT(25)
-/* DMA Channel 1 Not Bus Master During Master Or Target Abort (read-only) */
-#define PLX_INTCSR_ABNOTDMA1 BIT(26)
-/* DMA Channel N Not Bus Master During Master Or Target Abort (read-only) */
-#define PLX_INTCSR_ABNOTDMA(n) ((n) ? PLX_INTCSR_ABNOTDMA1 \
- : PLX_INTCSR_ABNOTDMA0)
-/* Target Abort Not Generated After 256 Master Retries (read-only) */
-#define PLX_INTCSR_ABNOTRETRY BIT(27)
-/* PCI Wrote Mailbox 0 (enabled if bit 3 set) (read-only) */
-#define PLX_INTCSR_MB0IA BIT(28)
-/* PCI Wrote Mailbox 1 (enabled if bit 3 set) (read-only) */
-#define PLX_INTCSR_MB1IA BIT(29)
-/* PCI Wrote Mailbox 2 (enabled if bit 3 set) (read-only) */
-#define PLX_INTCSR_MB2IA BIT(30)
-/* PCI Wrote Mailbox 3 (enabled if bit 3 set) (read-only) */
-#define PLX_INTCSR_MB3IA BIT(31)
-/* PCI Wrote Mailbox N (N <= 3) (enabled if bit 3 set) (read-only) */
-#define PLX_INTCSR_MBIA(n) BIT(28 + (n))
-
-/*
- * Serial EEPROM Control, PCI Command Codes, User I/O Control,
- * Init Control Register
- */
-#define PLX_REG_CNTRL 0x006c
-
-/* PCI Read Command Code For DMA */
-#define PLX_CNTRL_CCRDMA(x) (BIT(0) * ((x) & 0xf))
-#define PLX_CNTRL_CCRDMA_MASK GENMASK(3, 0)
-#define PLX_CNTRL_TO_CCRDMA(r) ((r) & PLX_CNTRL_CCRDMA_MASK)
-#define PLX_CNTRL_CCRDMA_NORMAL PLX_CNTRL_CCRDMA(14) /* value after reset */
-/* PCI Write Command Code For DMA 0 */
-#define PLX_CNTRL_CCWDMA(x) (BIT(4) * ((x) & 0xf))
-#define PLX_CNTRL_CCWDMA_MASK GENMASK(7, 4)
-#define PLX_CNTRL_TO_CCWDMA(r) (((r) & PLX_CNTRL_CCWDMA_MASK) >> 4)
-#define PLX_CNTRL_CCWDMA_NORMAL PLX_CNTRL_CCWDMA(7) /* value after reset */
-/* PCI Memory Read Command Code For Direct Master */
-#define PLX_CNTRL_CCRDM(x) (BIT(8) * ((x) & 0xf))
-#define PLX_CNTRL_CCRDM_MASK GENMASK(11, 8)
-#define PLX_CNTRL_TO_CCRDM(r) (((r) & PLX_CNTRL_CCRDM_MASK) >> 8)
-#define PLX_CNTRL_CCRDM_NORMAL PLX_CNTRL_CCRDM(6) /* value after reset */
-/* PCI Memory Write Command Code For Direct Master */
-#define PLX_CNTRL_CCWDM(x) (BIT(12) * ((x) & 0xf))
-#define PLX_CNTRL_CCWDM_MASK GENMASK(15, 12)
-#define PLX_CNTRL_TO_CCWDM(r) (((r) & PLX_CNTRL_CCWDM_MASK) >> 12)
-#define PLX_CNTRL_CCWDM_NORMAL PLX_CNTRL_CCWDM(7) /* value after reset */
-/* General Purpose Output (USERO) */
-#define PLX_CNTRL_USERO BIT(16)
-/* General Purpose Input (USERI) (read-only) */
-#define PLX_CNTRL_USERI BIT(17)
-/* Serial EEPROM Clock Output (EESK) */
-#define PLX_CNTRL_EESK BIT(24)
-/* Serial EEPROM Chip Select Output (EECS) */
-#define PLX_CNTRL_EECS BIT(25)
-/* Serial EEPROM Data Write Bit (EEDI (sic)) */
-#define PLX_CNTRL_EEWB BIT(26)
-/* Serial EEPROM Data Read Bit (EEDO (sic)) (read-only) */
-#define PLX_CNTRL_EERB BIT(27)
-/* Serial EEPROM Present (read-only) */
-#define PLX_CNTRL_EEPRESENT BIT(28)
-/* Reload Configuration Registers from EEPROM */
-#define PLX_CNTRL_EERELOAD BIT(29)
-/* PCI Adapter Software Reset (asserts LRESETo#) */
-#define PLX_CNTRL_RESET BIT(30)
-/* Local Init Status (read-only) */
-#define PLX_CNTRL_INITDONE BIT(31)
-/*
- * Combined command code stuff for convenience.
- */
-#define PLX_CNTRL_CC_MASK \
- (PLX_CNTRL_CCRDMA_MASK | PLX_CNTRL_CCWDMA_MASK | \
- PLX_CNTRL_CCRDM_MASK | PLX_CNTRL_CCWDM_MASK)
-#define PLX_CNTRL_CC_NORMAL \
- (PLX_CNTRL_CCRDMA_NORMAL | PLX_CNTRL_CCWDMA_NORMAL | \
- PLX_CNTRL_CCRDM_NORMAL | PLX_CNTRL_CCWDM_NORMAL) /* val after reset */
-
-/* PCI Permanent Configuration ID Register (hard-coded PLX vendor and device) */
-#define PLX_REG_PCIHIDR 0x0070
-
-/* Hard-coded ID for PLX PCI 9080 */
-#define PLX_PCIHIDR_9080 0x908010b5
-
-/* PCI Permanent Revision ID Register (hard-coded silicon revision) (8-bit). */
-#define PLX_REG_PCIHREV 0x0074
-
-/* DMA Channel N Mode Register (N <= 1) */
-#define PLX_REG_DMAMODE(n) ((n) ? PLX_REG_DMAMODE1 : PLX_REG_DMAMODE0)
-#define PLX_REG_DMAMODE0 0x0080
-#define PLX_REG_DMAMODE1 0x0094
-
-/* Local Bus Width */
-#define PLX_DMAMODE_WIDTH_8 (BIT(0) * 0) /* 8 bits wide */
-#define PLX_DMAMODE_WIDTH_16 (BIT(0) * 1) /* 16 bits wide */
-#define PLX_DMAMODE_WIDTH_32 (BIT(0) * 2) /* 32 bits wide */
-#define PLX_DMAMODE_WIDTH_32A (BIT(0) * 3) /* 32 bits wide */
-#define PLX_DMAMODE_WIDTH_MASK GENMASK(1, 0)
-/* Internal Wait States */
-#define PLX_DMAMODE_IWS(x) (BIT(2) * ((x) & 0xf))
-#define PLX_DMAMODE_IWS_MASK GENMASK(5, 2)
-#define PLX_DMAMODE_TO_IWS(r) (((r) & PLX_DMAMODE_IWS_MASK) >> 2)
-/* Ready Input Enable */
-#define PLX_DMAMODE_READYIEN BIT(6)
-/* BTERM# Input Enable */
-#define PLX_DMAMODE_BTERMIEN BIT(7)
-/* Local Burst Enable */
-#define PLX_DMAMODE_BURSTEN BIT(8)
-/* Chaining Enable */
-#define PLX_DMAMODE_CHAINEN BIT(9)
-/* Done Interrupt Enable */
-#define PLX_DMAMODE_DONEIEN BIT(10)
-/* Hold Local Address Constant */
-#define PLX_DMAMODE_LACONST BIT(11)
-/* Demand Mode */
-#define PLX_DMAMODE_DEMAND BIT(12)
-/* Write And Invalidate Mode */
-#define PLX_DMAMODE_WINVALIDATE BIT(13)
-/* DMA EOT Enable - enables EOT0# or EOT1# input pin */
-#define PLX_DMAMODE_EOTEN BIT(14)
-/* DMA Stop Data Transfer Mode - 0:BLAST; 1:EOT asserted or DREQ deasserted */
-#define PLX_DMAMODE_STOP BIT(15)
-/* DMA Clear Count Mode - count in descriptor cleared on completion */
-#define PLX_DMAMODE_CLRCOUNT BIT(16)
-/* DMA Channel Interrupt Select - 0:local bus interrupt; 1:PCI interrupt */
-#define PLX_DMAMODE_INTRPCI BIT(17)
-
-/* DMA Channel N PCI Address Register (N <= 1) */
-#define PLX_REG_DMAPADR(n) ((n) ? PLX_REG_DMAPADR1 : PLX_REG_DMAPADR0)
-#define PLX_REG_DMAPADR0 0x0084
-#define PLX_REG_DMAPADR1 0x0098
-
-/* DMA Channel N Local Address Register (N <= 1) */
-#define PLX_REG_DMALADR(n) ((n) ? PLX_REG_DMALADR1 : PLX_REG_DMALADR0)
-#define PLX_REG_DMALADR0 0x0088
-#define PLX_REG_DMALADR1 0x009c
-
-/* DMA Channel N Transfer Size (Bytes) Register (N <= 1) (first 23 bits) */
-#define PLX_REG_DMASIZ(n) ((n) ? PLX_REG_DMASIZ1 : PLX_REG_DMASIZ0)
-#define PLX_REG_DMASIZ0 0x008c
-#define PLX_REG_DMASIZ1 0x00a0
-
-/* DMA Channel N Descriptor Pointer Register (N <= 1) */
-#define PLX_REG_DMADPR(n) ((n) ? PLX_REG_DMADPR1 : PLX_REG_DMADPR0)
-#define PLX_REG_DMADPR0 0x0090
-#define PLX_REG_DMADPR1 0x00a4
-
-/* Descriptor Located In PCI Address Space (not local address space) */
-#define PLX_DMADPR_DESCPCI BIT(0)
-/* End Of Chain */
-#define PLX_DMADPR_CHAINEND BIT(1)
-/* Interrupt After Terminal Count */
-#define PLX_DMADPR_TCINTR BIT(2)
-/* Direction Of Transfer Local Bus To PCI (not PCI to local) */
-#define PLX_DMADPR_XFERL2P BIT(3)
-/* Next Descriptor Address Bits 31:4 (16 byte boundary) */
-#define PLX_DMADPR_NEXT_MASK GENMASK(31, 4)
-
-/* DMA Channel N Command/Status Register (N <= 1) (8-bit) */
-#define PLX_REG_DMACSR(n) ((n) ? PLX_REG_DMACSR1 : PLX_REG_DMACSR0)
-#define PLX_REG_DMACSR0 0x00a8
-#define PLX_REG_DMACSR1 0x00a9
-
-/* Channel Enable */
-#define PLX_DMACSR_ENABLE BIT(0)
-/* Channel Start - write 1 to start transfer (write-only) */
-#define PLX_DMACSR_START BIT(1)
-/* Channel Abort - write 1 to abort transfer (write-only) */
-#define PLX_DMACSR_ABORT BIT(2)
-/* Clear Interrupt - write 1 to clear DMA Channel Interrupt (write-only) */
-#define PLX_DMACSR_CLEARINTR BIT(3)
-/* Channel Done - transfer complete/inactive (read-only) */
-#define PLX_DMACSR_DONE BIT(4)
-
-/* DMA Threshold Register */
-#define PLX_REG_DMATHR 0x00b0
-
-/*
- * DMA Threshold constraints:
- * (C0PLAF + 1) + (C0PLAE + 1) <= 32
- * (C0LPAF + 1) + (C0LPAE + 1) <= 32
- * (C1PLAF + 1) + (C1PLAE + 1) <= 16
- * (C1LPAF + 1) + (C1LPAE + 1) <= 16
- */
-
-/* DMA Channel 0 PCI-to-Local Almost Full (divided by 2, minus 1) */
-#define PLX_DMATHR_C0PLAF(x) (BIT(0) * ((x) & 0xf))
-#define PLX_DMATHR_C0PLAF_MASK GENMASK(3, 0)
-#define PLX_DMATHR_TO_C0PLAF(r) ((r) & PLX_DMATHR_C0PLAF_MASK)
-/* DMA Channel 0 Local-to-PCI Almost Empty (divided by 2, minus 1) */
-#define PLX_DMATHR_C0LPAE(x) (BIT(4) * ((x) & 0xf))
-#define PLX_DMATHR_C0LPAE_MASK GENMASK(7, 4)
-#define PLX_DMATHR_TO_C0LPAE(r) (((r) & PLX_DMATHR_C0LPAE_MASK) >> 4)
-/* DMA Channel 0 Local-to-PCI Almost Full (divided by 2, minus 1) */
-#define PLX_DMATHR_C0LPAF(x) (BIT(8) * ((x) & 0xf))
-#define PLX_DMATHR_C0LPAF_MASK GENMASK(11, 8)
-#define PLX_DMATHR_TO_C0LPAF(r) (((r) & PLX_DMATHR_C0LPAF_MASK) >> 8)
-/* DMA Channel 0 PCI-to-Local Almost Empty (divided by 2, minus 1) */
-#define PLX_DMATHR_C0PLAE(x) (BIT(12) * ((x) & 0xf))
-#define PLX_DMATHR_C0PLAE_MASK GENMASK(15, 12)
-#define PLX_DMATHR_TO_C0PLAE(r) (((r) & PLX_DMATHR_C0PLAE_MASK) >> 12)
-/* DMA Channel 1 PCI-to-Local Almost Full (divided by 2, minus 1) */
-#define PLX_DMATHR_C1PLAF(x) (BIT(16) * ((x) & 0xf))
-#define PLX_DMATHR_C1PLAF_MASK GENMASK(19, 16)
-#define PLX_DMATHR_TO_C1PLAF(r) (((r) & PLX_DMATHR_C1PLAF_MASK) >> 16)
-/* DMA Channel 1 Local-to-PCI Almost Empty (divided by 2, minus 1) */
-#define PLX_DMATHR_C1LPAE(x) (BIT(20) * ((x) & 0xf))
-#define PLX_DMATHR_C1LPAE_MASK GENMASK(23, 20)
-#define PLX_DMATHR_TO_C1LPAE(r) (((r) & PLX_DMATHR_C1LPAE_MASK) >> 20)
-/* DMA Channel 1 Local-to-PCI Almost Full (divided by 2, minus 1) */
-#define PLX_DMATHR_C1LPAF(x) (BIT(24) * ((x) & 0xf))
-#define PLX_DMATHR_C1LPAF_MASK GENMASK(27, 24)
-#define PLX_DMATHR_TO_C1LPAF(r) (((r) & PLX_DMATHR_C1LPAF_MASK) >> 24)
-/* DMA Channel 1 PCI-to-Local Almost Empty (divided by 2, minus 1) */
-#define PLX_DMATHR_C1PLAE(x) (BIT(28) * ((x) & 0xf))
-#define PLX_DMATHR_C1PLAE_MASK GENMASK(31, 28)
-#define PLX_DMATHR_TO_C1PLAE(r) (((r) & PLX_DMATHR_C1PLAE_MASK) >> 28)
-
-/*
- * Messaging Queue Registers OPLFIS, OPLFIM, IQP, OQP, MQCR, QBAR, IFHPR,
- * IFTPR, IPHPR, IPTPR, OFHPR, OFTPR, OPHPR, OPTPR, and QSR have been omitted.
- * They are used by the I2O feature. (IQP and OQP occupy the usual offsets of
- * the MBOX0 and MBOX1 registers if the I2O feature is enabled, but MBOX0 and
- * MBOX1 are accessible via alternative offsets.
- */
-
-/* Queue Status/Control Register */
-#define PLX_REG_QSR 0x00e8
-
-/* Value of QSR after reset - disables I2O feature completely. */
-#define PLX_QSR_VALUE_AFTER_RESET 0x00000050
-
-/*
- * Accesses near the end of memory can cause the PLX chip
- * to pre-fetch data off of end-of-ram. Limit the size of
- * memory so host-side accesses cannot occur.
- */
-
-#define PLX_PREFETCH 32
-
-/**
- * plx9080_abort_dma - Abort a PLX PCI 9080 DMA transfer
- * @iobase: Remapped base address of configuration registers.
- * @channel: DMA channel number (0 or 1).
- *
- * Aborts the DMA transfer on the channel, which must have been enabled
- * and started beforehand.
- *
- * Return:
- * %0 on success.
- * -%ETIMEDOUT if timed out waiting for abort to complete.
- */
-static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel)
-{
- void __iomem *dma_cs_addr;
- u8 dma_status;
- const int timeout = 10000;
- unsigned int i;
-
- dma_cs_addr = iobase + PLX_REG_DMACSR(channel);
-
- /* abort dma transfer if necessary */
- dma_status = readb(dma_cs_addr);
- if ((dma_status & PLX_DMACSR_ENABLE) == 0)
- return 0;
-
- /* wait to make sure done bit is zero */
- for (i = 0; (dma_status & PLX_DMACSR_DONE) && i < timeout; i++) {
- udelay(1);
- dma_status = readb(dma_cs_addr);
- }
- if (i == timeout)
- return -ETIMEDOUT;
-
- /* disable and abort channel */
- writeb(PLX_DMACSR_ABORT, dma_cs_addr);
- /* wait for dma done bit */
- dma_status = readb(dma_cs_addr);
- for (i = 0; (dma_status & PLX_DMACSR_DONE) == 0 && i < timeout; i++) {
- udelay(1);
- dma_status = readb(dma_cs_addr);
- }
- if (i == timeout)
- return -ETIMEDOUT;
-
- return 0;
-}
-
-#endif /* __COMEDI_PLX9080_H */
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
deleted file mode 100644
index fe4408ebf6b3..000000000000
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ /dev/null
@@ -1,842 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * quatech_daqp_cs.c
- * Quatech DAQP PCMCIA data capture cards COMEDI client driver
- * Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
- * The DAQP interface code in this file is released into the public domain.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- * https://www.comedi.org/
- *
- * Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
- * ftp://ftp.quatech.com/Manuals/daqp-208.pdf
- *
- * This manual is for both the DAQP-208 and the DAQP-308.
- *
- * What works:
- * - A/D conversion
- * - 8 channels
- * - 4 gain ranges
- * - ground ref or differential
- * - single-shot and timed both supported
- * - D/A conversion, single-shot
- * - digital I/O
- *
- * What doesn't:
- * - any kind of triggering - external or D/A channel 1
- * - the card's optional expansion board
- * - the card's timer (for anything other than A/D conversion)
- * - D/A update modes other than immediate (i.e, timed)
- * - fancier timing modes
- * - setting card's FIFO buffer thresholds to anything but default
- */
-
-/*
- * Driver: quatech_daqp_cs
- * Description: Quatech DAQP PCMCIA data capture cards
- * Devices: [Quatech] DAQP-208 (daqp), DAQP-308
- * Author: Brent Baccala <baccala@freesoft.org>
- * Status: works
- */
-
-#include <linux/module.h>
-
-#include "../comedi_pcmcia.h"
-
-/*
- * Register I/O map
- *
- * The D/A and timer registers can be accessed with 16-bit or 8-bit I/O
- * instructions. All other registers can only use 8-bit instructions.
- *
- * The FIFO and scanlist registers require two 8-bit instructions to
- * access the 16-bit data. Data is transferred LSB then MSB.
- */
-#define DAQP_AI_FIFO_REG 0x00
-
-#define DAQP_SCANLIST_REG 0x01
-#define DAQP_SCANLIST_DIFFERENTIAL BIT(14)
-#define DAQP_SCANLIST_GAIN(x) (((x) & 0x3) << 12)
-#define DAQP_SCANLIST_CHANNEL(x) (((x) & 0xf) << 8)
-#define DAQP_SCANLIST_START BIT(7)
-#define DAQP_SCANLIST_EXT_GAIN(x) (((x) & 0x3) << 4)
-#define DAQP_SCANLIST_EXT_CHANNEL(x) (((x) & 0xf) << 0)
-
-#define DAQP_CTRL_REG 0x02
-#define DAQP_CTRL_PACER_CLK(x) (((x) & 0x3) << 6)
-#define DAQP_CTRL_PACER_CLK_EXT DAQP_CTRL_PACER_CLK(0)
-#define DAQP_CTRL_PACER_CLK_5MHZ DAQP_CTRL_PACER_CLK(1)
-#define DAQP_CTRL_PACER_CLK_1MHZ DAQP_CTRL_PACER_CLK(2)
-#define DAQP_CTRL_PACER_CLK_100KHZ DAQP_CTRL_PACER_CLK(3)
-#define DAQP_CTRL_EXPANSION BIT(5)
-#define DAQP_CTRL_EOS_INT_ENA BIT(4)
-#define DAQP_CTRL_FIFO_INT_ENA BIT(3)
-#define DAQP_CTRL_TRIG_MODE BIT(2) /* 0=one-shot; 1=continuous */
-#define DAQP_CTRL_TRIG_SRC BIT(1) /* 0=internal; 1=external */
-#define DAQP_CTRL_TRIG_EDGE BIT(0) /* 0=rising; 1=falling */
-
-#define DAQP_STATUS_REG 0x02
-#define DAQP_STATUS_IDLE BIT(7)
-#define DAQP_STATUS_RUNNING BIT(6)
-#define DAQP_STATUS_DATA_LOST BIT(5)
-#define DAQP_STATUS_END_OF_SCAN BIT(4)
-#define DAQP_STATUS_FIFO_THRESHOLD BIT(3)
-#define DAQP_STATUS_FIFO_FULL BIT(2)
-#define DAQP_STATUS_FIFO_NEARFULL BIT(1)
-#define DAQP_STATUS_FIFO_EMPTY BIT(0)
-/* these bits clear when the status register is read */
-#define DAQP_STATUS_EVENTS (DAQP_STATUS_DATA_LOST | \
- DAQP_STATUS_END_OF_SCAN | \
- DAQP_STATUS_FIFO_THRESHOLD)
-
-#define DAQP_DI_REG 0x03
-#define DAQP_DO_REG 0x03
-
-#define DAQP_PACER_LOW_REG 0x04
-#define DAQP_PACER_MID_REG 0x05
-#define DAQP_PACER_HIGH_REG 0x06
-
-#define DAQP_CMD_REG 0x07
-/* the monostable bits are self-clearing after the function is complete */
-#define DAQP_CMD_ARM BIT(7) /* monostable */
-#define DAQP_CMD_RSTF BIT(6) /* monostable */
-#define DAQP_CMD_RSTQ BIT(5) /* monostable */
-#define DAQP_CMD_STOP BIT(4) /* monostable */
-#define DAQP_CMD_LATCH BIT(3) /* monostable */
-#define DAQP_CMD_SCANRATE(x) (((x) & 0x3) << 1)
-#define DAQP_CMD_SCANRATE_100KHZ DAQP_CMD_SCANRATE(0)
-#define DAQP_CMD_SCANRATE_50KHZ DAQP_CMD_SCANRATE(1)
-#define DAQP_CMD_SCANRATE_25KHZ DAQP_CMD_SCANRATE(2)
-#define DAQP_CMD_FIFO_DATA BIT(0)
-
-#define DAQP_AO_REG 0x08 /* and 0x09 (16-bit) */
-
-#define DAQP_TIMER_REG 0x0a /* and 0x0b (16-bit) */
-
-#define DAQP_AUX_REG 0x0f
-/* Auxiliary Control register bits (write) */
-#define DAQP_AUX_EXT_ANALOG_TRIG BIT(7)
-#define DAQP_AUX_PRETRIG BIT(6)
-#define DAQP_AUX_TIMER_INT_ENA BIT(5)
-#define DAQP_AUX_TIMER_MODE(x) (((x) & 0x3) << 3)
-#define DAQP_AUX_TIMER_MODE_RELOAD DAQP_AUX_TIMER_MODE(0)
-#define DAQP_AUX_TIMER_MODE_PAUSE DAQP_AUX_TIMER_MODE(1)
-#define DAQP_AUX_TIMER_MODE_GO DAQP_AUX_TIMER_MODE(2)
-#define DAQP_AUX_TIMER_MODE_EXT DAQP_AUX_TIMER_MODE(3)
-#define DAQP_AUX_TIMER_CLK_SRC_EXT BIT(2)
-#define DAQP_AUX_DA_UPDATE(x) (((x) & 0x3) << 0)
-#define DAQP_AUX_DA_UPDATE_DIRECT DAQP_AUX_DA_UPDATE(0)
-#define DAQP_AUX_DA_UPDATE_OVERFLOW DAQP_AUX_DA_UPDATE(1)
-#define DAQP_AUX_DA_UPDATE_EXTERNAL DAQP_AUX_DA_UPDATE(2)
-#define DAQP_AUX_DA_UPDATE_PACER DAQP_AUX_DA_UPDATE(3)
-/* Auxiliary Status register bits (read) */
-#define DAQP_AUX_RUNNING BIT(7)
-#define DAQP_AUX_TRIGGERED BIT(6)
-#define DAQP_AUX_DA_BUFFER BIT(5)
-#define DAQP_AUX_TIMER_OVERFLOW BIT(4)
-#define DAQP_AUX_CONVERSION BIT(3)
-#define DAQP_AUX_DATA_LOST BIT(2)
-#define DAQP_AUX_FIFO_NEARFULL BIT(1)
-#define DAQP_AUX_FIFO_EMPTY BIT(0)
-
-#define DAQP_FIFO_SIZE 4096
-
-#define DAQP_MAX_TIMER_SPEED 10000 /* 100 kHz in nanoseconds */
-
-struct daqp_private {
- unsigned int pacer_div;
- int stop;
-};
-
-static const struct comedi_lrange range_daqp_ai = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(2.5),
- BIP_RANGE(1.25)
- }
-};
-
-static int daqp_clear_events(struct comedi_device *dev, int loops)
-{
- unsigned int status;
-
- /*
- * Reset any pending interrupts (my card has a tendency to require
- * multiple reads on the status register to achieve this).
- */
- while (--loops) {
- status = inb(dev->iobase + DAQP_STATUS_REG);
- if ((status & DAQP_STATUS_EVENTS) == 0)
- return 0;
- }
- dev_err(dev->class_dev, "couldn't clear events in status register\n");
- return -EBUSY;
-}
-
-static int daqp_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct daqp_private *devpriv = dev->private;
-
- if (devpriv->stop)
- return -EIO;
-
- /*
- * Stop any conversions, disable interrupts, and clear
- * the status event flags.
- */
- outb(DAQP_CMD_STOP, dev->iobase + DAQP_CMD_REG);
- outb(0, dev->iobase + DAQP_CTRL_REG);
- inb(dev->iobase + DAQP_STATUS_REG);
-
- return 0;
-}
-
-static unsigned int daqp_ai_get_sample(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int val;
-
- /*
- * Get a two's complement sample from the FIFO and
- * return the munged offset binary value.
- */
- val = inb(dev->iobase + DAQP_AI_FIFO_REG);
- val |= inb(dev->iobase + DAQP_AI_FIFO_REG) << 8;
- return comedi_offset_munge(s, val);
-}
-
-static irqreturn_t daqp_interrupt(int irq, void *dev_id)
-{
- struct comedi_device *dev = dev_id;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
- int loop_limit = 10000;
- int status;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- status = inb(dev->iobase + DAQP_STATUS_REG);
- if (!(status & DAQP_STATUS_EVENTS))
- return IRQ_NONE;
-
- while (!(status & DAQP_STATUS_FIFO_EMPTY)) {
- unsigned short data;
-
- if (status & DAQP_STATUS_DATA_LOST) {
- s->async->events |= COMEDI_CB_OVERFLOW;
- dev_warn(dev->class_dev, "data lost\n");
- break;
- }
-
- data = daqp_ai_get_sample(dev, s);
- comedi_buf_write_samples(s, &data, 1);
-
- if (cmd->stop_src == TRIG_COUNT &&
- s->async->scans_done >= cmd->stop_arg) {
- s->async->events |= COMEDI_CB_EOA;
- break;
- }
-
- if ((loop_limit--) <= 0)
- break;
-
- status = inb(dev->iobase + DAQP_STATUS_REG);
- }
-
- if (loop_limit <= 0) {
- dev_warn(dev->class_dev,
- "loop_limit reached in %s()\n", __func__);
- s->async->events |= COMEDI_CB_ERROR;
- }
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static void daqp_ai_set_one_scanlist_entry(struct comedi_device *dev,
- unsigned int chanspec,
- int start)
-{
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
- unsigned int val;
-
- val = DAQP_SCANLIST_CHANNEL(chan) | DAQP_SCANLIST_GAIN(range);
-
- if (aref == AREF_DIFF)
- val |= DAQP_SCANLIST_DIFFERENTIAL;
-
- if (start)
- val |= DAQP_SCANLIST_START;
-
- outb(val & 0xff, dev->iobase + DAQP_SCANLIST_REG);
- outb((val >> 8) & 0xff, dev->iobase + DAQP_SCANLIST_REG);
-}
-
-static int daqp_ai_eos(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DAQP_AUX_REG);
- if (status & DAQP_AUX_CONVERSION)
- return 0;
- return -EBUSY;
-}
-
-static int daqp_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct daqp_private *devpriv = dev->private;
- int ret = 0;
- int i;
-
- if (devpriv->stop)
- return -EIO;
-
- outb(0, dev->iobase + DAQP_AUX_REG);
-
- /* Reset scan list queue */
- outb(DAQP_CMD_RSTQ, dev->iobase + DAQP_CMD_REG);
-
- /* Program one scan list entry */
- daqp_ai_set_one_scanlist_entry(dev, insn->chanspec, 1);
-
- /* Reset data FIFO (see page 28 of DAQP User's Manual) */
- outb(DAQP_CMD_RSTF, dev->iobase + DAQP_CMD_REG);
-
- /* Set trigger - one-shot, internal, no interrupts */
- outb(DAQP_CTRL_PACER_CLK_100KHZ, dev->iobase + DAQP_CTRL_REG);
-
- ret = daqp_clear_events(dev, 10000);
- if (ret)
- return ret;
-
- for (i = 0; i < insn->n; i++) {
- /* Start conversion */
- outb(DAQP_CMD_ARM | DAQP_CMD_FIFO_DATA,
- dev->iobase + DAQP_CMD_REG);
-
- ret = comedi_timeout(dev, s, insn, daqp_ai_eos, 0);
- if (ret)
- break;
-
- /* clear the status event flags */
- inb(dev->iobase + DAQP_STATUS_REG);
-
- data[i] = daqp_ai_get_sample(dev, s);
- }
-
- /* stop any conversions and clear the status event flags */
- outb(DAQP_CMD_STOP, dev->iobase + DAQP_CMD_REG);
- inb(dev->iobase + DAQP_STATUS_REG);
-
- return ret ? ret : insn->n;
-}
-
-/* This function converts ns nanoseconds to a counter value suitable
- * for programming the device. We always use the DAQP's 5 MHz clock,
- * which with its 24-bit counter, allows values up to 84 seconds.
- * Also, the function adjusts ns so that it cooresponds to the actual
- * time that the device will use.
- */
-
-static int daqp_ns_to_timer(unsigned int *ns, unsigned int flags)
-{
- int timer;
-
- timer = *ns / 200;
- *ns = timer * 200;
-
- return timer;
-}
-
-static void daqp_set_pacer(struct comedi_device *dev, unsigned int val)
-{
- outb(val & 0xff, dev->iobase + DAQP_PACER_LOW_REG);
- outb((val >> 8) & 0xff, dev->iobase + DAQP_PACER_MID_REG);
- outb((val >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH_REG);
-}
-
-static int daqp_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct daqp_private *devpriv = dev->private;
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- /* the async command requires a pacer */
- if (cmd->scan_begin_src != TRIG_TIMER && cmd->convert_src != TRIG_TIMER)
- err |= -EINVAL;
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->scan_begin_src == TRIG_TIMER)
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- DAQP_MAX_TIMER_SPEED);
-
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- DAQP_MAX_TIMER_SPEED);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /*
- * If both scan_begin and convert are both timer
- * values, the only way that can make sense is if
- * the scan time is the number of conversions times
- * the convert time.
- */
- arg = cmd->convert_arg * cmd->scan_end_arg;
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg,
- arg);
- }
- }
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- devpriv->pacer_div = daqp_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- } else if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- devpriv->pacer_div = daqp_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct daqp_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int scanlist_start_on_every_entry;
- int threshold;
- int ret;
- int i;
-
- if (devpriv->stop)
- return -EIO;
-
- outb(0, dev->iobase + DAQP_AUX_REG);
-
- /* Reset scan list queue */
- outb(DAQP_CMD_RSTQ, dev->iobase + DAQP_CMD_REG);
-
- /* Program pacer clock
- *
- * There's two modes we can operate in. If convert_src is
- * TRIG_TIMER, then convert_arg specifies the time between
- * each conversion, so we program the pacer clock to that
- * frequency and set the SCANLIST_START bit on every scanlist
- * entry. Otherwise, convert_src is TRIG_NOW, which means
- * we want the fastest possible conversions, scan_begin_src
- * is TRIG_TIMER, and scan_begin_arg specifies the time between
- * each scan, so we program the pacer clock to this frequency
- * and only set the SCANLIST_START bit on the first entry.
- */
- daqp_set_pacer(dev, devpriv->pacer_div);
-
- if (cmd->convert_src == TRIG_TIMER)
- scanlist_start_on_every_entry = 1;
- else
- scanlist_start_on_every_entry = 0;
-
- /* Program scan list */
- for (i = 0; i < cmd->chanlist_len; i++) {
- int start = (i == 0 || scanlist_start_on_every_entry);
-
- daqp_ai_set_one_scanlist_entry(dev, cmd->chanlist[i], start);
- }
-
- /* Now it's time to program the FIFO threshold, basically the
- * number of samples the card will buffer before it interrupts
- * the CPU.
- *
- * If we don't have a stop count, then use half the size of
- * the FIFO (the manufacturer's recommendation). Consider
- * that the FIFO can hold 2K samples (4K bytes). With the
- * threshold set at half the FIFO size, we have a margin of
- * error of 1024 samples. At the chip's maximum sample rate
- * of 100,000 Hz, the CPU would have to delay interrupt
- * service for a full 10 milliseconds in order to lose data
- * here (as opposed to higher up in the kernel). I've never
- * seen it happen. However, for slow sample rates it may
- * buffer too much data and introduce too much delay for the
- * user application.
- *
- * If we have a stop count, then things get more interesting.
- * If the stop count is less than the FIFO size (actually
- * three-quarters of the FIFO size - see below), we just use
- * the stop count itself as the threshold, the card interrupts
- * us when that many samples have been taken, and we kill the
- * acquisition at that point and are done. If the stop count
- * is larger than that, then we divide it by 2 until it's less
- * than three quarters of the FIFO size (we always leave the
- * top quarter of the FIFO as protection against sluggish CPU
- * interrupt response) and use that as the threshold. So, if
- * the stop count is 4000 samples, we divide by two twice to
- * get 1000 samples, use that as the threshold, take four
- * interrupts to get our 4000 samples and are done.
- *
- * The algorithm could be more clever. For example, if 81000
- * samples are requested, we could set the threshold to 1500
- * samples and take 54 interrupts to get 81000. But 54 isn't
- * a power of two, so this algorithm won't find that option.
- * Instead, it'll set the threshold at 1266 and take 64
- * interrupts to get 81024 samples, of which the last 24 will
- * be discarded... but we won't get the last interrupt until
- * they've been collected. To find the first option, the
- * computer could look at the prime decomposition of the
- * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
- * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
- * = 3^3 * 2). Hmmm... a one-line while loop or prime
- * decomposition of integers... I'll leave it the way it is.
- *
- * I'll also note a mini-race condition before ignoring it in
- * the code. Let's say we're taking 4000 samples, as before.
- * After 1000 samples, we get an interrupt. But before that
- * interrupt is completely serviced, another sample is taken
- * and loaded into the FIFO. Since the interrupt handler
- * empties the FIFO before returning, it will read 1001 samples.
- * If that happens four times, we'll end up taking 4004 samples,
- * not 4000. The interrupt handler will discard the extra four
- * samples (by halting the acquisition with four samples still
- * in the FIFO), but we will have to wait for them.
- *
- * In short, this code works pretty well, but for either of
- * the two reasons noted, might end up waiting for a few more
- * samples than actually requested. Shouldn't make too much
- * of a difference.
- */
-
- /* Save away the number of conversions we should perform, and
- * compute the FIFO threshold (in bytes, not samples - that's
- * why we multiple devpriv->count by 2 = sizeof(sample))
- */
-
- if (cmd->stop_src == TRIG_COUNT) {
- unsigned long long nsamples;
- unsigned long long nbytes;
-
- nsamples = (unsigned long long)cmd->stop_arg *
- cmd->scan_end_arg;
- nbytes = nsamples * comedi_bytes_per_sample(s);
- while (nbytes > DAQP_FIFO_SIZE * 3 / 4)
- nbytes /= 2;
- threshold = nbytes;
- } else {
- threshold = DAQP_FIFO_SIZE / 2;
- }
-
- /* Reset data FIFO (see page 28 of DAQP User's Manual) */
-
- outb(DAQP_CMD_RSTF, dev->iobase + DAQP_CMD_REG);
-
- /* Set FIFO threshold. First two bytes are near-empty
- * threshold, which is unused; next two bytes are near-full
- * threshold. We computed the number of bytes we want in the
- * FIFO when the interrupt is generated, what the card wants
- * is actually the number of available bytes left in the FIFO
- * when the interrupt is to happen.
- */
-
- outb(0x00, dev->iobase + DAQP_AI_FIFO_REG);
- outb(0x00, dev->iobase + DAQP_AI_FIFO_REG);
-
- outb((DAQP_FIFO_SIZE - threshold) & 0xff,
- dev->iobase + DAQP_AI_FIFO_REG);
- outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_AI_FIFO_REG);
-
- /* Set trigger - continuous, internal */
- outb(DAQP_CTRL_TRIG_MODE | DAQP_CTRL_PACER_CLK_5MHZ |
- DAQP_CTRL_FIFO_INT_ENA, dev->iobase + DAQP_CTRL_REG);
-
- ret = daqp_clear_events(dev, 100);
- if (ret)
- return ret;
-
- /* Start conversion */
- outb(DAQP_CMD_ARM | DAQP_CMD_FIFO_DATA, dev->iobase + DAQP_CMD_REG);
-
- return 0;
-}
-
-static int daqp_ao_empty(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inb(dev->iobase + DAQP_AUX_REG);
- if ((status & DAQP_AUX_DA_BUFFER) == 0)
- return 0;
- return -EBUSY;
-}
-
-static int daqp_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct daqp_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- if (devpriv->stop)
- return -EIO;
-
- /* Make sure D/A update mode is direct update */
- outb(0, dev->iobase + DAQP_AUX_REG);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
- int ret;
-
- /* D/A transfer rate is about 8ms */
- ret = comedi_timeout(dev, s, insn, daqp_ao_empty, 0);
- if (ret)
- return ret;
-
- /* write the two's complement value to the channel */
- outw((chan << 12) | comedi_offset_munge(s, val),
- dev->iobase + DAQP_AO_REG);
-
- s->readback[chan] = val;
- }
-
- return insn->n;
-}
-
-static int daqp_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct daqp_private *devpriv = dev->private;
-
- if (devpriv->stop)
- return -EIO;
-
- data[0] = inb(dev->iobase + DAQP_DI_REG);
-
- return insn->n;
-}
-
-static int daqp_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct daqp_private *devpriv = dev->private;
-
- if (devpriv->stop)
- return -EIO;
-
- if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DAQP_DO_REG);
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int daqp_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
- struct daqp_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
- ret = comedi_pcmcia_enable(dev, NULL);
- if (ret)
- return ret;
- dev->iobase = link->resource[0]->start;
-
- link->priv = dev;
- ret = pcmcia_request_irq(link, daqp_interrupt);
- if (ret == 0)
- dev->irq = link->irq;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 8;
- s->maxdata = 0xffff;
- s->range_table = &range_daqp_ai;
- s->insn_read = daqp_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 2048;
- s->do_cmdtest = daqp_ai_cmdtest;
- s->do_cmd = daqp_ai_cmd;
- s->cancel = daqp_ai_cancel;
- }
-
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &range_bipolar5;
- s->insn_write = daqp_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /*
- * Digital Input subdevice
- * NOTE: The digital input lines are shared:
- *
- * Chan Normal Mode Expansion Mode
- * ---- ----------------- ----------------------------
- * 0 DI0, ext. trigger Same as normal mode
- * 1 DI1 External gain select, lo bit
- * 2 DI2, ext. clock Same as normal mode
- * 3 DI3 External gain select, hi bit
- */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->insn_bits = daqp_di_insn_bits;
-
- /*
- * Digital Output subdevice
- * NOTE: The digital output lines share the same pins on the
- * interface connector as the four external channel selection
- * bits. If expansion mode is used the digital outputs do not
- * work.
- */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->insn_bits = daqp_do_insn_bits;
-
- return 0;
-}
-
-static struct comedi_driver driver_daqp = {
- .driver_name = "quatech_daqp_cs",
- .module = THIS_MODULE,
- .auto_attach = daqp_auto_attach,
- .detach = comedi_pcmcia_disable,
-};
-
-static int daqp_cs_suspend(struct pcmcia_device *link)
-{
- struct comedi_device *dev = link->priv;
- struct daqp_private *devpriv = dev ? dev->private : NULL;
-
- /* Mark the device as stopped, to block IO until later */
- if (devpriv)
- devpriv->stop = 1;
-
- return 0;
-}
-
-static int daqp_cs_resume(struct pcmcia_device *link)
-{
- struct comedi_device *dev = link->priv;
- struct daqp_private *devpriv = dev ? dev->private : NULL;
-
- if (devpriv)
- devpriv->stop = 0;
-
- return 0;
-}
-
-static int daqp_cs_attach(struct pcmcia_device *link)
-{
- return comedi_pcmcia_auto_config(link, &driver_daqp);
-}
-
-static const struct pcmcia_device_id daqp_cs_id_table[] = {
- PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
- PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
-
-static struct pcmcia_driver daqp_cs_driver = {
- .name = "quatech_daqp_cs",
- .owner = THIS_MODULE,
- .id_table = daqp_cs_id_table,
- .probe = daqp_cs_attach,
- .remove = comedi_pcmcia_auto_unconfig,
- .suspend = daqp_cs_suspend,
- .resume = daqp_cs_resume,
-};
-module_comedi_pcmcia_driver(driver_daqp, daqp_cs_driver);
-
-MODULE_DESCRIPTION("Comedi driver for Quatech DAQP PCMCIA data capture cards");
-MODULE_AUTHOR("Brent Baccala <baccala@freesoft.org>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
deleted file mode 100644
index 2d99a648b054..000000000000
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ /dev/null
@@ -1,1365 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/rtd520.c
- * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2001 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: rtd520
- * Description: Real Time Devices PCI4520/DM7520
- * Devices: [Real Time Devices] DM7520HR-1 (DM7520), DM7520HR-8,
- * PCI4520 (PCI4520), PCI4520-8
- * Author: Dan Christian
- * Status: Works. Only tested on DM7520-8. Not SMP safe.
- *
- * Configuration options: not applicable, uses PCI auto config
- */
-
-/*
- * Created by Dan Christian, NASA Ames Research Center.
- *
- * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
- * Both have:
- * 8/16 12 bit ADC with FIFO and channel gain table
- * 8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
- * 8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
- * 2 12 bit DACs with FIFOs
- * 2 bits output
- * 2 bits input
- * bus mastering DMA
- * timers: ADC sample, pacer, burst, about, delay, DA1, DA2
- * sample counter
- * 3 user timer/counters (8254)
- * external interrupt
- *
- * The DM7520 has slightly fewer features (fewer gain steps).
- *
- * These boards can support external multiplexors and multi-board
- * synchronization, but this driver doesn't support that.
- *
- * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
- * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
- * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
- * Call them and ask for the register level manual.
- * PCI chip: http://www.plxtech.com/products/io/pci9080
- *
- * Notes:
- * This board is memory mapped. There is some IO stuff, but it isn't needed.
- *
- * I use a pretty loose naming style within the driver (rtd_blah).
- * All externally visible names should be rtd520_blah.
- * I use camelCase for structures (and inside them).
- * I may also use upper CamelCase for function names (old habit).
- *
- * This board is somewhat related to the RTD PCI4400 board.
- *
- * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
- * das1800, since they have the best documented code. Driver cb_pcidas64.c
- * uses the same DMA controller.
- *
- * As far as I can tell, the About interrupt doesn't work if Sample is
- * also enabled. It turns out that About really isn't needed, since
- * we always count down samples read.
- */
-
-/*
- * driver status:
- *
- * Analog-In supports instruction and command mode.
- *
- * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
- * (single channel, 64K read buffer). I get random system lockups when
- * using DMA with ALI-15xx based systems. I haven't been able to test
- * any other chipsets. The lockups happen soon after the start of an
- * acquistion, not in the middle of a long run.
- *
- * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
- * (with a 256K read buffer).
- *
- * Digital-IO and Analog-Out only support instruction mode.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include "../comedi_pci.h"
-
-#include "comedi_8254.h"
-#include "plx9080.h"
-
-/*
- * Local Address Space 0 Offsets
- */
-#define LAS0_USER_IO 0x0008 /* User I/O */
-#define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
-#define FS_DAC1_NOT_EMPTY BIT(0) /* DAC1 FIFO not empty */
-#define FS_DAC1_HEMPTY BIT(1) /* DAC1 FIFO half empty */
-#define FS_DAC1_NOT_FULL BIT(2) /* DAC1 FIFO not full */
-#define FS_DAC2_NOT_EMPTY BIT(4) /* DAC2 FIFO not empty */
-#define FS_DAC2_HEMPTY BIT(5) /* DAC2 FIFO half empty */
-#define FS_DAC2_NOT_FULL BIT(6) /* DAC2 FIFO not full */
-#define FS_ADC_NOT_EMPTY BIT(8) /* ADC FIFO not empty */
-#define FS_ADC_HEMPTY BIT(9) /* ADC FIFO half empty */
-#define FS_ADC_NOT_FULL BIT(10) /* ADC FIFO not full */
-#define FS_DIN_NOT_EMPTY BIT(12) /* DIN FIFO not empty */
-#define FS_DIN_HEMPTY BIT(13) /* DIN FIFO half empty */
-#define FS_DIN_NOT_FULL BIT(14) /* DIN FIFO not full */
-#define LAS0_UPDATE_DAC(x) (0x0014 + ((x) * 0x4)) /* D/Ax Update (w) */
-#define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
-#define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
-#define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
-#define LAS0_IT 0x0030 /* Interrupt Status/Enable */
-#define IRQM_ADC_FIFO_WRITE BIT(0) /* ADC FIFO Write */
-#define IRQM_CGT_RESET BIT(1) /* Reset CGT */
-#define IRQM_CGT_PAUSE BIT(3) /* Pause CGT */
-#define IRQM_ADC_ABOUT_CNT BIT(4) /* About Counter out */
-#define IRQM_ADC_DELAY_CNT BIT(5) /* Delay Counter out */
-#define IRQM_ADC_SAMPLE_CNT BIT(6) /* ADC Sample Counter */
-#define IRQM_DAC1_UCNT BIT(7) /* DAC1 Update Counter */
-#define IRQM_DAC2_UCNT BIT(8) /* DAC2 Update Counter */
-#define IRQM_UTC1 BIT(9) /* User TC1 out */
-#define IRQM_UTC1_INV BIT(10) /* User TC1 out, inverted */
-#define IRQM_UTC2 BIT(11) /* User TC2 out */
-#define IRQM_DIGITAL_IT BIT(12) /* Digital Interrupt */
-#define IRQM_EXTERNAL_IT BIT(13) /* External Interrupt */
-#define IRQM_ETRIG_RISING BIT(14) /* Ext Trigger rising-edge */
-#define IRQM_ETRIG_FALLING BIT(15) /* Ext Trigger falling-edge */
-#define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
-#define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
-#define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
-#define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
-#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
-#define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
-#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
-#define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
-#define LAS0_ACNT 0x0058 /* About counter (16 bit) */
-#define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
-#define LAS0_8254_TIMER_BASE 0x0060 /* 8254 timer/counter base */
-#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
-#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
-#define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
-#define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
-#define LAS0_BOARD_RESET 0x0100 /* Board reset */
-#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
-#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
-#define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
-#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
-#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
-#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
-#define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
-#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
-#define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
-#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
-#define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
-#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
-#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
-#define LAS0_CG_DATA 0x0138 /* Digital Table Write */
-#define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
-#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
-#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
-#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
-#define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
-#define LAS0_DAC_CTRL(x) (0x0150 + ((x) * 0x14)) /* D/Ax type/range */
-#define LAS0_DAC_SRC(x) (0x0154 + ((x) * 0x14)) /* D/Ax update source */
-#define LAS0_DAC_CYCLE(x) (0x0158 + ((x) * 0x14)) /* D/Ax cycle mode */
-#define LAS0_DAC_RESET(x) (0x015c + ((x) * 0x14)) /* D/Ax FIFO reset */
-#define LAS0_DAC_FIFO_CLEAR(x) (0x0160 + ((x) * 0x14)) /* D/Ax FIFO clear */
-#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
-#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
-#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
-#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
-#define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
-#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
-#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
-#define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
-#define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
-#define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
-#define LAS0_8254_CLK_SEL(x) (0x01ac + ((x) * 0x8)) /* 8254 clock select */
-#define LAS0_8254_GATE_SEL(x) (0x01b0 + ((x) * 0x8)) /* 8254 gate select */
-#define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
-#define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
-#define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
-#define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
-
-/*
- * Local Address Space 1 Offsets
- */
-#define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
-#define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
-#define LAS1_DAC_FIFO(x) (0x0008 + ((x) * 0x4)) /* D/Ax FIFO (16bit) */
-
-/*
- * Driver specific stuff (tunable)
- */
-
-/*
- * We really only need 2 buffers. More than that means being much
- * smarter about knowing which ones are full.
- */
-#define DMA_CHAIN_COUNT 2 /* max DMA segments/buffers in a ring (min 2) */
-
-/* Target period for periodic transfers. This sets the user read latency. */
-/* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
-/* If this is too low, efficiency is poor */
-#define TRANS_TARGET_PERIOD 10000000 /* 10 ms (in nanoseconds) */
-
-/* Set a practical limit on how long a list to support (affects memory use) */
-/* The board support a channel list up to the FIFO length (1K or 8K) */
-#define RTD_MAX_CHANLIST 128 /* max channel list that we allow */
-
-/*
- * Board specific stuff
- */
-
-#define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */
-#define RTD_CLOCK_BASE 125 /* clock period in ns */
-
-/* Note: these speed are slower than the spec, but fit the counter resolution*/
-#define RTD_MAX_SPEED 1625 /* when sampling, in nanoseconds */
-/* max speed if we don't have to wait for settling */
-#define RTD_MAX_SPEED_1 875 /* if single channel, in nanoseconds */
-
-#define RTD_MIN_SPEED 2097151875 /* (24bit counter) in nanoseconds */
-/* min speed when only 1 channel (no burst counter) */
-#define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
-
-/* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */
-#define DMA_MODE_BITS (\
- PLX_LOCAL_BUS_16_WIDE_BITS \
- | PLX_DMA_EN_READYIN_BIT \
- | PLX_DMA_LOCAL_BURST_EN_BIT \
- | PLX_EN_CHAIN_BIT \
- | PLX_DMA_INTR_PCI_BIT \
- | PLX_LOCAL_ADDR_CONST_BIT \
- | PLX_DEMAND_MODE_BIT)
-
-#define DMA_TRANSFER_BITS (\
-/* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \
-/* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
-/* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI)
-
-/*
- * Comedi specific stuff
- */
-
-/*
- * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
- */
-static const struct comedi_lrange rtd_ai_7520_range = {
- 18, {
- /* +-5V input range gain steps */
- BIP_RANGE(5.0),
- BIP_RANGE(5.0 / 2),
- BIP_RANGE(5.0 / 4),
- BIP_RANGE(5.0 / 8),
- BIP_RANGE(5.0 / 16),
- BIP_RANGE(5.0 / 32),
- /* +-10V input range gain steps */
- BIP_RANGE(10.0),
- BIP_RANGE(10.0 / 2),
- BIP_RANGE(10.0 / 4),
- BIP_RANGE(10.0 / 8),
- BIP_RANGE(10.0 / 16),
- BIP_RANGE(10.0 / 32),
- /* +10V input range gain steps */
- UNI_RANGE(10.0),
- UNI_RANGE(10.0 / 2),
- UNI_RANGE(10.0 / 4),
- UNI_RANGE(10.0 / 8),
- UNI_RANGE(10.0 / 16),
- UNI_RANGE(10.0 / 32),
- }
-};
-
-/* PCI4520 has two more gains (6 more entries) */
-static const struct comedi_lrange rtd_ai_4520_range = {
- 24, {
- /* +-5V input range gain steps */
- BIP_RANGE(5.0),
- BIP_RANGE(5.0 / 2),
- BIP_RANGE(5.0 / 4),
- BIP_RANGE(5.0 / 8),
- BIP_RANGE(5.0 / 16),
- BIP_RANGE(5.0 / 32),
- BIP_RANGE(5.0 / 64),
- BIP_RANGE(5.0 / 128),
- /* +-10V input range gain steps */
- BIP_RANGE(10.0),
- BIP_RANGE(10.0 / 2),
- BIP_RANGE(10.0 / 4),
- BIP_RANGE(10.0 / 8),
- BIP_RANGE(10.0 / 16),
- BIP_RANGE(10.0 / 32),
- BIP_RANGE(10.0 / 64),
- BIP_RANGE(10.0 / 128),
- /* +10V input range gain steps */
- UNI_RANGE(10.0),
- UNI_RANGE(10.0 / 2),
- UNI_RANGE(10.0 / 4),
- UNI_RANGE(10.0 / 8),
- UNI_RANGE(10.0 / 16),
- UNI_RANGE(10.0 / 32),
- UNI_RANGE(10.0 / 64),
- UNI_RANGE(10.0 / 128),
- }
-};
-
-/* Table order matches range values */
-static const struct comedi_lrange rtd_ao_range = {
- 4, {
- UNI_RANGE(5),
- UNI_RANGE(10),
- BIP_RANGE(5),
- BIP_RANGE(10),
- }
-};
-
-enum rtd_boardid {
- BOARD_DM7520,
- BOARD_PCI4520,
-};
-
-struct rtd_boardinfo {
- const char *name;
- int range_bip10; /* start of +-10V range */
- int range_uni10; /* start of +10V range */
- const struct comedi_lrange *ai_range;
-};
-
-static const struct rtd_boardinfo rtd520_boards[] = {
- [BOARD_DM7520] = {
- .name = "DM7520",
- .range_bip10 = 6,
- .range_uni10 = 12,
- .ai_range = &rtd_ai_7520_range,
- },
- [BOARD_PCI4520] = {
- .name = "PCI4520",
- .range_bip10 = 8,
- .range_uni10 = 16,
- .ai_range = &rtd_ai_4520_range,
- },
-};
-
-struct rtd_private {
- /* memory mapped board structures */
- void __iomem *las1;
- void __iomem *lcfg;
-
- long ai_count; /* total transfer size (samples) */
- int xfer_count; /* # to transfer data. 0->1/2FIFO */
- int flags; /* flag event modes */
- unsigned int fifosz;
-
- /* 8254 Timer/Counter gate and clock sources */
- unsigned char timer_gate_src[3];
- unsigned char timer_clk_src[3];
-};
-
-/* bit defines for "flags" */
-#define SEND_EOS 0x01 /* send End Of Scan events */
-#define DMA0_ACTIVE 0x02 /* DMA0 is active */
-#define DMA1_ACTIVE 0x04 /* DMA1 is active */
-
-/*
- * Given a desired period and the clock period (both in ns), return the
- * proper counter value (divider-1). Sets the original period to be the
- * true value.
- * Note: you have to check if the value is larger than the counter range!
- */
-static int rtd_ns_to_timer_base(unsigned int *nanosec,
- unsigned int flags, int base)
-{
- int divider;
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- divider = DIV_ROUND_CLOSEST(*nanosec, base);
- break;
- case CMDF_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case CMDF_ROUND_UP:
- divider = DIV_ROUND_UP(*nanosec, base);
- break;
- }
- if (divider < 2)
- divider = 2; /* min is divide by 2 */
-
- /*
- * Note: we don't check for max, because different timers
- * have different ranges
- */
-
- *nanosec = base * divider;
- return divider - 1; /* countdown is divisor+1 */
-}
-
-/*
- * Given a desired period (in ns), return the proper counter value
- * (divider-1) for the internal clock. Sets the original period to
- * be the true value.
- */
-static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
-{
- return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
-}
-
-/* Convert a single comedi channel-gain entry to a RTD520 table entry */
-static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
- unsigned int chanspec, int index)
-{
- const struct rtd_boardinfo *board = dev->board_ptr;
- unsigned int chan = CR_CHAN(chanspec);
- unsigned int range = CR_RANGE(chanspec);
- unsigned int aref = CR_AREF(chanspec);
- unsigned short r = 0;
-
- r |= chan & 0xf;
-
- /* Note: we also setup the channel list bipolar flag array */
- if (range < board->range_bip10) {
- /* +-5 range */
- r |= 0x000;
- r |= (range & 0x7) << 4;
- } else if (range < board->range_uni10) {
- /* +-10 range */
- r |= 0x100;
- r |= ((range - board->range_bip10) & 0x7) << 4;
- } else {
- /* +10 range */
- r |= 0x200;
- r |= ((range - board->range_uni10) & 0x7) << 4;
- }
-
- switch (aref) {
- case AREF_GROUND: /* on-board ground */
- break;
-
- case AREF_COMMON:
- r |= 0x80; /* ref external analog common */
- break;
-
- case AREF_DIFF:
- r |= 0x400; /* differential inputs */
- break;
-
- case AREF_OTHER: /* ??? */
- break;
- }
- return r;
-}
-
-/* Setup the channel-gain table from a comedi list */
-static void rtd_load_channelgain_list(struct comedi_device *dev,
- unsigned int n_chan, unsigned int *list)
-{
- if (n_chan > 1) { /* setup channel gain table */
- int ii;
-
- writel(0, dev->mmio + LAS0_CGT_CLEAR);
- writel(1, dev->mmio + LAS0_CGT_ENABLE);
- for (ii = 0; ii < n_chan; ii++) {
- writel(rtd_convert_chan_gain(dev, list[ii], ii),
- dev->mmio + LAS0_CGT_WRITE);
- }
- } else { /* just use the channel gain latch */
- writel(0, dev->mmio + LAS0_CGT_ENABLE);
- writel(rtd_convert_chan_gain(dev, list[0], 0),
- dev->mmio + LAS0_CGL_WRITE);
- }
-}
-
-/*
- * Determine fifo size by doing adc conversions until the fifo half
- * empty status flag clears.
- */
-static int rtd520_probe_fifo_depth(struct comedi_device *dev)
-{
- unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
- unsigned int i;
- static const unsigned int limit = 0x2000;
- unsigned int fifo_size = 0;
-
- writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
- rtd_load_channelgain_list(dev, 1, &chanspec);
- /* ADC conversion trigger source: SOFTWARE */
- writel(0, dev->mmio + LAS0_ADC_CONVERSION);
- /* convert samples */
- for (i = 0; i < limit; ++i) {
- unsigned int fifo_status;
- /* trigger conversion */
- writew(0, dev->mmio + LAS0_ADC);
- usleep_range(1, 1000);
- fifo_status = readl(dev->mmio + LAS0_ADC);
- if ((fifo_status & FS_ADC_HEMPTY) == 0) {
- fifo_size = 2 * i;
- break;
- }
- }
- if (i == limit) {
- dev_info(dev->class_dev, "failed to probe fifo size.\n");
- return -EIO;
- }
- writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
- if (fifo_size != 0x400 && fifo_size != 0x2000) {
- dev_info(dev->class_dev,
- "unexpected fifo size of %i, expected 1024 or 8192.\n",
- fifo_size);
- return -EIO;
- }
- return fifo_size;
-}
-
-static int rtd_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = readl(dev->mmio + LAS0_ADC);
- if (status & FS_ADC_NOT_EMPTY)
- return 0;
- return -EBUSY;
-}
-
-static int rtd_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
-{
- struct rtd_private *devpriv = dev->private;
- unsigned int range = CR_RANGE(insn->chanspec);
- int ret;
- int n;
-
- /* clear any old fifo data */
- writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
-
- /* write channel to multiplexer and clear channel gain table */
- rtd_load_channelgain_list(dev, 1, &insn->chanspec);
-
- /* ADC conversion trigger source: SOFTWARE */
- writel(0, dev->mmio + LAS0_ADC_CONVERSION);
-
- /* convert n samples */
- for (n = 0; n < insn->n; n++) {
- unsigned short d;
- /* trigger conversion */
- writew(0, dev->mmio + LAS0_ADC);
-
- ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* read data */
- d = readw(devpriv->las1 + LAS1_ADC_FIFO);
- d >>= 3; /* low 3 bits are marker lines */
-
- /* convert bipolar data to comedi unsigned data */
- if (comedi_range_is_bipolar(s, range))
- d = comedi_offset_munge(s, d);
-
- data[n] = d & s->maxdata;
- }
-
- /* return the number of samples read/written */
- return n;
-}
-
-static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
- int count)
-{
- struct rtd_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- int ii;
-
- for (ii = 0; ii < count; ii++) {
- unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]);
- unsigned short d;
-
- if (devpriv->ai_count == 0) { /* done */
- d = readw(devpriv->las1 + LAS1_ADC_FIFO);
- continue;
- }
-
- d = readw(devpriv->las1 + LAS1_ADC_FIFO);
- d >>= 3; /* low 3 bits are marker lines */
-
- /* convert bipolar data to comedi unsigned data */
- if (comedi_range_is_bipolar(s, range))
- d = comedi_offset_munge(s, d);
- d &= s->maxdata;
-
- if (!comedi_buf_write_samples(s, &d, 1))
- return -1;
-
- if (devpriv->ai_count > 0) /* < 0, means read forever */
- devpriv->ai_count--;
- }
- return 0;
-}
-
-static irqreturn_t rtd_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- struct rtd_private *devpriv = dev->private;
- u32 overrun;
- u16 status;
- u16 fifo_status;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- fifo_status = readl(dev->mmio + LAS0_ADC);
- /* check for FIFO full, this automatically halts the ADC! */
- if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */
- goto xfer_abort;
-
- status = readw(dev->mmio + LAS0_IT);
- /* if interrupt was not caused by our board, or handled above */
- if (status == 0)
- return IRQ_HANDLED;
-
- if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */
- /*
- * since the priority interrupt controller may have queued
- * a sample counter interrupt, even though we have already
- * finished, we must handle the possibility that there is
- * no data here
- */
- if (!(fifo_status & FS_ADC_HEMPTY)) {
- /* FIFO half full */
- if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
- goto xfer_abort;
-
- if (devpriv->ai_count == 0)
- goto xfer_done;
- } else if (devpriv->xfer_count > 0) {
- if (fifo_status & FS_ADC_NOT_EMPTY) {
- /* FIFO not empty */
- if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
- goto xfer_abort;
-
- if (devpriv->ai_count == 0)
- goto xfer_done;
- }
- }
- }
-
- overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
- if (overrun)
- goto xfer_abort;
-
- /* clear the interrupt */
- writew(status, dev->mmio + LAS0_CLEAR);
- readw(dev->mmio + LAS0_CLEAR);
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-
-xfer_abort:
- s->async->events |= COMEDI_CB_ERROR;
-
-xfer_done:
- s->async->events |= COMEDI_CB_EOA;
-
- /* clear the interrupt */
- status = readw(dev->mmio + LAS0_IT);
- writew(status, dev->mmio + LAS0_CLEAR);
- readw(dev->mmio + LAS0_CLEAR);
-
- fifo_status = readl(dev->mmio + LAS0_ADC);
- overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
-
- comedi_handle_events(dev, s);
-
- return IRQ_HANDLED;
-}
-
-static int rtd_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Note: these are time periods, not actual rates */
- if (cmd->chanlist_len == 1) { /* no scanning */
- if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- RTD_MAX_SPEED_1)) {
- rtd_ns_to_timer(&cmd->scan_begin_arg,
- CMDF_ROUND_UP);
- err |= -EINVAL;
- }
- if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- RTD_MIN_SPEED_1)) {
- rtd_ns_to_timer(&cmd->scan_begin_arg,
- CMDF_ROUND_DOWN);
- err |= -EINVAL;
- }
- } else {
- if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- RTD_MAX_SPEED)) {
- rtd_ns_to_timer(&cmd->scan_begin_arg,
- CMDF_ROUND_UP);
- err |= -EINVAL;
- }
- if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- RTD_MIN_SPEED)) {
- rtd_ns_to_timer(&cmd->scan_begin_arg,
- CMDF_ROUND_DOWN);
- err |= -EINVAL;
- }
- }
- } else {
- /* external trigger */
- /* should be level/edge, hi/lo specification here */
- /* should specify multiple external triggers */
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- if (cmd->chanlist_len == 1) { /* no scanning */
- if (comedi_check_trigger_arg_min(&cmd->convert_arg,
- RTD_MAX_SPEED_1)) {
- rtd_ns_to_timer(&cmd->convert_arg,
- CMDF_ROUND_UP);
- err |= -EINVAL;
- }
- if (comedi_check_trigger_arg_max(&cmd->convert_arg,
- RTD_MIN_SPEED_1)) {
- rtd_ns_to_timer(&cmd->convert_arg,
- CMDF_ROUND_DOWN);
- err |= -EINVAL;
- }
- } else {
- if (comedi_check_trigger_arg_min(&cmd->convert_arg,
- RTD_MAX_SPEED)) {
- rtd_ns_to_timer(&cmd->convert_arg,
- CMDF_ROUND_UP);
- err |= -EINVAL;
- }
- if (comedi_check_trigger_arg_max(&cmd->convert_arg,
- RTD_MIN_SPEED)) {
- rtd_ns_to_timer(&cmd->convert_arg,
- CMDF_ROUND_DOWN);
- err |= -EINVAL;
- }
- }
- } else {
- /* external trigger */
- /* see above */
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 9);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- rtd_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- rtd_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->convert_arg * cmd->scan_end_arg;
- err |= comedi_check_trigger_arg_min(
- &cmd->scan_begin_arg, arg);
- }
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct rtd_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int timer;
-
- /* stop anything currently running */
- /* pacer stop source: SOFTWARE */
- writel(0, dev->mmio + LAS0_PACER_STOP);
- writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
- writel(0, dev->mmio + LAS0_ADC_CONVERSION);
- writew(0, dev->mmio + LAS0_IT);
- writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
- writel(0, dev->mmio + LAS0_OVERRUN);
-
- /* start configuration */
- /* load channel list and reset CGT */
- rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
-
- /* setup the common case and override if needed */
- if (cmd->chanlist_len > 1) {
- /* pacer start source: SOFTWARE */
- writel(0, dev->mmio + LAS0_PACER_START);
- /* burst trigger source: PACER */
- writel(1, dev->mmio + LAS0_BURST_START);
- /* ADC conversion trigger source: BURST */
- writel(2, dev->mmio + LAS0_ADC_CONVERSION);
- } else { /* single channel */
- /* pacer start source: SOFTWARE */
- writel(0, dev->mmio + LAS0_PACER_START);
- /* ADC conversion trigger source: PACER */
- writel(1, dev->mmio + LAS0_ADC_CONVERSION);
- }
- writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* scan_begin_arg is in nanoseconds */
- /* find out how many samples to wait before transferring */
- if (cmd->flags & CMDF_WAKE_EOS) {
- /*
- * this may generate un-sustainable interrupt rates
- * the application is responsible for doing the
- * right thing
- */
- devpriv->xfer_count = cmd->chanlist_len;
- devpriv->flags |= SEND_EOS;
- } else {
- /* arrange to transfer data periodically */
- devpriv->xfer_count =
- (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
- cmd->scan_begin_arg;
- if (devpriv->xfer_count < cmd->chanlist_len) {
- /* transfer after each scan (and avoid 0) */
- devpriv->xfer_count = cmd->chanlist_len;
- } else { /* make a multiple of scan length */
- devpriv->xfer_count =
- DIV_ROUND_UP(devpriv->xfer_count,
- cmd->chanlist_len);
- devpriv->xfer_count *= cmd->chanlist_len;
- }
- devpriv->flags |= SEND_EOS;
- }
- if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
- /* out of counter range, use 1/2 fifo instead */
- devpriv->xfer_count = 0;
- devpriv->flags &= ~SEND_EOS;
- } else {
- /* interrupt for each transfer */
- writel((devpriv->xfer_count - 1) & 0xffff,
- dev->mmio + LAS0_ACNT);
- }
- } else { /* unknown timing, just use 1/2 FIFO */
- devpriv->xfer_count = 0;
- devpriv->flags &= ~SEND_EOS;
- }
- /* pacer clock source: INTERNAL 8MHz */
- writel(1, dev->mmio + LAS0_PACER_SELECT);
- /* just interrupt, don't stop */
- writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
-
- /* BUG??? these look like enumerated values, but they are bit fields */
-
- /* First, setup when to stop */
- switch (cmd->stop_src) {
- case TRIG_COUNT: /* stop after N scans */
- devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
- if ((devpriv->xfer_count > 0) &&
- (devpriv->xfer_count > devpriv->ai_count)) {
- devpriv->xfer_count = devpriv->ai_count;
- }
- break;
-
- case TRIG_NONE: /* stop when cancel is called */
- devpriv->ai_count = -1; /* read forever */
- break;
- }
-
- /* Scan timing */
- switch (cmd->scan_begin_src) {
- case TRIG_TIMER: /* periodic scanning */
- timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
- CMDF_ROUND_NEAREST);
- /* set PACER clock */
- writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
-
- break;
-
- case TRIG_EXT:
- /* pacer start source: EXTERNAL */
- writel(1, dev->mmio + LAS0_PACER_START);
- break;
- }
-
- /* Sample timing within a scan */
- switch (cmd->convert_src) {
- case TRIG_TIMER: /* periodic */
- if (cmd->chanlist_len > 1) {
- /* only needed for multi-channel */
- timer = rtd_ns_to_timer(&cmd->convert_arg,
- CMDF_ROUND_NEAREST);
- /* setup BURST clock */
- writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
- }
-
- break;
-
- case TRIG_EXT: /* external */
- /* burst trigger source: EXTERNAL */
- writel(2, dev->mmio + LAS0_BURST_START);
- break;
- }
- /* end configuration */
-
- /*
- * This doesn't seem to work. There is no way to clear an interrupt
- * that the priority controller has queued!
- */
- writew(~0, dev->mmio + LAS0_CLEAR);
- readw(dev->mmio + LAS0_CLEAR);
-
- /* TODO: allow multiple interrupt sources */
- /* transfer every N samples */
- writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
-
- /* BUG: start_src is ASSUMED to be TRIG_NOW */
- /* BUG? it seems like things are running before the "start" */
- readl(dev->mmio + LAS0_PACER); /* start pacer */
- return 0;
-}
-
-static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct rtd_private *devpriv = dev->private;
-
- /* pacer stop source: SOFTWARE */
- writel(0, dev->mmio + LAS0_PACER_STOP);
- writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
- writel(0, dev->mmio + LAS0_ADC_CONVERSION);
- writew(0, dev->mmio + LAS0_IT);
- devpriv->ai_count = 0; /* stop and don't transfer any more */
- writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
- return 0;
-}
-
-static int rtd_ao_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
- unsigned int status;
-
- status = readl(dev->mmio + LAS0_ADC);
- if (status & bit)
- return 0;
- return -EBUSY;
-}
-
-static int rtd_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct rtd_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- int ret;
- int i;
-
- /* Configure the output range (table index matches the range values) */
- writew(range & 7, dev->mmio + LAS0_DAC_CTRL(chan));
-
- for (i = 0; i < insn->n; ++i) {
- unsigned int val = data[i];
-
- /* bipolar uses 2's complement values with an extended sign */
- if (comedi_range_is_bipolar(s, range)) {
- val = comedi_offset_munge(s, val);
- val |= (val & ((s->maxdata + 1) >> 1)) << 1;
- }
-
- /* shift the 12-bit data (+ sign) to match the register */
- val <<= 3;
-
- writew(val, devpriv->las1 + LAS1_DAC_FIFO(chan));
- writew(0, dev->mmio + LAS0_UPDATE_DAC(chan));
-
- ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
- if (ret)
- return ret;
-
- s->readback[chan] = data[i];
- }
-
- return insn->n;
-}
-
-static int rtd_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
-
- data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
-
- return insn->n;
-}
-
-static int rtd_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- /* TODO support digital match interrupts and strobes */
-
- /* set direction */
- writew(0x01, dev->mmio + LAS0_DIO_STATUS);
- writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
-
- /* clear interrupts */
- writew(0x00, dev->mmio + LAS0_DIO_STATUS);
-
- /* port1 can only be all input or all output */
-
- /* there are also 2 user input lines and 2 user output lines */
-
- return insn->n;
-}
-
-static int rtd_counter_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct rtd_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int max_src;
- unsigned int src;
-
- switch (data[0]) {
- case INSN_CONFIG_SET_GATE_SRC:
- /*
- * 8254 Timer/Counter gate sources:
- *
- * 0 = Not gated, free running (reset state)
- * 1 = Gated, off
- * 2 = Ext. TC Gate 1
- * 3 = Ext. TC Gate 2
- * 4 = Previous TC out (chan 1 and 2 only)
- */
- src = data[2];
- max_src = (chan == 0) ? 3 : 4;
- if (src > max_src)
- return -EINVAL;
-
- devpriv->timer_gate_src[chan] = src;
- writeb(src, dev->mmio + LAS0_8254_GATE_SEL(chan));
- break;
- case INSN_CONFIG_GET_GATE_SRC:
- data[2] = devpriv->timer_gate_src[chan];
- break;
- case INSN_CONFIG_SET_CLOCK_SRC:
- /*
- * 8254 Timer/Counter clock sources:
- *
- * 0 = 8 MHz (reset state)
- * 1 = Ext. TC Clock 1
- * 2 = Ext. TX Clock 2
- * 3 = Ext. Pacer Clock
- * 4 = Previous TC out (chan 1 and 2 only)
- * 5 = High-Speed Digital Input Sampling signal (chan 1 only)
- */
- src = data[1];
- switch (chan) {
- case 0:
- max_src = 3;
- break;
- case 1:
- max_src = 5;
- break;
- case 2:
- max_src = 4;
- break;
- default:
- return -EINVAL;
- }
- if (src > max_src)
- return -EINVAL;
-
- devpriv->timer_clk_src[chan] = src;
- writeb(src, dev->mmio + LAS0_8254_CLK_SEL(chan));
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- src = devpriv->timer_clk_src[chan];
- data[1] = devpriv->timer_clk_src[chan];
- data[2] = (src == 0) ? RTD_CLOCK_BASE : 0;
- break;
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static void rtd_reset(struct comedi_device *dev)
-{
- struct rtd_private *devpriv = dev->private;
-
- writel(0, dev->mmio + LAS0_BOARD_RESET);
- usleep_range(100, 1000); /* needed? */
- writel(0, devpriv->lcfg + PLX_REG_INTCSR);
- writew(0, dev->mmio + LAS0_IT);
- writew(~0, dev->mmio + LAS0_CLEAR);
- readw(dev->mmio + LAS0_CLEAR);
-}
-
-/*
- * initialize board, per RTD spec
- * also, initialize shadow registers
- */
-static void rtd_init_board(struct comedi_device *dev)
-{
- rtd_reset(dev);
-
- writel(0, dev->mmio + LAS0_OVERRUN);
- writel(0, dev->mmio + LAS0_CGT_CLEAR);
- writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
- writel(0, dev->mmio + LAS0_DAC_RESET(0));
- writel(0, dev->mmio + LAS0_DAC_RESET(1));
- /* clear digital IO fifo */
- writew(0, dev->mmio + LAS0_DIO_STATUS);
- /* TODO: set user out source ??? */
-}
-
-/* The RTD driver does this */
-static void rtd_pci_latency_quirk(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- unsigned char pci_latency;
-
- pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
- if (pci_latency < 32) {
- dev_info(dev->class_dev,
- "PCI latency changed from %d to %d\n",
- pci_latency, 32);
- pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
- }
-}
-
-static int rtd_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct rtd_boardinfo *board = NULL;
- struct rtd_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- if (context < ARRAY_SIZE(rtd520_boards))
- board = &rtd520_boards[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 2);
- devpriv->las1 = pci_ioremap_bar(pcidev, 3);
- devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
- if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
- return -ENOMEM;
-
- rtd_pci_latency_quirk(dev, pcidev);
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
- s->n_chan = 16;
- s->maxdata = 0x0fff;
- s->range_table = board->ai_range;
- s->len_chanlist = RTD_MAX_CHANLIST;
- s->insn_read = rtd_ai_rinsn;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->do_cmd = rtd_ai_cmd;
- s->do_cmdtest = rtd_ai_cmdtest;
- s->cancel = rtd_ai_cancel;
- }
-
- s = &dev->subdevices[1];
- /* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table = &rtd_ao_range;
- s->insn_write = rtd_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s = &dev->subdevices[2];
- /* digital i/o subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- /* we only support port 0 right now. Ignoring port 1 and user IO */
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = rtd_dio_insn_bits;
- s->insn_config = rtd_dio_insn_config;
-
- /* 8254 Timer/Counter subdevice */
- s = &dev->subdevices[3];
- dev->pacer = comedi_8254_mm_init(dev->mmio + LAS0_8254_TIMER_BASE,
- RTD_CLOCK_BASE, I8254_IO8, 2);
- if (!dev->pacer)
- return -ENOMEM;
-
- comedi_8254_subdevice_init(s, dev->pacer);
- dev->pacer->insn_config = rtd_counter_insn_config;
-
- rtd_init_board(dev);
-
- ret = rtd520_probe_fifo_depth(dev);
- if (ret < 0)
- return ret;
- devpriv->fifosz = ret;
-
- if (dev->irq)
- writel(PLX_INTCSR_PIEN | PLX_INTCSR_PLIEN,
- devpriv->lcfg + PLX_REG_INTCSR);
-
- return 0;
-}
-
-static void rtd_detach(struct comedi_device *dev)
-{
- struct rtd_private *devpriv = dev->private;
-
- if (devpriv) {
- /* Shut down any board ops by resetting it */
- if (dev->mmio && devpriv->lcfg)
- rtd_reset(dev);
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->mmio)
- iounmap(dev->mmio);
- if (devpriv->las1)
- iounmap(devpriv->las1);
- if (devpriv->lcfg)
- iounmap(devpriv->lcfg);
- }
- comedi_pci_disable(dev);
-}
-
-static struct comedi_driver rtd520_driver = {
- .driver_name = "rtd520",
- .module = THIS_MODULE,
- .auto_attach = rtd_auto_attach,
- .detach = rtd_detach,
-};
-
-static int rtd520_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
-}
-
-static const struct pci_device_id rtd520_pci_table[] = {
- { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
- { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
-
-static struct pci_driver rtd520_pci_driver = {
- .name = "rtd520",
- .id_table = rtd520_pci_table,
- .probe = rtd520_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
deleted file mode 100644
index 327fd93b8b12..000000000000
--- a/drivers/staging/comedi/drivers/rti800.c
+++ /dev/null
@@ -1,357 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/rti800.c
- * Hardware driver for Analog Devices RTI-800/815 board
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: rti800
- * Description: Analog Devices RTI-800/815
- * Devices: [Analog Devices] RTI-800 (rti800), RTI-815 (rti815)
- * Author: David A. Schleef <ds@schleef.org>
- * Status: unknown
- * Updated: Fri, 05 Sep 2008 14:50:44 +0100
- *
- * Configuration options:
- * [0] - I/O port base address
- * [1] - IRQ (not supported / unused)
- * [2] - A/D mux/reference (number of channels)
- * 0 = differential
- * 1 = pseudodifferential (common)
- * 2 = single-ended
- * [3] - A/D range
- * 0 = [-10,10]
- * 1 = [-5,5]
- * 2 = [0,10]
- * [4] - A/D encoding
- * 0 = two's complement
- * 1 = straight binary
- * [5] - DAC 0 range
- * 0 = [-10,10]
- * 1 = [0,10]
- * [6] - DAC 0 encoding
- * 0 = two's complement
- * 1 = straight binary
- * [7] - DAC 1 range (same as DAC 0)
- * [8] - DAC 1 encoding (same as DAC 0)
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include "../comedidev.h"
-
-/*
- * Register map
- */
-#define RTI800_CSR 0x00
-#define RTI800_CSR_BUSY BIT(7)
-#define RTI800_CSR_DONE BIT(6)
-#define RTI800_CSR_OVERRUN BIT(5)
-#define RTI800_CSR_TCR BIT(4)
-#define RTI800_CSR_DMA_ENAB BIT(3)
-#define RTI800_CSR_INTR_TC BIT(2)
-#define RTI800_CSR_INTR_EC BIT(1)
-#define RTI800_CSR_INTR_OVRN BIT(0)
-#define RTI800_MUXGAIN 0x01
-#define RTI800_CONVERT 0x02
-#define RTI800_ADCLO 0x03
-#define RTI800_ADCHI 0x04
-#define RTI800_DAC0LO 0x05
-#define RTI800_DAC0HI 0x06
-#define RTI800_DAC1LO 0x07
-#define RTI800_DAC1HI 0x08
-#define RTI800_CLRFLAGS 0x09
-#define RTI800_DI 0x0a
-#define RTI800_DO 0x0b
-#define RTI800_9513A_DATA 0x0c
-#define RTI800_9513A_CNTRL 0x0d
-#define RTI800_9513A_STATUS 0x0d
-
-static const struct comedi_lrange range_rti800_ai_10_bipolar = {
- 4, {
- BIP_RANGE(10),
- BIP_RANGE(1),
- BIP_RANGE(0.1),
- BIP_RANGE(0.02)
- }
-};
-
-static const struct comedi_lrange range_rti800_ai_5_bipolar = {
- 4, {
- BIP_RANGE(5),
- BIP_RANGE(0.5),
- BIP_RANGE(0.05),
- BIP_RANGE(0.01)
- }
-};
-
-static const struct comedi_lrange range_rti800_ai_unipolar = {
- 4, {
- UNI_RANGE(10),
- UNI_RANGE(1),
- UNI_RANGE(0.1),
- UNI_RANGE(0.02)
- }
-};
-
-static const struct comedi_lrange *const rti800_ai_ranges[] = {
- &range_rti800_ai_10_bipolar,
- &range_rti800_ai_5_bipolar,
- &range_rti800_ai_unipolar,
-};
-
-static const struct comedi_lrange *const rti800_ao_ranges[] = {
- &range_bipolar10,
- &range_unipolar10,
-};
-
-struct rti800_board {
- const char *name;
- int has_ao;
-};
-
-static const struct rti800_board rti800_boardtypes[] = {
- {
- .name = "rti800",
- }, {
- .name = "rti815",
- .has_ao = 1,
- },
-};
-
-struct rti800_private {
- bool adc_2comp;
- bool dac_2comp[2];
- const struct comedi_lrange *ao_range_type_list[2];
- unsigned char muxgain_bits;
-};
-
-static int rti800_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned char status;
-
- status = inb(dev->iobase + RTI800_CSR);
- if (status & RTI800_CSR_OVERRUN) {
- outb(0, dev->iobase + RTI800_CLRFLAGS);
- return -EOVERFLOW;
- }
- if (status & RTI800_CSR_DONE)
- return 0;
- return -EBUSY;
-}
-
-static int rti800_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct rti800_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int gain = CR_RANGE(insn->chanspec);
- unsigned char muxgain_bits;
- int ret;
- int i;
-
- inb(dev->iobase + RTI800_ADCHI);
- outb(0, dev->iobase + RTI800_CLRFLAGS);
-
- muxgain_bits = chan | (gain << 5);
- if (muxgain_bits != devpriv->muxgain_bits) {
- devpriv->muxgain_bits = muxgain_bits;
- outb(devpriv->muxgain_bits, dev->iobase + RTI800_MUXGAIN);
- /*
- * Without a delay here, the RTI_CSR_OVERRUN bit
- * gets set, and you will have an error.
- */
- if (insn->n > 0) {
- int delay = (gain == 0) ? 10 :
- (gain == 1) ? 20 :
- (gain == 2) ? 40 : 80;
-
- udelay(delay);
- }
- }
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val;
-
- outb(0, dev->iobase + RTI800_CONVERT);
-
- ret = comedi_timeout(dev, s, insn, rti800_ai_eoc, 0);
- if (ret)
- return ret;
-
- val = inb(dev->iobase + RTI800_ADCLO);
- val |= (inb(dev->iobase + RTI800_ADCHI) & 0xf) << 8;
-
- if (devpriv->adc_2comp)
- val = comedi_offset_munge(s, val);
-
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int rti800_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct rti800_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int reg_lo = chan ? RTI800_DAC1LO : RTI800_DAC0LO;
- int reg_hi = chan ? RTI800_DAC1HI : RTI800_DAC0HI;
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- if (devpriv->dac_2comp[chan])
- val = comedi_offset_munge(s, val);
-
- outb(val & 0xff, dev->iobase + reg_lo);
- outb((val >> 8) & 0xff, dev->iobase + reg_hi);
- }
-
- return insn->n;
-}
-
-static int rti800_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = inb(dev->iobase + RTI800_DI);
- return insn->n;
-}
-
-static int rti800_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data)) {
- /* Outputs are inverted... */
- outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
- }
-
- data[1] = s->state;
-
- return insn->n;
-}
-
-static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct rti800_board *board = dev->board_ptr;
- struct rti800_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x10);
- if (ret)
- return ret;
-
- outb(0, dev->iobase + RTI800_CSR);
- inb(dev->iobase + RTI800_ADCHI);
- outb(0, dev->iobase + RTI800_CLRFLAGS);
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- devpriv->adc_2comp = (it->options[4] == 0);
- devpriv->dac_2comp[0] = (it->options[6] == 0);
- devpriv->dac_2comp[1] = (it->options[8] == 0);
- /* invalid, forces the MUXGAIN register to be set when first used */
- devpriv->muxgain_bits = 0xff;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = (it->options[2] ? 16 : 8);
- s->insn_read = rti800_ai_insn_read;
- s->maxdata = 0x0fff;
- s->range_table = (it->options[3] < ARRAY_SIZE(rti800_ai_ranges))
- ? rti800_ai_ranges[it->options[3]]
- : &range_unknown;
-
- s = &dev->subdevices[1];
- if (board->has_ao) {
- /* ao subdevice (only on rti815) */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->maxdata = 0x0fff;
- s->range_table_list = devpriv->ao_range_type_list;
- devpriv->ao_range_type_list[0] =
- (it->options[5] < ARRAY_SIZE(rti800_ao_ranges))
- ? rti800_ao_ranges[it->options[5]]
- : &range_unknown;
- devpriv->ao_range_type_list[1] =
- (it->options[7] < ARRAY_SIZE(rti800_ao_ranges))
- ? rti800_ao_ranges[it->options[7]]
- : &range_unknown;
- s->insn_write = rti800_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- s = &dev->subdevices[2];
- /* di */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->insn_bits = rti800_di_insn_bits;
- s->maxdata = 1;
- s->range_table = &range_digital;
-
- s = &dev->subdevices[3];
- /* do */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->insn_bits = rti800_do_insn_bits;
- s->maxdata = 1;
- s->range_table = &range_digital;
-
- /*
- * There is also an Am9513 timer on these boards. This subdevice
- * is not currently supported.
- */
-
- return 0;
-}
-
-static struct comedi_driver rti800_driver = {
- .driver_name = "rti800",
- .module = THIS_MODULE,
- .attach = rti800_attach,
- .detach = comedi_legacy_detach,
- .num_names = ARRAY_SIZE(rti800_boardtypes),
- .board_name = &rti800_boardtypes[0].name,
- .offset = sizeof(struct rti800_board),
-};
-module_comedi_driver(rti800_driver);
-
-MODULE_DESCRIPTION("Comedi: RTI-800 Multifunction Analog/Digital board");
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
deleted file mode 100644
index 195e2b1ac4c1..000000000000
--- a/drivers/staging/comedi/drivers/rti802.c
+++ /dev/null
@@ -1,120 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * rti802.c
- * Comedi driver for Analog Devices RTI-802 board
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
- */
-
-/*
- * Driver: rti802
- * Description: Analog Devices RTI-802
- * Author: Anders Blomdell <anders.blomdell@control.lth.se>
- * Devices: [Analog Devices] RTI-802 (rti802)
- * Status: works
- *
- * Configuration Options:
- * [0] - i/o base
- * [1] - unused
- * [2,4,6,8,10,12,14,16] - dac#[0-7] 0=two's comp, 1=straight
- * [3,5,7,9,11,13,15,17] - dac#[0-7] 0=bipolar, 1=unipolar
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-/*
- * Register I/O map
- */
-#define RTI802_SELECT 0x00
-#define RTI802_DATALOW 0x01
-#define RTI802_DATAHIGH 0x02
-
-struct rti802_private {
- enum {
- dac_2comp, dac_straight
- } dac_coding[8];
- const struct comedi_lrange *range_type_list[8];
-};
-
-static int rti802_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct rti802_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- outb(chan, dev->iobase + RTI802_SELECT);
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- s->readback[chan] = val;
-
- /* munge offset binary to two's complement if needed */
- if (devpriv->dac_coding[chan] == dac_2comp)
- val = comedi_offset_munge(s, val);
-
- outb(val & 0xff, dev->iobase + RTI802_DATALOW);
- outb((val >> 8) & 0xff, dev->iobase + RTI802_DATAHIGH);
- }
-
- return insn->n;
-}
-
-static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct rti802_private *devpriv;
- struct comedi_subdevice *s;
- int i;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x04);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->maxdata = 0xfff;
- s->n_chan = 8;
- s->insn_write = rti802_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s->range_table_list = devpriv->range_type_list;
- for (i = 0; i < 8; i++) {
- devpriv->dac_coding[i] = (it->options[3 + 2 * i])
- ? (dac_straight) : (dac_2comp);
- devpriv->range_type_list[i] = (it->options[2 + 2 * i])
- ? &range_unipolar10 : &range_bipolar10;
- }
-
- return 0;
-}
-
-static struct comedi_driver rti802_driver = {
- .driver_name = "rti802",
- .module = THIS_MODULE,
- .attach = rti802_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(rti802_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi driver for Analog Devices RTI-802 board");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
deleted file mode 100644
index 085cf5b449e5..000000000000
--- a/drivers/staging/comedi/drivers/s526.c
+++ /dev/null
@@ -1,629 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * s526.c
- * Sensoray s526 Comedi driver
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: s526
- * Description: Sensoray 526 driver
- * Devices: [Sensoray] 526 (s526)
- * Author: Richie
- * Everett Wang <everett.wang@everteq.com>
- * Updated: Thu, 14 Sep. 2006
- * Status: experimental
- *
- * Encoder works
- * Analog input works
- * Analog output works
- * PWM output works
- * Commands are not supported yet.
- *
- * Configuration Options:
- * [0] - I/O port base address
- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-/*
- * Register I/O map
- */
-#define S526_TIMER_REG 0x00
-#define S526_TIMER_LOAD(x) (((x) & 0xff) << 8)
-#define S526_TIMER_MODE ((x) << 1)
-#define S526_TIMER_MANUAL S526_TIMER_MODE(0)
-#define S526_TIMER_AUTO S526_TIMER_MODE(1)
-#define S526_TIMER_RESTART BIT(0)
-#define S526_WDOG_REG 0x02
-#define S526_WDOG_INVERTED BIT(4)
-#define S526_WDOG_ENA BIT(3)
-#define S526_WDOG_INTERVAL(x) (((x) & 0x7) << 0)
-#define S526_AO_CTRL_REG 0x04
-#define S526_AO_CTRL_RESET BIT(3)
-#define S526_AO_CTRL_CHAN(x) (((x) & 0x3) << 1)
-#define S526_AO_CTRL_START BIT(0)
-#define S526_AI_CTRL_REG 0x06
-#define S526_AI_CTRL_DELAY BIT(15)
-#define S526_AI_CTRL_CONV(x) (1 << (5 + ((x) & 0x9)))
-#define S526_AI_CTRL_READ(x) (((x) & 0xf) << 1)
-#define S526_AI_CTRL_START BIT(0)
-#define S526_AO_REG 0x08
-#define S526_AI_REG 0x08
-#define S526_DIO_CTRL_REG 0x0a
-#define S526_DIO_CTRL_DIO3_NEG BIT(15) /* irq on DIO3 neg/pos edge */
-#define S526_DIO_CTRL_DIO2_NEG BIT(14) /* irq on DIO2 neg/pos edge */
-#define S526_DIO_CTRL_DIO1_NEG BIT(13) /* irq on DIO1 neg/pos edge */
-#define S526_DIO_CTRL_DIO0_NEG BIT(12) /* irq on DIO0 neg/pos edge */
-#define S526_DIO_CTRL_GRP2_OUT BIT(11)
-#define S526_DIO_CTRL_GRP1_OUT BIT(10)
-#define S526_DIO_CTRL_GRP2_NEG BIT(8) /* irq on DIO[4-7] neg/pos edge */
-#define S526_INT_ENA_REG 0x0c
-#define S526_INT_STATUS_REG 0x0e
-#define S526_INT_DIO(x) BIT(8 + ((x) & 0x7))
-#define S526_INT_EEPROM BIT(7) /* status only */
-#define S526_INT_CNTR(x) BIT(3 + (3 - ((x) & 0x3)))
-#define S526_INT_AI BIT(2)
-#define S526_INT_AO BIT(1)
-#define S526_INT_TIMER BIT(0)
-#define S526_MISC_REG 0x10
-#define S526_MISC_LED_OFF BIT(0)
-#define S526_GPCT_LSB_REG(x) (0x12 + ((x) * 8))
-#define S526_GPCT_MSB_REG(x) (0x14 + ((x) * 8))
-#define S526_GPCT_MODE_REG(x) (0x16 + ((x) * 8))
-#define S526_GPCT_MODE_COUT_SRC(x) ((x) << 0)
-#define S526_GPCT_MODE_COUT_SRC_MASK S526_GPCT_MODE_COUT_SRC(0x1)
-#define S526_GPCT_MODE_COUT_SRC_RCAP S526_GPCT_MODE_COUT_SRC(0)
-#define S526_GPCT_MODE_COUT_SRC_RTGL S526_GPCT_MODE_COUT_SRC(1)
-#define S526_GPCT_MODE_COUT_POL(x) ((x) << 1)
-#define S526_GPCT_MODE_COUT_POL_MASK S526_GPCT_MODE_COUT_POL(0x1)
-#define S526_GPCT_MODE_COUT_POL_NORM S526_GPCT_MODE_COUT_POL(0)
-#define S526_GPCT_MODE_COUT_POL_INV S526_GPCT_MODE_COUT_POL(1)
-#define S526_GPCT_MODE_AUTOLOAD(x) ((x) << 2)
-#define S526_GPCT_MODE_AUTOLOAD_MASK S526_GPCT_MODE_AUTOLOAD(0x7)
-#define S526_GPCT_MODE_AUTOLOAD_NONE S526_GPCT_MODE_AUTOLOAD(0)
-/* these 3 bits can be OR'ed */
-#define S526_GPCT_MODE_AUTOLOAD_RO S526_GPCT_MODE_AUTOLOAD(0x1)
-#define S526_GPCT_MODE_AUTOLOAD_IXFALL S526_GPCT_MODE_AUTOLOAD(0x2)
-#define S526_GPCT_MODE_AUTOLOAD_IXRISE S526_GPCT_MODE_AUTOLOAD(0x4)
-#define S526_GPCT_MODE_HWCTEN_SRC(x) ((x) << 5)
-#define S526_GPCT_MODE_HWCTEN_SRC_MASK S526_GPCT_MODE_HWCTEN_SRC(0x3)
-#define S526_GPCT_MODE_HWCTEN_SRC_CEN S526_GPCT_MODE_HWCTEN_SRC(0)
-#define S526_GPCT_MODE_HWCTEN_SRC_IX S526_GPCT_MODE_HWCTEN_SRC(1)
-#define S526_GPCT_MODE_HWCTEN_SRC_IXRF S526_GPCT_MODE_HWCTEN_SRC(2)
-#define S526_GPCT_MODE_HWCTEN_SRC_NRCAP S526_GPCT_MODE_HWCTEN_SRC(3)
-#define S526_GPCT_MODE_CTEN_CTRL(x) ((x) << 7)
-#define S526_GPCT_MODE_CTEN_CTRL_MASK S526_GPCT_MODE_CTEN_CTRL(0x3)
-#define S526_GPCT_MODE_CTEN_CTRL_DIS S526_GPCT_MODE_CTEN_CTRL(0)
-#define S526_GPCT_MODE_CTEN_CTRL_ENA S526_GPCT_MODE_CTEN_CTRL(1)
-#define S526_GPCT_MODE_CTEN_CTRL_HW S526_GPCT_MODE_CTEN_CTRL(2)
-#define S526_GPCT_MODE_CTEN_CTRL_INVHW S526_GPCT_MODE_CTEN_CTRL(3)
-#define S526_GPCT_MODE_CLK_SRC(x) ((x) << 9)
-#define S526_GPCT_MODE_CLK_SRC_MASK S526_GPCT_MODE_CLK_SRC(0x3)
-/* if count direction control set to quadrature */
-#define S526_GPCT_MODE_CLK_SRC_QUADX1 S526_GPCT_MODE_CLK_SRC(0)
-#define S526_GPCT_MODE_CLK_SRC_QUADX2 S526_GPCT_MODE_CLK_SRC(1)
-#define S526_GPCT_MODE_CLK_SRC_QUADX4 S526_GPCT_MODE_CLK_SRC(2)
-#define S526_GPCT_MODE_CLK_SRC_QUADX4_ S526_GPCT_MODE_CLK_SRC(3)
-/* if count direction control set to software control */
-#define S526_GPCT_MODE_CLK_SRC_ARISE S526_GPCT_MODE_CLK_SRC(0)
-#define S526_GPCT_MODE_CLK_SRC_AFALL S526_GPCT_MODE_CLK_SRC(1)
-#define S526_GPCT_MODE_CLK_SRC_INT S526_GPCT_MODE_CLK_SRC(2)
-#define S526_GPCT_MODE_CLK_SRC_INTHALF S526_GPCT_MODE_CLK_SRC(3)
-#define S526_GPCT_MODE_CT_DIR(x) ((x) << 11)
-#define S526_GPCT_MODE_CT_DIR_MASK S526_GPCT_MODE_CT_DIR(0x1)
-/* if count direction control set to software control */
-#define S526_GPCT_MODE_CT_DIR_UP S526_GPCT_MODE_CT_DIR(0)
-#define S526_GPCT_MODE_CT_DIR_DOWN S526_GPCT_MODE_CT_DIR(1)
-#define S526_GPCT_MODE_CTDIR_CTRL(x) ((x) << 12)
-#define S526_GPCT_MODE_CTDIR_CTRL_MASK S526_GPCT_MODE_CTDIR_CTRL(0x1)
-#define S526_GPCT_MODE_CTDIR_CTRL_QUAD S526_GPCT_MODE_CTDIR_CTRL(0)
-#define S526_GPCT_MODE_CTDIR_CTRL_SOFT S526_GPCT_MODE_CTDIR_CTRL(1)
-#define S526_GPCT_MODE_LATCH_CTRL(x) ((x) << 13)
-#define S526_GPCT_MODE_LATCH_CTRL_MASK S526_GPCT_MODE_LATCH_CTRL(0x1)
-#define S526_GPCT_MODE_LATCH_CTRL_READ S526_GPCT_MODE_LATCH_CTRL(0)
-#define S526_GPCT_MODE_LATCH_CTRL_EVENT S526_GPCT_MODE_LATCH_CTRL(1)
-#define S526_GPCT_MODE_PR_SELECT(x) ((x) << 14)
-#define S526_GPCT_MODE_PR_SELECT_MASK S526_GPCT_MODE_PR_SELECT(0x1)
-#define S526_GPCT_MODE_PR_SELECT_PR0 S526_GPCT_MODE_PR_SELECT(0)
-#define S526_GPCT_MODE_PR_SELECT_PR1 S526_GPCT_MODE_PR_SELECT(1)
-/* Control/Status - R = readable, W = writeable, C = write 1 to clear */
-#define S526_GPCT_CTRL_REG(x) (0x18 + ((x) * 8))
-#define S526_GPCT_CTRL_EV_STATUS(x) ((x) << 0) /* RC */
-#define S526_GPCT_CTRL_EV_STATUS_MASK S526_GPCT_EV_STATUS(0xf)
-#define S526_GPCT_CTRL_EV_STATUS_NONE S526_GPCT_EV_STATUS(0)
-/* these 4 bits can be OR'ed */
-#define S526_GPCT_CTRL_EV_STATUS_ECAP S526_GPCT_EV_STATUS(0x1)
-#define S526_GPCT_CTRL_EV_STATUS_ICAPN S526_GPCT_EV_STATUS(0x2)
-#define S526_GPCT_CTRL_EV_STATUS_ICAPP S526_GPCT_EV_STATUS(0x4)
-#define S526_GPCT_CTRL_EV_STATUS_RCAP S526_GPCT_EV_STATUS(0x8)
-#define S526_GPCT_CTRL_COUT_STATUS BIT(4) /* R */
-#define S526_GPCT_CTRL_INDEX_STATUS BIT(5) /* R */
-#define S525_GPCT_CTRL_INTEN(x) ((x) << 6) /* W */
-#define S525_GPCT_CTRL_INTEN_MASK S526_GPCT_CTRL_INTEN(0xf)
-#define S525_GPCT_CTRL_INTEN_NONE S526_GPCT_CTRL_INTEN(0)
-/* these 4 bits can be OR'ed */
-#define S525_GPCT_CTRL_INTEN_ERROR S526_GPCT_CTRL_INTEN(0x1)
-#define S525_GPCT_CTRL_INTEN_IXFALL S526_GPCT_CTRL_INTEN(0x2)
-#define S525_GPCT_CTRL_INTEN_IXRISE S526_GPCT_CTRL_INTEN(0x4)
-#define S525_GPCT_CTRL_INTEN_RO S526_GPCT_CTRL_INTEN(0x8)
-#define S525_GPCT_CTRL_LATCH_SEL(x) ((x) << 10) /* W */
-#define S525_GPCT_CTRL_LATCH_SEL_MASK S526_GPCT_CTRL_LATCH_SEL(0x7)
-#define S525_GPCT_CTRL_LATCH_SEL_NONE S526_GPCT_CTRL_LATCH_SEL(0)
-/* these 3 bits can be OR'ed */
-#define S525_GPCT_CTRL_LATCH_SEL_IXFALL S526_GPCT_CTRL_LATCH_SEL(0x1)
-#define S525_GPCT_CTRL_LATCH_SEL_IXRISE S526_GPCT_CTRL_LATCH_SEL(0x2)
-#define S525_GPCT_CTRL_LATCH_SEL_ITIMER S526_GPCT_CTRL_LATCH_SEL(0x4)
-#define S525_GPCT_CTRL_CT_ARM BIT(13) /* W */
-#define S525_GPCT_CTRL_CT_LOAD BIT(14) /* W */
-#define S526_GPCT_CTRL_CT_RESET BIT(15) /* W */
-#define S526_EEPROM_DATA_REG 0x32
-#define S526_EEPROM_CTRL_REG 0x34
-#define S526_EEPROM_CTRL_ADDR(x) (((x) & 0x3f) << 3)
-#define S526_EEPROM_CTRL(x) (((x) & 0x3) << 1)
-#define S526_EEPROM_CTRL_READ S526_EEPROM_CTRL(2)
-#define S526_EEPROM_CTRL_START BIT(0)
-
-struct s526_private {
- unsigned int gpct_config[4];
- unsigned short ai_ctrl;
-};
-
-static void s526_gpct_write(struct comedi_device *dev,
- unsigned int chan, unsigned int val)
-{
- /* write high word then low word */
- outw((val >> 16) & 0xffff, dev->iobase + S526_GPCT_MSB_REG(chan));
- outw(val & 0xffff, dev->iobase + S526_GPCT_LSB_REG(chan));
-}
-
-static unsigned int s526_gpct_read(struct comedi_device *dev,
- unsigned int chan)
-{
- unsigned int val;
-
- /* read the low word then high word */
- val = inw(dev->iobase + S526_GPCT_LSB_REG(chan)) & 0xffff;
- val |= (inw(dev->iobase + S526_GPCT_MSB_REG(chan)) & 0xff) << 16;
-
- return val;
-}
-
-static int s526_gpct_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++)
- data[i] = s526_gpct_read(dev, chan);
-
- return insn->n;
-}
-
-static int s526_gpct_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct s526_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int val;
-
- /*
- * Check what type of Counter the user requested
- * data[0] contains the Application type
- */
- switch (data[0]) {
- case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
- /*
- * data[0]: Application Type
- * data[1]: Counter Mode Register Value
- * data[2]: Pre-load Register Value
- * data[3]: Conter Control Register
- */
- devpriv->gpct_config[chan] = data[0];
-
-#if 1
- /* Set Counter Mode Register */
- val = data[1] & 0xffff;
- outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
-
- /* Reset the counter if it is software preload */
- if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) ==
- S526_GPCT_MODE_AUTOLOAD_NONE) {
- /* Reset the counter */
- outw(S526_GPCT_CTRL_CT_RESET,
- dev->iobase + S526_GPCT_CTRL_REG(chan));
- /*
- * Load the counter from PR0
- * outw(S526_GPCT_CTRL_CT_LOAD,
- * dev->iobase + S526_GPCT_CTRL_REG(chan));
- */
- }
-#else
- val = S526_GPCT_MODE_CTDIR_CTRL_QUAD;
-
- /* data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4 */
- if (data[1] == GPCT_X2)
- val |= S526_GPCT_MODE_CLK_SRC_QUADX2;
- else if (data[1] == GPCT_X4)
- val |= S526_GPCT_MODE_CLK_SRC_QUADX4;
- else
- val |= S526_GPCT_MODE_CLK_SRC_QUADX1;
-
- /* When to take into account the indexpulse: */
- /*
- * if (data[2] == GPCT_IndexPhaseLowLow) {
- * } else if (data[2] == GPCT_IndexPhaseLowHigh) {
- * } else if (data[2] == GPCT_IndexPhaseHighLow) {
- * } else if (data[2] == GPCT_IndexPhaseHighHigh) {
- * }
- */
- /* Take into account the index pulse? */
- if (data[3] == GPCT_RESET_COUNTER_ON_INDEX) {
- /* Auto load with INDEX^ */
- val |= S526_GPCT_MODE_AUTOLOAD_IXRISE;
- }
-
- /* Set Counter Mode Register */
- val = data[1] & 0xffff;
- outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
-
- /* Load the pre-load register */
- s526_gpct_write(dev, chan, data[2]);
-
- /* Write the Counter Control Register */
- if (data[3])
- outw(data[3] & 0xffff,
- dev->iobase + S526_GPCT_CTRL_REG(chan));
-
- /* Reset the counter if it is software preload */
- if ((val & S526_GPCT_MODE_AUTOLOAD_MASK) ==
- S526_GPCT_MODE_AUTOLOAD_NONE) {
- /* Reset the counter */
- outw(S526_GPCT_CTRL_CT_RESET,
- dev->iobase + S526_GPCT_CTRL_REG(chan));
- /* Load the counter from PR0 */
- outw(S526_GPCT_CTRL_CT_LOAD,
- dev->iobase + S526_GPCT_CTRL_REG(chan));
- }
-#endif
- break;
-
- case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
- /*
- * data[0]: Application Type
- * data[1]: Counter Mode Register Value
- * data[2]: Pre-load Register 0 Value
- * data[3]: Pre-load Register 1 Value
- * data[4]: Conter Control Register
- */
- devpriv->gpct_config[chan] = data[0];
-
- /* Set Counter Mode Register */
- val = data[1] & 0xffff;
- /* Select PR0 */
- val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
- val |= S526_GPCT_MODE_PR_SELECT_PR0;
- outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
-
- /* Load the pre-load register 0 */
- s526_gpct_write(dev, chan, data[2]);
-
- /* Set Counter Mode Register */
- val = data[1] & 0xffff;
- /* Select PR1 */
- val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
- val |= S526_GPCT_MODE_PR_SELECT_PR1;
- outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
-
- /* Load the pre-load register 1 */
- s526_gpct_write(dev, chan, data[3]);
-
- /* Write the Counter Control Register */
- if (data[4]) {
- val = data[4] & 0xffff;
- outw(val, dev->iobase + S526_GPCT_CTRL_REG(chan));
- }
- break;
-
- case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
- /*
- * data[0]: Application Type
- * data[1]: Counter Mode Register Value
- * data[2]: Pre-load Register 0 Value
- * data[3]: Pre-load Register 1 Value
- * data[4]: Conter Control Register
- */
- devpriv->gpct_config[chan] = data[0];
-
- /* Set Counter Mode Register */
- val = data[1] & 0xffff;
- /* Select PR0 */
- val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
- val |= S526_GPCT_MODE_PR_SELECT_PR0;
- outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
-
- /* Load the pre-load register 0 */
- s526_gpct_write(dev, chan, data[2]);
-
- /* Set Counter Mode Register */
- val = data[1] & 0xffff;
- /* Select PR1 */
- val &= ~S526_GPCT_MODE_PR_SELECT_MASK;
- val |= S526_GPCT_MODE_PR_SELECT_PR1;
- outw(val, dev->iobase + S526_GPCT_MODE_REG(chan));
-
- /* Load the pre-load register 1 */
- s526_gpct_write(dev, chan, data[3]);
-
- /* Write the Counter Control Register */
- if (data[4]) {
- val = data[4] & 0xffff;
- outw(val, dev->iobase + S526_GPCT_CTRL_REG(chan));
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int s526_gpct_winsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct s526_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- inw(dev->iobase + S526_GPCT_MODE_REG(chan)); /* Is this required? */
-
- /* Check what Application of Counter this channel is configured for */
- switch (devpriv->gpct_config[chan]) {
- case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
- /*
- * data[0] contains the PULSE_WIDTH
- * data[1] contains the PULSE_PERIOD
- * @pre PULSE_PERIOD > PULSE_WIDTH > 0
- * The above periods must be expressed as a multiple of the
- * pulse frequency on the selected source
- */
- if ((data[1] <= data[0]) || !data[0])
- return -EINVAL;
- /* to write the PULSE_WIDTH */
- fallthrough;
- case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
- case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
- s526_gpct_write(dev, chan, data[0]);
- break;
-
- default:
- return -EINVAL;
- }
-
- return insn->n;
-}
-
-static int s526_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = inw(dev->iobase + S526_INT_STATUS_REG);
- if (status & context) {
- /* we got our eoc event, clear it */
- outw(context, dev->iobase + S526_INT_STATUS_REG);
- return 0;
- }
- return -EBUSY;
-}
-
-static int s526_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct s526_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int ctrl;
- unsigned int val;
- int ret;
- int i;
-
- ctrl = S526_AI_CTRL_CONV(chan) | S526_AI_CTRL_READ(chan) |
- S526_AI_CTRL_START;
- if (ctrl != devpriv->ai_ctrl) {
- /*
- * The multiplexor needs to change, enable the 15us
- * delay for the first sample.
- */
- devpriv->ai_ctrl = ctrl;
- ctrl |= S526_AI_CTRL_DELAY;
- }
-
- for (i = 0; i < insn->n; i++) {
- /* trigger conversion */
- outw(ctrl, dev->iobase + S526_AI_CTRL_REG);
- ctrl &= ~S526_AI_CTRL_DELAY;
-
- /* wait for conversion to end */
- ret = comedi_timeout(dev, s, insn, s526_eoc, S526_INT_AI);
- if (ret)
- return ret;
-
- val = inw(dev->iobase + S526_AI_REG);
- data[i] = comedi_offset_munge(s, val);
- }
-
- return insn->n;
-}
-
-static int s526_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int ctrl = S526_AO_CTRL_CHAN(chan);
- unsigned int val = s->readback[chan];
- int ret;
- int i;
-
- outw(ctrl, dev->iobase + S526_AO_CTRL_REG);
- ctrl |= S526_AO_CTRL_START;
-
- for (i = 0; i < insn->n; i++) {
- val = data[i];
- outw(val, dev->iobase + S526_AO_REG);
- outw(ctrl, dev->iobase + S526_AO_CTRL_REG);
-
- /* wait for conversion to end */
- ret = comedi_timeout(dev, s, insn, s526_eoc, S526_INT_AO);
- if (ret)
- return ret;
- }
- s->readback[chan] = val;
-
- return insn->n;
-}
-
-static int s526_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + S526_DIO_CTRL_REG);
-
- data[1] = inw(dev->iobase + S526_DIO_CTRL_REG) & 0xff;
-
- return insn->n;
-}
-
-static int s526_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- int ret;
-
- /*
- * Digital I/O can be configured as inputs or outputs in
- * groups of 4; DIO group 1 (DIO0-3) and DIO group 2 (DIO4-7).
- */
- if (chan < 4)
- mask = 0x0f;
- else
- mask = 0xf0;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, mask);
- if (ret)
- return ret;
-
- if (s->io_bits & 0x0f)
- s->state |= S526_DIO_CTRL_GRP1_OUT;
- else
- s->state &= ~S526_DIO_CTRL_GRP1_OUT;
- if (s->io_bits & 0xf0)
- s->state |= S526_DIO_CTRL_GRP2_OUT;
- else
- s->state &= ~S526_DIO_CTRL_GRP2_OUT;
-
- outw(s->state, dev->iobase + S526_DIO_CTRL_REG);
-
- return insn->n;
-}
-
-static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct s526_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- ret = comedi_request_region(dev, it->options[0], 0x40);
- if (ret)
- return ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
- /* General-Purpose Counter/Timer (GPCT) */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
- s->n_chan = 4;
- s->maxdata = 0x00ffffff;
- s->insn_read = s526_gpct_rinsn;
- s->insn_config = s526_gpct_insn_config;
- s->insn_write = s526_gpct_winsn;
-
- /*
- * Analog Input subdevice
- * channels 0 to 7 are the regular differential inputs
- * channel 8 is "reference 0" (+10V)
- * channel 9 is "reference 1" (0V)
- */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF;
- s->n_chan = 10;
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar10;
- s->len_chanlist = 16;
- s->insn_read = s526_ai_insn_read;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->range_table = &range_bipolar10;
- s->insn_write = s526_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = s526_dio_insn_bits;
- s->insn_config = s526_dio_insn_config;
-
- return 0;
-}
-
-static struct comedi_driver s526_driver = {
- .driver_name = "s526",
- .module = THIS_MODULE,
- .attach = s526_attach,
- .detach = comedi_legacy_detach,
-};
-module_comedi_driver(s526_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
deleted file mode 100644
index e7aba937d896..000000000000
--- a/drivers/staging/comedi/drivers/s626.c
+++ /dev/null
@@ -1,2605 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/drivers/s626.c
- * Sensoray s626 Comedi driver
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- *
- * Based on Sensoray Model 626 Linux driver Version 0.2
- * Copyright (C) 2002-2004 Sensoray Co., Inc.
- */
-
-/*
- * Driver: s626
- * Description: Sensoray 626 driver
- * Devices: [Sensoray] 626 (s626)
- * Authors: Gianluca Palli <gpalli@deis.unibo.it>,
- * Updated: Fri, 15 Feb 2008 10:28:42 +0000
- * Status: experimental
-
- * Configuration options: not applicable, uses PCI auto config
-
- * INSN_CONFIG instructions:
- * analog input:
- * none
- *
- * analog output:
- * none
- *
- * digital channel:
- * s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
- * supported configuration options:
- * INSN_CONFIG_DIO_QUERY
- * COMEDI_INPUT
- * COMEDI_OUTPUT
- *
- * encoder:
- * Every channel must be configured before reading.
- *
- * Example code
- *
- * insn.insn=INSN_CONFIG; //configuration instruction
- * insn.n=1; //number of operation (must be 1)
- * insn.data=&initialvalue; //initial value loaded into encoder
- * //during configuration
- * insn.subdev=5; //encoder subdevice
- * insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
- * //to configure
- *
- * comedi_do_insn(cf,&insn); //executing configuration
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include "../comedi_pci.h"
-
-#include "s626.h"
-
-struct s626_buffer_dma {
- dma_addr_t physical_base;
- void *logical_base;
-};
-
-/**
- * struct s626_private - Working data for s626 driver.
- * @ai_cmd_running: non-zero if ai_cmd is running.
- * @ai_sample_timer: time between samples in units of the timer.
- * @ai_convert_count: conversion counter.
- * @ai_convert_timer: time between conversion in units of the timer.
- * @counter_int_enabs: counter interrupt enable mask for MISC2 register.
- * @adc_items: number of items in ADC poll list.
- * @rps_buf: DMA buffer used to hold ADC (RPS1) program.
- * @ana_buf: DMA buffer used to receive ADC data and hold DAC data.
- * @dac_wbuf: pointer to logical adrs of DMA buffer used to hold DAC data.
- * @dacpol: image of DAC polarity register.
- * @trim_setpoint: images of TrimDAC setpoints.
- * @i2c_adrs: I2C device address for onboard EEPROM (board rev dependent)
- */
-struct s626_private {
- u8 ai_cmd_running;
- unsigned int ai_sample_timer;
- int ai_convert_count;
- unsigned int ai_convert_timer;
- u16 counter_int_enabs;
- u8 adc_items;
- struct s626_buffer_dma rps_buf;
- struct s626_buffer_dma ana_buf;
- u32 *dac_wbuf;
- u16 dacpol;
- u8 trim_setpoint[12];
- u32 i2c_adrs;
-};
-
-/* Counter overflow/index event flag masks for RDMISC2. */
-#define S626_INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4)))
-#define S626_OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
-
-/*
- * Enable/disable a function or test status bit(s) that are accessed
- * through Main Control Registers 1 or 2.
- */
-static void s626_mc_enable(struct comedi_device *dev,
- unsigned int cmd, unsigned int reg)
-{
- unsigned int val = (cmd << 16) | cmd;
-
- writel(val, dev->mmio + reg);
-}
-
-static void s626_mc_disable(struct comedi_device *dev,
- unsigned int cmd, unsigned int reg)
-{
- writel(cmd << 16, dev->mmio + reg);
-}
-
-static bool s626_mc_test(struct comedi_device *dev,
- unsigned int cmd, unsigned int reg)
-{
- unsigned int val;
-
- val = readl(dev->mmio + reg);
-
- return (val & cmd) ? true : false;
-}
-
-#define S626_BUGFIX_STREG(REGADRS) ((REGADRS) - 4)
-
-/* Write a time slot control record to TSL2. */
-#define S626_VECTPORT(VECTNUM) (S626_P_TSL2 + ((VECTNUM) << 2))
-
-static const struct comedi_lrange s626_range_table = {
- 2, {
- BIP_RANGE(5),
- BIP_RANGE(10)
- }
-};
-
-/*
- * Execute a DEBI transfer. This must be called from within a critical section.
- */
-static void s626_debi_transfer(struct comedi_device *dev)
-{
- static const int timeout = 10000;
- int i;
-
- /* Initiate upload of shadow RAM to DEBI control register */
- s626_mc_enable(dev, S626_MC2_UPLD_DEBI, S626_P_MC2);
-
- /*
- * Wait for completion of upload from shadow RAM to
- * DEBI control register.
- */
- for (i = 0; i < timeout; i++) {
- if (s626_mc_test(dev, S626_MC2_UPLD_DEBI, S626_P_MC2))
- break;
- udelay(1);
- }
- if (i == timeout)
- dev_err(dev->class_dev,
- "Timeout while uploading to DEBI control register\n");
-
- /* Wait until DEBI transfer is done */
- for (i = 0; i < timeout; i++) {
- if (!(readl(dev->mmio + S626_P_PSR) & S626_PSR_DEBI_S))
- break;
- udelay(1);
- }
- if (i == timeout)
- dev_err(dev->class_dev, "DEBI transfer timeout\n");
-}
-
-/*
- * Read a value from a gate array register.
- */
-static u16 s626_debi_read(struct comedi_device *dev, u16 addr)
-{
- /* Set up DEBI control register value in shadow RAM */
- writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD);
-
- /* Execute the DEBI transfer. */
- s626_debi_transfer(dev);
-
- return readl(dev->mmio + S626_P_DEBIAD);
-}
-
-/*
- * Write a value to a gate array register.
- */
-static void s626_debi_write(struct comedi_device *dev, u16 addr,
- u16 wdata)
-{
- /* Set up DEBI control register value in shadow RAM */
- writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD);
- writel(wdata, dev->mmio + S626_P_DEBIAD);
-
- /* Execute the DEBI transfer. */
- s626_debi_transfer(dev);
-}
-
-/*
- * Replace the specified bits in a gate array register. Imports: mask
- * specifies bits that are to be preserved, wdata is new value to be
- * or'd with the masked original.
- */
-static void s626_debi_replace(struct comedi_device *dev, unsigned int addr,
- unsigned int mask, unsigned int wdata)
-{
- unsigned int val;
-
- addr &= 0xffff;
- writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD);
- s626_debi_transfer(dev);
-
- writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD);
- val = readl(dev->mmio + S626_P_DEBIAD);
- val &= mask;
- val |= wdata;
- writel(val & 0xffff, dev->mmio + S626_P_DEBIAD);
- s626_debi_transfer(dev);
-}
-
-/* ************** EEPROM ACCESS FUNCTIONS ************** */
-
-static int s626_i2c_handshake_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- bool status;
-
- status = s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- if (status)
- return 0;
- return -EBUSY;
-}
-
-static int s626_i2c_handshake(struct comedi_device *dev, u32 val)
-{
- unsigned int ctrl;
- int ret;
-
- /* Write I2C command to I2C Transfer Control shadow register */
- writel(val, dev->mmio + S626_P_I2CCTRL);
-
- /*
- * Upload I2C shadow registers into working registers and
- * wait for upload confirmation.
- */
- s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
- if (ret)
- return ret;
-
- /* Wait until I2C bus transfer is finished or an error occurs */
- do {
- ctrl = readl(dev->mmio + S626_P_I2CCTRL);
- } while ((ctrl & (S626_I2C_BUSY | S626_I2C_ERR)) == S626_I2C_BUSY);
-
- /* Return non-zero if I2C error occurred */
- return ctrl & S626_I2C_ERR;
-}
-
-/* Read u8 from EEPROM. */
-static u8 s626_i2c_read(struct comedi_device *dev, u8 addr)
-{
- struct s626_private *devpriv = dev->private;
-
- /*
- * Send EEPROM target address:
- * Byte2 = I2C command: write to I2C EEPROM device.
- * Byte1 = EEPROM internal target address.
- * Byte0 = Not sent.
- */
- if (s626_i2c_handshake(dev, S626_I2C_B2(S626_I2C_ATTRSTART,
- devpriv->i2c_adrs) |
- S626_I2C_B1(S626_I2C_ATTRSTOP, addr) |
- S626_I2C_B0(S626_I2C_ATTRNOP, 0)))
- /* Abort function and declare error if handshake failed. */
- return 0;
-
- /*
- * Execute EEPROM read:
- * Byte2 = I2C command: read from I2C EEPROM device.
- * Byte1 receives uint8_t from EEPROM.
- * Byte0 = Not sent.
- */
- if (s626_i2c_handshake(dev, S626_I2C_B2(S626_I2C_ATTRSTART,
- (devpriv->i2c_adrs | 1)) |
- S626_I2C_B1(S626_I2C_ATTRSTOP, 0) |
- S626_I2C_B0(S626_I2C_ATTRNOP, 0)))
- /* Abort function and declare error if handshake failed. */
- return 0;
-
- return (readl(dev->mmio + S626_P_I2CCTRL) >> 16) & 0xff;
-}
-
-/* *********** DAC FUNCTIONS *********** */
-
-/* TrimDac LogicalChan-to-PhysicalChan mapping table. */
-static const u8 s626_trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
-
-/* TrimDac LogicalChan-to-EepromAdrs mapping table. */
-static const u8 s626_trimadrs[] = {
- 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63
-};
-
-enum {
- s626_send_dac_wait_not_mc1_a2out,
- s626_send_dac_wait_ssr_af2_out,
- s626_send_dac_wait_fb_buffer2_msb_00,
- s626_send_dac_wait_fb_buffer2_msb_ff
-};
-
-static int s626_send_dac_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- switch (context) {
- case s626_send_dac_wait_not_mc1_a2out:
- status = readl(dev->mmio + S626_P_MC1);
- if (!(status & S626_MC1_A2OUT))
- return 0;
- break;
- case s626_send_dac_wait_ssr_af2_out:
- status = readl(dev->mmio + S626_P_SSR);
- if (status & S626_SSR_AF2_OUT)
- return 0;
- break;
- case s626_send_dac_wait_fb_buffer2_msb_00:
- status = readl(dev->mmio + S626_P_FB_BUFFER2);
- if (!(status & 0xff000000))
- return 0;
- break;
- case s626_send_dac_wait_fb_buffer2_msb_ff:
- status = readl(dev->mmio + S626_P_FB_BUFFER2);
- if (status & 0xff000000)
- return 0;
- break;
- default:
- return -EINVAL;
- }
- return -EBUSY;
-}
-
-/*
- * Private helper function: Transmit serial data to DAC via Audio
- * channel 2. Assumes: (1) TSL2 slot records initialized, and (2)
- * dacpol contains valid target image.
- */
-static int s626_send_dac(struct comedi_device *dev, u32 val)
-{
- struct s626_private *devpriv = dev->private;
- int ret;
-
- /* START THE SERIAL CLOCK RUNNING ------------- */
-
- /*
- * Assert DAC polarity control and enable gating of DAC serial clock
- * and audio bit stream signals. At this point in time we must be
- * assured of being in time slot 0. If we are not in slot 0, the
- * serial clock and audio stream signals will be disabled; this is
- * because the following s626_debi_write statement (which enables
- * signals to be passed through the gate array) would execute before
- * the trailing edge of WS1/WS3 (which turns off the signals), thus
- * causing the signals to be inactive during the DAC write.
- */
- s626_debi_write(dev, S626_LP_DACPOL, devpriv->dacpol);
-
- /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
-
- /* Copy DAC setpoint value to DAC's output DMA buffer. */
- /* writel(val, dev->mmio + (uint32_t)devpriv->dac_wbuf); */
- *devpriv->dac_wbuf = val;
-
- /*
- * Enable the output DMA transfer. This will cause the DMAC to copy
- * the DAC's data value to A2's output FIFO. The DMA transfer will
- * then immediately terminate because the protection address is
- * reached upon transfer of the first DWORD value.
- */
- s626_mc_enable(dev, S626_MC1_A2OUT, S626_P_MC1);
-
- /* While the DMA transfer is executing ... */
-
- /*
- * Reset Audio2 output FIFO's underflow flag (along with any
- * other FIFO underflow/overflow flags). When set, this flag
- * will indicate that we have emerged from slot 0.
- */
- writel(S626_ISR_AFOU, dev->mmio + S626_P_ISR);
-
- /*
- * Wait for the DMA transfer to finish so that there will be data
- * available in the FIFO when time slot 1 tries to transfer a DWORD
- * from the FIFO to the output buffer register. We test for DMA
- * Done by polling the DMAC enable flag; this flag is automatically
- * cleared when the transfer has finished.
- */
- ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
- s626_send_dac_wait_not_mc1_a2out);
- if (ret) {
- dev_err(dev->class_dev, "DMA transfer timeout\n");
- return ret;
- }
-
- /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
-
- /*
- * FIFO data is now available, so we enable execution of time slots
- * 1 and higher by clearing the EOS flag in slot 0. Note that SD3
- * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
- * detection.
- */
- writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2,
- dev->mmio + S626_VECTPORT(0));
-
- /*
- * Wait for slot 1 to execute to ensure that the Packet will be
- * transmitted. This is detected by polling the Audio2 output FIFO
- * underflow flag, which will be set when slot 1 execution has
- * finished transferring the DAC's data DWORD from the output FIFO
- * to the output buffer register.
- */
- ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
- s626_send_dac_wait_ssr_af2_out);
- if (ret) {
- dev_err(dev->class_dev,
- "TSL timeout waiting for slot 1 to execute\n");
- return ret;
- }
-
- /*
- * Set up to trap execution at slot 0 when the TSL sequencer cycles
- * back to slot 0 after executing the EOS in slot 5. Also,
- * simultaneously shift out and in the 0x00 that is ALWAYS the value
- * stored in the last byte to be shifted out of the FIFO's DWORD
- * buffer register.
- */
- writel(S626_XSD2 | S626_XFIFO_2 | S626_RSD2 | S626_SIB_A2 | S626_EOS,
- dev->mmio + S626_VECTPORT(0));
-
- /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
-
- /*
- * Wait for the TSL to finish executing all time slots before
- * exiting this function. We must do this so that the next DAC
- * write doesn't start, thereby enabling clock/chip select signals:
- *
- * 1. Before the TSL sequence cycles back to slot 0, which disables
- * the clock/cs signal gating and traps slot // list execution.
- * we have not yet finished slot 5 then the clock/cs signals are
- * still gated and we have not finished transmitting the stream.
- *
- * 2. While slots 2-5 are executing due to a late slot 0 trap. In
- * this case, the slot sequence is currently repeating, but with
- * clock/cs signals disabled. We must wait for slot 0 to trap
- * execution before setting up the next DAC setpoint DMA transfer
- * and enabling the clock/cs signals. To detect the end of slot 5,
- * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If
- * the TSL has not yet finished executing slot 5 ...
- */
- if (readl(dev->mmio + S626_P_FB_BUFFER2) & 0xff000000) {
- /*
- * The trap was set on time and we are still executing somewhere
- * in slots 2-5, so we now wait for slot 0 to execute and trap
- * TSL execution. This is detected when FB_BUFFER2 MSB changes
- * from 0xFF to 0x00, which slot 0 causes to happen by shifting
- * out/in on SD2 the 0x00 that is always referenced by slot 5.
- */
- ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
- s626_send_dac_wait_fb_buffer2_msb_00);
- if (ret) {
- dev_err(dev->class_dev,
- "TSL timeout waiting for slot 0 to execute\n");
- return ret;
- }
- }
- /*
- * Either (1) we were too late setting the slot 0 trap; the TSL
- * sequencer restarted slot 0 before we could set the EOS trap flag,
- * or (2) we were not late and execution is now trapped at slot 0.
- * In either case, we must now change slot 0 so that it will store
- * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
- * In order to do this, we reprogram slot 0 so that it will shift in
- * SD3, which is driven only by a pull-up resistor.
- */
- writel(S626_RSD3 | S626_SIB_A2 | S626_EOS,
- dev->mmio + S626_VECTPORT(0));
-
- /*
- * Wait for slot 0 to execute, at which time the TSL is setup for
- * the next DAC write. This is detected when FB_BUFFER2 MSB changes
- * from 0x00 to 0xFF.
- */
- ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
- s626_send_dac_wait_fb_buffer2_msb_ff);
- if (ret) {
- dev_err(dev->class_dev,
- "TSL timeout waiting for slot 0 to execute\n");
- return ret;
- }
- return 0;
-}
-
-/*
- * Private helper function: Write setpoint to an application DAC channel.
- */
-static int s626_set_dac(struct comedi_device *dev,
- u16 chan, int16_t dacdata)
-{
- struct s626_private *devpriv = dev->private;
- u16 signmask;
- u32 ws_image;
- u32 val;
-
- /*
- * Adjust DAC data polarity and set up Polarity Control Register image.
- */
- signmask = 1 << chan;
- if (dacdata < 0) {
- dacdata = -dacdata;
- devpriv->dacpol |= signmask;
- } else {
- devpriv->dacpol &= ~signmask;
- }
-
- /* Limit DAC setpoint value to valid range. */
- if ((u16)dacdata > 0x1FFF)
- dacdata = 0x1FFF;
-
- /*
- * Set up TSL2 records (aka "vectors") for DAC update. Vectors V2
- * and V3 transmit the setpoint to the target DAC. V4 and V5 send
- * data to a non-existent TrimDac channel just to keep the clock
- * running after sending data to the target DAC. This is necessary
- * to eliminate the clock glitch that would otherwise occur at the
- * end of the target DAC's serial data stream. When the sequence
- * restarts at V0 (after executing V5), the gate array automatically
- * disables gating for the DAC clock and all DAC chip selects.
- */
-
- /* Choose DAC chip select to be asserted */
- ws_image = (chan & 2) ? S626_WS1 : S626_WS2;
- /* Slot 2: Transmit high data byte to target DAC */
- writel(S626_XSD2 | S626_XFIFO_1 | ws_image,
- dev->mmio + S626_VECTPORT(2));
- /* Slot 3: Transmit low data byte to target DAC */
- writel(S626_XSD2 | S626_XFIFO_0 | ws_image,
- dev->mmio + S626_VECTPORT(3));
- /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
- writel(S626_XSD2 | S626_XFIFO_3 | S626_WS3,
- dev->mmio + S626_VECTPORT(4));
- /* Slot 5: running after writing target DAC's low data byte */
- writel(S626_XSD2 | S626_XFIFO_2 | S626_WS3 | S626_EOS,
- dev->mmio + S626_VECTPORT(5));
-
- /*
- * Construct and transmit target DAC's serial packet:
- * (A10D DDDD), (DDDD DDDD), (0x0F), (0x00) where A is chan<0>,
- * and D<12:0> is the DAC setpoint. Append a WORD value (that writes
- * to a non-existent TrimDac channel) that serves to keep the clock
- * running after the packet has been sent to the target DAC.
- */
- val = 0x0F000000; /* Continue clock after target DAC data
- * (write to non-existent trimdac).
- */
- val |= 0x00004000; /* Address the two main dual-DAC devices
- * (TSL's chip select enables target device).
- */
- val |= ((u32)(chan & 1) << 15); /* Address the DAC channel
- * within the device.
- */
- val |= (u32)dacdata; /* Include DAC setpoint data. */
- return s626_send_dac(dev, val);
-}
-
-static int s626_write_trim_dac(struct comedi_device *dev,
- u8 logical_chan, u8 dac_data)
-{
- struct s626_private *devpriv = dev->private;
- u32 chan;
-
- /*
- * Save the new setpoint in case the application needs to read it back
- * later.
- */
- devpriv->trim_setpoint[logical_chan] = dac_data;
-
- /* Map logical channel number to physical channel number. */
- chan = s626_trimchan[logical_chan];
-
- /*
- * Set up TSL2 records for TrimDac write operation. All slots shift
- * 0xFF in from pulled-up SD3 so that the end of the slot sequence
- * can be detected.
- */
-
- /* Slot 2: Send high uint8_t to target TrimDac */
- writel(S626_XSD2 | S626_XFIFO_1 | S626_WS3,
- dev->mmio + S626_VECTPORT(2));
- /* Slot 3: Send low uint8_t to target TrimDac */
- writel(S626_XSD2 | S626_XFIFO_0 | S626_WS3,
- dev->mmio + S626_VECTPORT(3));
- /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running */
- writel(S626_XSD2 | S626_XFIFO_3 | S626_WS1,
- dev->mmio + S626_VECTPORT(4));
- /* Slot 5: Send NOP low uint8_t to DAC0 */
- writel(S626_XSD2 | S626_XFIFO_2 | S626_WS1 | S626_EOS,
- dev->mmio + S626_VECTPORT(5));
-
- /*
- * Construct and transmit target DAC's serial packet:
- * (0000 AAAA), (DDDD DDDD), (0x00), (0x00) where A<3:0> is the
- * DAC channel's address, and D<7:0> is the DAC setpoint. Append a
- * WORD value (that writes a channel 0 NOP command to a non-existent
- * main DAC channel) that serves to keep the clock running after the
- * packet has been sent to the target DAC.
- */
-
- /*
- * Address the DAC channel within the trimdac device.
- * Include DAC setpoint data.
- */
- return s626_send_dac(dev, (chan << 8) | dac_data);
-}
-
-static int s626_load_trim_dacs(struct comedi_device *dev)
-{
- u8 i;
- int ret;
-
- /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */
- for (i = 0; i < ARRAY_SIZE(s626_trimchan); i++) {
- ret = s626_write_trim_dac(dev, i,
- s626_i2c_read(dev, s626_trimadrs[i]));
- if (ret)
- return ret;
- }
- return 0;
-}
-
-/* ****** COUNTER FUNCTIONS ******* */
-
-/*
- * All counter functions address a specific counter by means of the
- * "Counter" argument, which is a logical counter number. The Counter
- * argument may have any of the following legal values: 0=0A, 1=1A,
- * 2=2A, 3=0B, 4=1B, 5=2B.
- */
-
-/*
- * Return/set a counter pair's latch trigger source. 0: On read
- * access, 1: A index latches A, 2: B index latches B, 3: A overflow
- * latches B.
- */
-static void s626_set_latch_source(struct comedi_device *dev,
- unsigned int chan, u16 value)
-{
- s626_debi_replace(dev, S626_LP_CRB(chan),
- ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_LATCHSRC),
- S626_SET_CRB_LATCHSRC(value));
-}
-
-/*
- * Write value into counter preload register.
- */
-static void s626_preload(struct comedi_device *dev,
- unsigned int chan, u32 value)
-{
- s626_debi_write(dev, S626_LP_CNTR(chan), value);
- s626_debi_write(dev, S626_LP_CNTR(chan) + 2, value >> 16);
-}
-
-/* ****** PRIVATE COUNTER FUNCTIONS ****** */
-
-/*
- * Reset a counter's index and overflow event capture flags.
- */
-static void s626_reset_cap_flags(struct comedi_device *dev,
- unsigned int chan)
-{
- u16 set;
-
- set = S626_SET_CRB_INTRESETCMD(1);
- if (chan < 3)
- set |= S626_SET_CRB_INTRESET_A(1);
- else
- set |= S626_SET_CRB_INTRESET_B(1);
-
- s626_debi_replace(dev, S626_LP_CRB(chan), ~S626_CRBMSK_INTCTRL, set);
-}
-
-/*
- * Set the operating mode for the specified counter. The setup
- * parameter is treated as a COUNTER_SETUP data type. The following
- * parameters are programmable (all other parms are ignored): ClkMult,
- * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
- */
-static void s626_set_mode_a(struct comedi_device *dev,
- unsigned int chan, u16 setup,
- u16 disable_int_src)
-{
- struct s626_private *devpriv = dev->private;
- u16 cra;
- u16 crb;
- unsigned int cntsrc, clkmult, clkpol;
-
- /* Initialize CRA and CRB images. */
- /* Preload trigger is passed through. */
- cra = S626_SET_CRA_LOADSRC_A(S626_GET_STD_LOADSRC(setup));
- /* IndexSrc is passed through. */
- cra |= S626_SET_CRA_INDXSRC_A(S626_GET_STD_INDXSRC(setup));
-
- /* Reset any pending CounterA event captures. */
- crb = S626_SET_CRB_INTRESETCMD(1) | S626_SET_CRB_INTRESET_A(1);
- /* Clock enable is passed through. */
- crb |= S626_SET_CRB_CLKENAB_A(S626_GET_STD_CLKENAB(setup));
-
- /* Force IntSrc to Disabled if disable_int_src is asserted. */
- if (!disable_int_src)
- cra |= S626_SET_CRA_INTSRC_A(S626_GET_STD_INTSRC(setup));
-
- /* Populate all mode-dependent attributes of CRA & CRB images. */
- clkpol = S626_GET_STD_CLKPOL(setup);
- switch (S626_GET_STD_ENCMODE(setup)) {
- case S626_ENCMODE_EXTENDER: /* Extender Mode: */
- /* Force to Timer mode (Extender valid only for B counters). */
- /* Fall through to case S626_ENCMODE_TIMER: */
- case S626_ENCMODE_TIMER: /* Timer Mode: */
- /* CntSrcA<1> selects system clock */
- cntsrc = S626_CNTSRC_SYSCLK;
- /* Count direction (CntSrcA<0>) obtained from ClkPol. */
- cntsrc |= clkpol;
- /* ClkPolA behaves as always-on clock enable. */
- clkpol = 1;
- /* ClkMult must be 1x. */
- clkmult = S626_CLKMULT_1X;
- break;
- default: /* Counter Mode: */
- /* Select ENC_C and ENC_D as clock/direction inputs. */
- cntsrc = S626_CNTSRC_ENCODER;
- /* Clock polarity is passed through. */
- /* Force multiplier to x1 if not legal, else pass through. */
- clkmult = S626_GET_STD_CLKMULT(setup);
- if (clkmult == S626_CLKMULT_SPECIAL)
- clkmult = S626_CLKMULT_1X;
- break;
- }
- cra |= S626_SET_CRA_CNTSRC_A(cntsrc) | S626_SET_CRA_CLKPOL_A(clkpol) |
- S626_SET_CRA_CLKMULT_A(clkmult);
-
- /*
- * Force positive index polarity if IndxSrc is software-driven only,
- * otherwise pass it through.
- */
- if (S626_GET_STD_INDXSRC(setup) != S626_INDXSRC_SOFT)
- cra |= S626_SET_CRA_INDXPOL_A(S626_GET_STD_INDXPOL(setup));
-
- /*
- * If IntSrc has been forced to Disabled, update the MISC2 interrupt
- * enable mask to indicate the counter interrupt is disabled.
- */
- if (disable_int_src)
- devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
- S626_INDXMASK(chan));
-
- /*
- * While retaining CounterB and LatchSrc configurations, program the
- * new counter operating mode.
- */
- s626_debi_replace(dev, S626_LP_CRA(chan),
- S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B, cra);
- s626_debi_replace(dev, S626_LP_CRB(chan),
- ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A), crb);
-}
-
-static void s626_set_mode_b(struct comedi_device *dev,
- unsigned int chan, u16 setup,
- u16 disable_int_src)
-{
- struct s626_private *devpriv = dev->private;
- u16 cra;
- u16 crb;
- unsigned int cntsrc, clkmult, clkpol;
-
- /* Initialize CRA and CRB images. */
- /* IndexSrc is passed through. */
- cra = S626_SET_CRA_INDXSRC_B(S626_GET_STD_INDXSRC(setup));
-
- /* Reset event captures and disable interrupts. */
- crb = S626_SET_CRB_INTRESETCMD(1) | S626_SET_CRB_INTRESET_B(1);
- /* Clock enable is passed through. */
- crb |= S626_SET_CRB_CLKENAB_B(S626_GET_STD_CLKENAB(setup));
- /* Preload trigger source is passed through. */
- crb |= S626_SET_CRB_LOADSRC_B(S626_GET_STD_LOADSRC(setup));
-
- /* Force IntSrc to Disabled if disable_int_src is asserted. */
- if (!disable_int_src)
- crb |= S626_SET_CRB_INTSRC_B(S626_GET_STD_INTSRC(setup));
-
- /* Populate all mode-dependent attributes of CRA & CRB images. */
- clkpol = S626_GET_STD_CLKPOL(setup);
- switch (S626_GET_STD_ENCMODE(setup)) {
- case S626_ENCMODE_TIMER: /* Timer Mode: */
- /* CntSrcB<1> selects system clock */
- cntsrc = S626_CNTSRC_SYSCLK;
- /* with direction (CntSrcB<0>) obtained from ClkPol. */
- cntsrc |= clkpol;
- /* ClkPolB behaves as always-on clock enable. */
- clkpol = 1;
- /* ClkMultB must be 1x. */
- clkmult = S626_CLKMULT_1X;
- break;
- case S626_ENCMODE_EXTENDER: /* Extender Mode: */
- /* CntSrcB source is OverflowA (same as "timer") */
- cntsrc = S626_CNTSRC_SYSCLK;
- /* with direction obtained from ClkPol. */
- cntsrc |= clkpol;
- /* ClkPolB controls IndexB -- always set to active. */
- clkpol = 1;
- /* ClkMultB selects OverflowA as the clock source. */
- clkmult = S626_CLKMULT_SPECIAL;
- break;
- default: /* Counter Mode: */
- /* Select ENC_C and ENC_D as clock/direction inputs. */
- cntsrc = S626_CNTSRC_ENCODER;
- /* ClkPol is passed through. */
- /* Force ClkMult to x1 if not legal, otherwise pass through. */
- clkmult = S626_GET_STD_CLKMULT(setup);
- if (clkmult == S626_CLKMULT_SPECIAL)
- clkmult = S626_CLKMULT_1X;
- break;
- }
- cra |= S626_SET_CRA_CNTSRC_B(cntsrc);
- crb |= S626_SET_CRB_CLKPOL_B(clkpol) | S626_SET_CRB_CLKMULT_B(clkmult);
-
- /*
- * Force positive index polarity if IndxSrc is software-driven only,
- * otherwise pass it through.
- */
- if (S626_GET_STD_INDXSRC(setup) != S626_INDXSRC_SOFT)
- crb |= S626_SET_CRB_INDXPOL_B(S626_GET_STD_INDXPOL(setup));
-
- /*
- * If IntSrc has been forced to Disabled, update the MISC2 interrupt
- * enable mask to indicate the counter interrupt is disabled.
- */
- if (disable_int_src)
- devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
- S626_INDXMASK(chan));
-
- /*
- * While retaining CounterA and LatchSrc configurations, program the
- * new counter operating mode.
- */
- s626_debi_replace(dev, S626_LP_CRA(chan),
- ~(S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B), cra);
- s626_debi_replace(dev, S626_LP_CRB(chan),
- S626_CRBMSK_CLKENAB_A | S626_CRBMSK_LATCHSRC, crb);
-}
-
-static void s626_set_mode(struct comedi_device *dev,
- unsigned int chan,
- u16 setup, u16 disable_int_src)
-{
- if (chan < 3)
- s626_set_mode_a(dev, chan, setup, disable_int_src);
- else
- s626_set_mode_b(dev, chan, setup, disable_int_src);
-}
-
-/*
- * Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index.
- */
-static void s626_set_enable(struct comedi_device *dev,
- unsigned int chan, u16 enab)
-{
- unsigned int mask = S626_CRBMSK_INTCTRL;
- unsigned int set;
-
- if (chan < 3) {
- mask |= S626_CRBMSK_CLKENAB_A;
- set = S626_SET_CRB_CLKENAB_A(enab);
- } else {
- mask |= S626_CRBMSK_CLKENAB_B;
- set = S626_SET_CRB_CLKENAB_B(enab);
- }
- s626_debi_replace(dev, S626_LP_CRB(chan), ~mask, set);
-}
-
-/*
- * Return/set the event that will trigger transfer of the preload
- * register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
- * 2=OverflowA (B counters only), 3=disabled.
- */
-static void s626_set_load_trig(struct comedi_device *dev,
- unsigned int chan, u16 trig)
-{
- u16 reg;
- u16 mask;
- u16 set;
-
- if (chan < 3) {
- reg = S626_LP_CRA(chan);
- mask = S626_CRAMSK_LOADSRC_A;
- set = S626_SET_CRA_LOADSRC_A(trig);
- } else {
- reg = S626_LP_CRB(chan);
- mask = S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL;
- set = S626_SET_CRB_LOADSRC_B(trig);
- }
- s626_debi_replace(dev, reg, ~mask, set);
-}
-
-/*
- * Return/set counter interrupt source and clear any captured
- * index/overflow events. int_source: 0=Disabled, 1=OverflowOnly,
- * 2=IndexOnly, 3=IndexAndOverflow.
- */
-static void s626_set_int_src(struct comedi_device *dev,
- unsigned int chan, u16 int_source)
-{
- struct s626_private *devpriv = dev->private;
- u16 cra_reg = S626_LP_CRA(chan);
- u16 crb_reg = S626_LP_CRB(chan);
-
- if (chan < 3) {
- /* Reset any pending counter overflow or index captures */
- s626_debi_replace(dev, crb_reg, ~S626_CRBMSK_INTCTRL,
- S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_A(1));
-
- /* Program counter interrupt source */
- s626_debi_replace(dev, cra_reg, ~S626_CRAMSK_INTSRC_A,
- S626_SET_CRA_INTSRC_A(int_source));
- } else {
- u16 crb;
-
- /* Cache writeable CRB register image */
- crb = s626_debi_read(dev, crb_reg);
- crb &= ~S626_CRBMSK_INTCTRL;
-
- /* Reset any pending counter overflow or index captures */
- s626_debi_write(dev, crb_reg,
- crb | S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_B(1));
-
- /* Program counter interrupt source */
- s626_debi_write(dev, crb_reg,
- (crb & ~S626_CRBMSK_INTSRC_B) |
- S626_SET_CRB_INTSRC_B(int_source));
- }
-
- /* Update MISC2 interrupt enable mask. */
- devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
- S626_INDXMASK(chan));
- switch (int_source) {
- case 0:
- default:
- break;
- case 1:
- devpriv->counter_int_enabs |= S626_OVERMASK(chan);
- break;
- case 2:
- devpriv->counter_int_enabs |= S626_INDXMASK(chan);
- break;
- case 3:
- devpriv->counter_int_enabs |= (S626_OVERMASK(chan) |
- S626_INDXMASK(chan));
- break;
- }
-}
-
-/*
- * Generate an index pulse.
- */
-static void s626_pulse_index(struct comedi_device *dev,
- unsigned int chan)
-{
- if (chan < 3) {
- u16 cra;
-
- cra = s626_debi_read(dev, S626_LP_CRA(chan));
-
- /* Pulse index */
- s626_debi_write(dev, S626_LP_CRA(chan),
- (cra ^ S626_CRAMSK_INDXPOL_A));
- s626_debi_write(dev, S626_LP_CRA(chan), cra);
- } else {
- u16 crb;
-
- crb = s626_debi_read(dev, S626_LP_CRB(chan));
- crb &= ~S626_CRBMSK_INTCTRL;
-
- /* Pulse index */
- s626_debi_write(dev, S626_LP_CRB(chan),
- (crb ^ S626_CRBMSK_INDXPOL_B));
- s626_debi_write(dev, S626_LP_CRB(chan), crb);
- }
-}
-
-static unsigned int s626_ai_reg_to_uint(unsigned int data)
-{
- return ((data >> 18) & 0x3fff) ^ 0x2000;
-}
-
-static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
-{
- unsigned int group = chan / 16;
- unsigned int mask = 1 << (chan - (16 * group));
- unsigned int status;
-
- /* set channel to capture positive edge */
- status = s626_debi_read(dev, S626_LP_RDEDGSEL(group));
- s626_debi_write(dev, S626_LP_WREDGSEL(group), mask | status);
-
- /* enable interrupt on selected channel */
- status = s626_debi_read(dev, S626_LP_RDINTSEL(group));
- s626_debi_write(dev, S626_LP_WRINTSEL(group), mask | status);
-
- /* enable edge capture write command */
- s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_EDCAP);
-
- /* enable edge capture on selected channel */
- status = s626_debi_read(dev, S626_LP_RDCAPSEL(group));
- s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask | status);
-
- return 0;
-}
-
-static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
- unsigned int mask)
-{
- /* disable edge capture write command */
- s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
-
- /* enable edge capture on selected channel */
- s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask);
-
- return 0;
-}
-
-static int s626_dio_clear_irq(struct comedi_device *dev)
-{
- unsigned int group;
-
- /* disable edge capture write command */
- s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
-
- /* clear all dio pending events and interrupt */
- for (group = 0; group < S626_DIO_BANKS; group++)
- s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff);
-
- return 0;
-}
-
-static void s626_handle_dio_interrupt(struct comedi_device *dev,
- u16 irqbit, u8 group)
-{
- struct s626_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- s626_dio_reset_irq(dev, group, irqbit);
-
- if (devpriv->ai_cmd_running) {
- /* check if interrupt is an ai acquisition start trigger */
- if ((irqbit >> (cmd->start_arg - (16 * group))) == 1 &&
- cmd->start_src == TRIG_EXT) {
- /* Start executing the RPS program */
- s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
-
- if (cmd->scan_begin_src == TRIG_EXT)
- s626_dio_set_irq(dev, cmd->scan_begin_arg);
- }
- if ((irqbit >> (cmd->scan_begin_arg - (16 * group))) == 1 &&
- cmd->scan_begin_src == TRIG_EXT) {
- /* Trigger ADC scan loop start */
- s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
-
- if (cmd->convert_src == TRIG_EXT) {
- devpriv->ai_convert_count = cmd->chanlist_len;
-
- s626_dio_set_irq(dev, cmd->convert_arg);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- devpriv->ai_convert_count = cmd->chanlist_len;
- s626_set_enable(dev, 5, S626_CLKENAB_ALWAYS);
- }
- }
- if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 &&
- cmd->convert_src == TRIG_EXT) {
- /* Trigger ADC scan loop start */
- s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
-
- devpriv->ai_convert_count--;
- if (devpriv->ai_convert_count > 0)
- s626_dio_set_irq(dev, cmd->convert_arg);
- }
- }
-}
-
-static void s626_check_dio_interrupts(struct comedi_device *dev)
-{
- u16 irqbit;
- u8 group;
-
- for (group = 0; group < S626_DIO_BANKS; group++) {
- /* read interrupt type */
- irqbit = s626_debi_read(dev, S626_LP_RDCAPFLG(group));
-
- /* check if interrupt is generated from dio channels */
- if (irqbit) {
- s626_handle_dio_interrupt(dev, irqbit, group);
- return;
- }
- }
-}
-
-static void s626_check_counter_interrupts(struct comedi_device *dev)
-{
- struct s626_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u16 irqbit;
-
- /* read interrupt type */
- irqbit = s626_debi_read(dev, S626_LP_RDMISC2);
-
- /* check interrupt on counters */
- if (irqbit & S626_IRQ_COINT1A) {
- /* clear interrupt capture flag */
- s626_reset_cap_flags(dev, 0);
- }
- if (irqbit & S626_IRQ_COINT2A) {
- /* clear interrupt capture flag */
- s626_reset_cap_flags(dev, 1);
- }
- if (irqbit & S626_IRQ_COINT3A) {
- /* clear interrupt capture flag */
- s626_reset_cap_flags(dev, 2);
- }
- if (irqbit & S626_IRQ_COINT1B) {
- /* clear interrupt capture flag */
- s626_reset_cap_flags(dev, 3);
- }
- if (irqbit & S626_IRQ_COINT2B) {
- /* clear interrupt capture flag */
- s626_reset_cap_flags(dev, 4);
-
- if (devpriv->ai_convert_count > 0) {
- devpriv->ai_convert_count--;
- if (devpriv->ai_convert_count == 0)
- s626_set_enable(dev, 4, S626_CLKENAB_INDEX);
-
- if (cmd->convert_src == TRIG_TIMER) {
- /* Trigger ADC scan loop start */
- s626_mc_enable(dev, S626_MC2_ADC_RPS,
- S626_P_MC2);
- }
- }
- }
- if (irqbit & S626_IRQ_COINT3B) {
- /* clear interrupt capture flag */
- s626_reset_cap_flags(dev, 5);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Trigger ADC scan loop start */
- s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- devpriv->ai_convert_count = cmd->chanlist_len;
- s626_set_enable(dev, 4, S626_CLKENAB_ALWAYS);
- }
- }
-}
-
-static bool s626_handle_eos_interrupt(struct comedi_device *dev)
-{
- struct s626_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- /*
- * Init ptr to DMA buffer that holds new ADC data. We skip the
- * first uint16_t in the buffer because it contains junk data
- * from the final ADC of the previous poll list scan.
- */
- u32 *readaddr = (u32 *)devpriv->ana_buf.logical_base + 1;
- int i;
-
- /* get the data and hand it over to comedi */
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned short tempdata;
-
- /*
- * Convert ADC data to 16-bit integer values and copy
- * to application buffer.
- */
- tempdata = s626_ai_reg_to_uint(*readaddr);
- readaddr++;
-
- comedi_buf_write_samples(s, &tempdata, 1);
- }
-
- if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
-
- if (async->events & COMEDI_CB_CANCEL_MASK)
- devpriv->ai_cmd_running = 0;
-
- if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT)
- s626_dio_set_irq(dev, cmd->scan_begin_arg);
-
- comedi_handle_events(dev, s);
-
- return !devpriv->ai_cmd_running;
-}
-
-static irqreturn_t s626_irq_handler(int irq, void *d)
-{
- struct comedi_device *dev = d;
- unsigned long flags;
- u32 irqtype, irqstatus;
-
- if (!dev->attached)
- return IRQ_NONE;
- /* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&dev->spinlock, flags);
-
- /* save interrupt enable register state */
- irqstatus = readl(dev->mmio + S626_P_IER);
-
- /* read interrupt type */
- irqtype = readl(dev->mmio + S626_P_ISR);
-
- /* disable master interrupt */
- writel(0, dev->mmio + S626_P_IER);
-
- /* clear interrupt */
- writel(irqtype, dev->mmio + S626_P_ISR);
-
- switch (irqtype) {
- case S626_IRQ_RPS1: /* end_of_scan occurs */
- if (s626_handle_eos_interrupt(dev))
- irqstatus = 0;
- break;
- case S626_IRQ_GPIO3: /* check dio and counter interrupt */
- /* s626_dio_clear_irq(dev); */
- s626_check_dio_interrupts(dev);
- s626_check_counter_interrupts(dev);
- break;
- }
-
- /* enable interrupt */
- writel(irqstatus, dev->mmio + S626_P_IER);
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return IRQ_HANDLED;
-}
-
-/*
- * This function builds the RPS program for hardware driven acquisition.
- */
-static void s626_reset_adc(struct comedi_device *dev, u8 *ppl)
-{
- struct s626_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_cmd *cmd = &s->async->cmd;
- u32 *rps;
- u32 jmp_adrs;
- u16 i;
- u16 n;
- u32 local_ppl;
-
- /* Stop RPS program in case it is currently running */
- s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
-
- /* Set starting logical address to write RPS commands. */
- rps = (u32 *)devpriv->rps_buf.logical_base;
-
- /* Initialize RPS instruction pointer */
- writel((u32)devpriv->rps_buf.physical_base,
- dev->mmio + S626_P_RPSADDR1);
-
- /* Construct RPS program in rps_buf DMA buffer */
- if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /* Wait for Start trigger. */
- *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC;
- *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC;
- }
-
- /*
- * SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary
- * because the first RPS DEBI Write following a non-RPS DEBI write
- * seems to always fail. If we don't do this dummy write, the ADC
- * gain might not be set to the value required for the first slot in
- * the poll list; the ADC gain would instead remain unchanged from
- * the previously programmed value.
- */
- /* Write DEBI Write command and address to shadow RAM. */
- *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
- *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_GSEL;
- *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
- /* Write DEBI immediate data to shadow RAM: */
- *rps++ = S626_GSEL_BIPOLAR5V; /* arbitrary immediate data value. */
- *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
- /* Reset "shadow RAM uploaded" flag. */
- /* Invoke shadow RAM upload. */
- *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
- /* Wait for shadow upload to finish. */
- *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
-
- /*
- * Digitize all slots in the poll list. This is implemented as a
- * for loop to limit the slot count to 16 in case the application
- * forgot to set the S626_EOPL flag in the final slot.
- */
- for (devpriv->adc_items = 0; devpriv->adc_items < 16;
- devpriv->adc_items++) {
- /*
- * Convert application's poll list item to private board class
- * format. Each app poll list item is an uint8_t with form
- * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
- * +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
- */
- local_ppl = (*ppl << 8) | (*ppl & 0x10 ? S626_GSEL_BIPOLAR5V :
- S626_GSEL_BIPOLAR10V);
-
- /* Switch ADC analog gain. */
- /* Write DEBI command and address to shadow RAM. */
- *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
- *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_GSEL;
- /* Write DEBI immediate data to shadow RAM. */
- *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
- *rps++ = local_ppl;
- /* Reset "shadow RAM uploaded" flag. */
- *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
- /* Invoke shadow RAM upload. */
- *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
- /* Wait for shadow upload to finish. */
- *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
- /* Select ADC analog input channel. */
- *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
- /* Write DEBI command and address to shadow RAM. */
- *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_ISEL;
- *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
- /* Write DEBI immediate data to shadow RAM. */
- *rps++ = local_ppl;
- /* Reset "shadow RAM uploaded" flag. */
- *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
- /* Invoke shadow RAM upload. */
- *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
- /* Wait for shadow upload to finish. */
- *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
-
- /*
- * Delay at least 10 microseconds for analog input settling.
- * Instead of padding with NOPs, we use S626_RPS_JUMP
- * instructions here; this allows us to produce a longer delay
- * than is possible with NOPs because each S626_RPS_JUMP
- * flushes the RPS' instruction prefetch pipeline.
- */
- jmp_adrs =
- (u32)devpriv->rps_buf.physical_base +
- (u32)((unsigned long)rps -
- (unsigned long)devpriv->rps_buf.logical_base);
- for (i = 0; i < (10 * S626_RPSCLK_PER_US / 2); i++) {
- jmp_adrs += 8; /* Repeat to implement time delay: */
- /* Jump to next RPS instruction. */
- *rps++ = S626_RPS_JUMP;
- *rps++ = jmp_adrs;
- }
-
- if (cmd->convert_src != TRIG_NOW) {
- /* Wait for Start trigger. */
- *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC;
- *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC;
- }
- /* Start ADC by pulsing GPIO1. */
- /* Begin ADC Start pulse. */
- *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
- *rps++ = S626_GPIO_BASE | S626_GPIO1_LO;
- *rps++ = S626_RPS_NOP;
- /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
- /* End ADC Start pulse. */
- *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
- *rps++ = S626_GPIO_BASE | S626_GPIO1_HI;
- /*
- * Wait for ADC to complete (GPIO2 is asserted high when ADC not
- * busy) and for data from previous conversion to shift into FB
- * BUFFER 1 register.
- */
- /* Wait for ADC done. */
- *rps++ = S626_RPS_PAUSE | S626_RPS_GPIO2;
-
- /* Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
- *rps++ = S626_RPS_STREG |
- (S626_BUGFIX_STREG(S626_P_FB_BUFFER1) >> 2);
- *rps++ = (u32)devpriv->ana_buf.physical_base +
- (devpriv->adc_items << 2);
-
- /*
- * If this slot's EndOfPollList flag is set, all channels have
- * now been processed.
- */
- if (*ppl++ & S626_EOPL) {
- devpriv->adc_items++; /* Adjust poll list item count. */
- break; /* Exit poll list processing loop. */
- }
- }
-
- /*
- * VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the
- * ADC to stabilize for 2 microseconds before starting the final
- * (dummy) conversion. This delay is necessary to allow sufficient
- * time between last conversion finished and the start of the dummy
- * conversion. Without this delay, the last conversion's data value
- * is sometimes set to the previous conversion's data value.
- */
- for (n = 0; n < (2 * S626_RPSCLK_PER_US); n++)
- *rps++ = S626_RPS_NOP;
-
- /*
- * Start a dummy conversion to cause the data from the last
- * conversion of interest to be shifted in.
- */
- /* Begin ADC Start pulse. */
- *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
- *rps++ = S626_GPIO_BASE | S626_GPIO1_LO;
- *rps++ = S626_RPS_NOP;
- /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
- *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2); /* End ADC Start pulse. */
- *rps++ = S626_GPIO_BASE | S626_GPIO1_HI;
-
- /*
- * Wait for the data from the last conversion of interest to arrive
- * in FB BUFFER 1 register.
- */
- *rps++ = S626_RPS_PAUSE | S626_RPS_GPIO2; /* Wait for ADC done. */
-
- /* Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
- *rps++ = S626_RPS_STREG | (S626_BUGFIX_STREG(S626_P_FB_BUFFER1) >> 2);
- *rps++ = (u32)devpriv->ana_buf.physical_base +
- (devpriv->adc_items << 2);
-
- /* Indicate ADC scan loop is finished. */
- /* Signal ReadADC() that scan is done. */
- /* *rps++= S626_RPS_CLRSIGNAL | S626_RPS_SIGADC; */
-
- /* invoke interrupt */
- if (devpriv->ai_cmd_running == 1)
- *rps++ = S626_RPS_IRQ;
-
- /* Restart RPS program at its beginning. */
- *rps++ = S626_RPS_JUMP; /* Branch to start of RPS program. */
- *rps++ = (u32)devpriv->rps_buf.physical_base;
-
- /* End of RPS program build */
-}
-
-static int s626_ai_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
-{
- unsigned int status;
-
- status = readl(dev->mmio + S626_P_PSR);
- if (status & S626_PSR_GPIO2)
- return 0;
- return -EBUSY;
-}
-
-static int s626_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- u16 chan = CR_CHAN(insn->chanspec);
- u16 range = CR_RANGE(insn->chanspec);
- u16 adc_spec = 0;
- u32 gpio_image;
- u32 tmp;
- int ret;
- int n;
-
- /*
- * Convert application's ADC specification into form
- * appropriate for register programming.
- */
- if (range == 0)
- adc_spec = (chan << 8) | (S626_GSEL_BIPOLAR5V);
- else
- adc_spec = (chan << 8) | (S626_GSEL_BIPOLAR10V);
-
- /* Switch ADC analog gain. */
- s626_debi_write(dev, S626_LP_GSEL, adc_spec); /* Set gain. */
-
- /* Select ADC analog input channel. */
- s626_debi_write(dev, S626_LP_ISEL, adc_spec); /* Select channel. */
-
- for (n = 0; n < insn->n; n++) {
- /* Delay 10 microseconds for analog input settling. */
- usleep_range(10, 20);
-
- /* Start ADC by pulsing GPIO1 low */
- gpio_image = readl(dev->mmio + S626_P_GPIO);
- /* Assert ADC Start command */
- writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
- /* and stretch it out */
- writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
- writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
- /* Negate ADC Start command */
- writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
-
- /*
- * Wait for ADC to complete (GPIO2 is asserted high when
- * ADC not busy) and for data from previous conversion to
- * shift into FB BUFFER 1 register.
- */
-
- /* Wait for ADC done */
- ret = comedi_timeout(dev, s, insn, s626_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* Fetch ADC data */
- if (n != 0) {
- tmp = readl(dev->mmio + S626_P_FB_BUFFER1);
- data[n - 1] = s626_ai_reg_to_uint(tmp);
- }
-
- /*
- * Allow the ADC to stabilize for 4 microseconds before
- * starting the next (final) conversion. This delay is
- * necessary to allow sufficient time between last
- * conversion finished and the start of the next
- * conversion. Without this delay, the last conversion's
- * data value is sometimes set to the previous
- * conversion's data value.
- */
- udelay(4);
- }
-
- /*
- * Start a dummy conversion to cause the data from the
- * previous conversion to be shifted in.
- */
- gpio_image = readl(dev->mmio + S626_P_GPIO);
- /* Assert ADC Start command */
- writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
- /* and stretch it out */
- writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
- writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
- /* Negate ADC Start command */
- writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
-
- /* Wait for the data to arrive in FB BUFFER 1 register. */
-
- /* Wait for ADC done */
- ret = comedi_timeout(dev, s, insn, s626_ai_eoc, 0);
- if (ret)
- return ret;
-
- /* Fetch ADC data from audio interface's input shift register. */
-
- /* Fetch ADC data */
- if (n != 0) {
- tmp = readl(dev->mmio + S626_P_FB_BUFFER1);
- data[n - 1] = s626_ai_reg_to_uint(tmp);
- }
-
- return n;
-}
-
-static int s626_ai_load_polllist(u8 *ppl, struct comedi_cmd *cmd)
-{
- int n;
-
- for (n = 0; n < cmd->chanlist_len; n++) {
- if (CR_RANGE(cmd->chanlist[n]) == 0)
- ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_5V;
- else
- ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_10V;
- }
- if (n != 0)
- ppl[n - 1] |= S626_EOPL;
-
- return n;
-}
-
-static int s626_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- /* Start executing the RPS program */
- s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
-
- s->async->inttrig = NULL;
-
- return 1;
-}
-
-/*
- * This function doesn't require a particular form, this is just what
- * happens to be used in some of the drivers. It should convert ns
- * nanoseconds to a counter value suitable for programming the device.
- * Also, it should adjust ns so that it cooresponds to the actual time
- * that the device will use.
- */
-static int s626_ns_to_timer(unsigned int *nanosec, unsigned int flags)
-{
- int divider, base;
-
- base = 500; /* 2MHz internal clock */
-
- switch (flags & CMDF_ROUND_MASK) {
- case CMDF_ROUND_NEAREST:
- default:
- divider = DIV_ROUND_CLOSEST(*nanosec, base);
- break;
- case CMDF_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case CMDF_ROUND_UP:
- divider = DIV_ROUND_UP(*nanosec, base);
- break;
- }
-
- *nanosec = base * divider;
- return divider - 1;
-}
-
-static void s626_timer_load(struct comedi_device *dev,
- unsigned int chan, int tick)
-{
- u16 setup =
- /* Preload upon index. */
- S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
- /* Disable hardware index. */
- S626_SET_STD_INDXSRC(S626_INDXSRC_SOFT) |
- /* Operating mode is Timer. */
- S626_SET_STD_ENCMODE(S626_ENCMODE_TIMER) |
- /* Count direction is Down. */
- S626_SET_STD_CLKPOL(S626_CNTDIR_DOWN) |
- /* Clock multiplier is 1x. */
- S626_SET_STD_CLKMULT(S626_CLKMULT_1X) |
- /* Enabled by index */
- S626_SET_STD_CLKENAB(S626_CLKENAB_INDEX);
- u16 value_latchsrc = S626_LATCHSRC_A_INDXA;
- /* uint16_t enab = S626_CLKENAB_ALWAYS; */
-
- s626_set_mode(dev, chan, setup, false);
-
- /* Set the preload register */
- s626_preload(dev, chan, tick);
-
- /*
- * Software index pulse forces the preload register to load
- * into the counter
- */
- s626_set_load_trig(dev, chan, 0);
- s626_pulse_index(dev, chan);
-
- /* set reload on counter overflow */
- s626_set_load_trig(dev, chan, 1);
-
- /* set interrupt on overflow */
- s626_set_int_src(dev, chan, S626_INTSRC_OVER);
-
- s626_set_latch_source(dev, chan, value_latchsrc);
- /* s626_set_enable(dev, chan, (uint16_t)(enab != 0)); */
-}
-
-/* TO COMPLETE */
-static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct s626_private *devpriv = dev->private;
- u8 ppl[16];
- struct comedi_cmd *cmd = &s->async->cmd;
- int tick;
-
- if (devpriv->ai_cmd_running) {
- dev_err(dev->class_dev,
- "%s: Another ai_cmd is running\n", __func__);
- return -EBUSY;
- }
- /* disable interrupt */
- writel(0, dev->mmio + S626_P_IER);
-
- /* clear interrupt request */
- writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, dev->mmio + S626_P_ISR);
-
- /* clear any pending interrupt */
- s626_dio_clear_irq(dev);
- /* s626_enc_clear_irq(dev); */
-
- /* reset ai_cmd_running flag */
- devpriv->ai_cmd_running = 0;
-
- s626_ai_load_polllist(ppl, cmd);
- devpriv->ai_cmd_running = 1;
- devpriv->ai_convert_count = 0;
-
- switch (cmd->scan_begin_src) {
- case TRIG_FOLLOW:
- break;
- case TRIG_TIMER:
- /*
- * set a counter to generate adc trigger at scan_begin_arg
- * interval
- */
- tick = s626_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
-
- /* load timer value and enable interrupt */
- s626_timer_load(dev, 5, tick);
- s626_set_enable(dev, 5, S626_CLKENAB_ALWAYS);
- break;
- case TRIG_EXT:
- /* set the digital line and interrupt for scan trigger */
- if (cmd->start_src != TRIG_EXT)
- s626_dio_set_irq(dev, cmd->scan_begin_arg);
- break;
- }
-
- switch (cmd->convert_src) {
- case TRIG_NOW:
- break;
- case TRIG_TIMER:
- /*
- * set a counter to generate adc trigger at convert_arg
- * interval
- */
- tick = s626_ns_to_timer(&cmd->convert_arg, cmd->flags);
-
- /* load timer value and enable interrupt */
- s626_timer_load(dev, 4, tick);
- s626_set_enable(dev, 4, S626_CLKENAB_INDEX);
- break;
- case TRIG_EXT:
- /* set the digital line and interrupt for convert trigger */
- if (cmd->scan_begin_src != TRIG_EXT &&
- cmd->start_src == TRIG_EXT)
- s626_dio_set_irq(dev, cmd->convert_arg);
- break;
- }
-
- s626_reset_adc(dev, ppl);
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- /* Trigger ADC scan loop start */
- /* s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2); */
-
- /* Start executing the RPS program */
- s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
- s->async->inttrig = NULL;
- break;
- case TRIG_EXT:
- /* configure DIO channel for acquisition trigger */
- s626_dio_set_irq(dev, cmd->start_arg);
- s->async->inttrig = NULL;
- break;
- case TRIG_INT:
- s->async->inttrig = s626_ai_inttrig;
- break;
- }
-
- /* enable interrupt */
- writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, dev->mmio + S626_P_IER);
-
- return 0;
-}
-
-static int s626_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src,
- TRIG_NOW | TRIG_INT | TRIG_EXT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src,
- TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src,
- TRIG_TIMER | TRIG_EXT | TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
- err |= comedi_check_trigger_is_unique(cmd->convert_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- switch (cmd->start_src) {
- case TRIG_NOW:
- case TRIG_INT:
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
- break;
- case TRIG_EXT:
- err |= comedi_check_trigger_arg_max(&cmd->start_arg, 39);
- break;
- }
-
- if (cmd->scan_begin_src == TRIG_EXT)
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 39);
- if (cmd->convert_src == TRIG_EXT)
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 39);
-
-#define S626_MAX_SPEED 200000 /* in nanoseconds */
-#define S626_MIN_SPEED 2000000000 /* in nanoseconds */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- S626_MAX_SPEED);
- err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
- S626_MIN_SPEED);
- } else {
- /*
- * external trigger
- * should be level/edge, hi/lo specification here
- * should specify multiple external triggers
- * err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
- */
- }
- if (cmd->convert_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
- S626_MAX_SPEED);
- err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
- S626_MIN_SPEED);
- } else {
- /*
- * external trigger - see above
- * err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
- */
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->scan_begin_arg;
- s626_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- if (cmd->convert_src == TRIG_TIMER) {
- arg = cmd->convert_arg;
- s626_ns_to_timer(&arg, cmd->flags);
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- arg = cmd->convert_arg * cmd->scan_end_arg;
- err |= comedi_check_trigger_arg_min(
- &cmd->scan_begin_arg, arg);
- }
- }
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct s626_private *devpriv = dev->private;
-
- /* Stop RPS program in case it is currently running */
- s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
-
- /* disable master interrupt */
- writel(0, dev->mmio + S626_P_IER);
-
- devpriv->ai_cmd_running = 0;
-
- return 0;
-}
-
-static int s626_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- s16 dacdata = (s16)data[i];
- int ret;
-
- dacdata -= (0x1fff);
-
- ret = s626_set_dac(dev, chan, dacdata);
- if (ret)
- return ret;
-
- s->readback[chan] = data[i];
- }
-
- return insn->n;
-}
-
-/* *************** DIGITAL I/O FUNCTIONS *************** */
-
-/*
- * All DIO functions address a group of DIO channels by means of
- * "group" argument. group may be 0, 1 or 2, which correspond to DIO
- * ports A, B and C, respectively.
- */
-
-static void s626_dio_init(struct comedi_device *dev)
-{
- u16 group;
-
- /* Prepare to treat writes to WRCapSel as capture disables. */
- s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
-
- /* For each group of sixteen channels ... */
- for (group = 0; group < S626_DIO_BANKS; group++) {
- /* Disable all interrupts */
- s626_debi_write(dev, S626_LP_WRINTSEL(group), 0);
- /* Disable all event captures */
- s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff);
- /* Init all DIOs to default edge polarity */
- s626_debi_write(dev, S626_LP_WREDGSEL(group), 0);
- /* Program all outputs to inactive state */
- s626_debi_write(dev, S626_LP_WRDOUT(group), 0);
- }
-}
-
-static int s626_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long group = (unsigned long)s->private;
-
- if (comedi_dio_update_state(s, data))
- s626_debi_write(dev, S626_LP_WRDOUT(group), s->state);
-
- data[1] = s626_debi_read(dev, S626_LP_RDDIN(group));
-
- return insn->n;
-}
-
-static int s626_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned long group = (unsigned long)s->private;
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- s626_debi_write(dev, S626_LP_WRDOUT(group), s->io_bits);
-
- return insn->n;
-}
-
-/*
- * Now this function initializes the value of the counter (data[0])
- * and set the subdevice. To complete with trigger and interrupt
- * configuration.
- *
- * FIXME: data[0] is supposed to be an INSN_CONFIG_xxx constant indicating
- * what is being configured, but this function appears to be using data[0]
- * as a variable.
- */
-static int s626_enc_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- u16 setup =
- /* Preload upon index. */
- S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
- /* Disable hardware index. */
- S626_SET_STD_INDXSRC(S626_INDXSRC_SOFT) |
- /* Operating mode is Counter. */
- S626_SET_STD_ENCMODE(S626_ENCMODE_COUNTER) |
- /* Active high clock. */
- S626_SET_STD_CLKPOL(S626_CLKPOL_POS) |
- /* Clock multiplier is 1x. */
- S626_SET_STD_CLKMULT(S626_CLKMULT_1X) |
- /* Enabled by index */
- S626_SET_STD_CLKENAB(S626_CLKENAB_INDEX);
- /* uint16_t disable_int_src = true; */
- /* uint32_t Preloadvalue; //Counter initial value */
- u16 value_latchsrc = S626_LATCHSRC_AB_READ;
- u16 enab = S626_CLKENAB_ALWAYS;
-
- /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
-
- s626_set_mode(dev, chan, setup, true);
- s626_preload(dev, chan, data[0]);
- s626_pulse_index(dev, chan);
- s626_set_latch_source(dev, chan, value_latchsrc);
- s626_set_enable(dev, chan, (enab != 0));
-
- return insn->n;
-}
-
-static int s626_enc_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- u16 cntr_latch_reg = S626_LP_CNTR(chan);
- int i;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val;
-
- /*
- * Read the counter's output latch LSW/MSW.
- * Latches on LSW read.
- */
- val = s626_debi_read(dev, cntr_latch_reg);
- val |= (s626_debi_read(dev, cntr_latch_reg + 2) << 16);
- data[i] = val;
- }
-
- return insn->n;
-}
-
-static int s626_enc_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /* Set the preload register */
- s626_preload(dev, chan, data[0]);
-
- /*
- * Software index pulse forces the preload register to load
- * into the counter
- */
- s626_set_load_trig(dev, chan, 0);
- s626_pulse_index(dev, chan);
- s626_set_load_trig(dev, chan, 2);
-
- return 1;
-}
-
-static void s626_write_misc2(struct comedi_device *dev, u16 new_image)
-{
- s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_WENABLE);
- s626_debi_write(dev, S626_LP_WRMISC2, new_image);
- s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_WDISABLE);
-}
-
-static void s626_counters_init(struct comedi_device *dev)
-{
- int chan;
- u16 setup =
- /* Preload upon index. */
- S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
- /* Disable hardware index. */
- S626_SET_STD_INDXSRC(S626_INDXSRC_SOFT) |
- /* Operating mode is counter. */
- S626_SET_STD_ENCMODE(S626_ENCMODE_COUNTER) |
- /* Active high clock. */
- S626_SET_STD_CLKPOL(S626_CLKPOL_POS) |
- /* Clock multiplier is 1x. */
- S626_SET_STD_CLKMULT(S626_CLKMULT_1X) |
- /* Enabled by index */
- S626_SET_STD_CLKENAB(S626_CLKENAB_INDEX);
-
- /*
- * Disable all counter interrupts and clear any captured counter events.
- */
- for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
- s626_set_mode(dev, chan, setup, true);
- s626_set_int_src(dev, chan, 0);
- s626_reset_cap_flags(dev, chan);
- s626_set_enable(dev, chan, S626_CLKENAB_ALWAYS);
- }
-}
-
-static int s626_allocate_dma_buffers(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct s626_private *devpriv = dev->private;
- void *addr;
- dma_addr_t appdma;
-
- addr = dma_alloc_coherent(&pcidev->dev, S626_DMABUF_SIZE, &appdma,
- GFP_KERNEL);
- if (!addr)
- return -ENOMEM;
- devpriv->ana_buf.logical_base = addr;
- devpriv->ana_buf.physical_base = appdma;
-
- addr = dma_alloc_coherent(&pcidev->dev, S626_DMABUF_SIZE, &appdma,
- GFP_KERNEL);
- if (!addr)
- return -ENOMEM;
- devpriv->rps_buf.logical_base = addr;
- devpriv->rps_buf.physical_base = appdma;
-
- return 0;
-}
-
-static void s626_free_dma_buffers(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct s626_private *devpriv = dev->private;
-
- if (!devpriv)
- return;
-
- if (devpriv->rps_buf.logical_base)
- dma_free_coherent(&pcidev->dev, S626_DMABUF_SIZE,
- devpriv->rps_buf.logical_base,
- devpriv->rps_buf.physical_base);
- if (devpriv->ana_buf.logical_base)
- dma_free_coherent(&pcidev->dev, S626_DMABUF_SIZE,
- devpriv->ana_buf.logical_base,
- devpriv->ana_buf.physical_base);
-}
-
-static int s626_initialize(struct comedi_device *dev)
-{
- struct s626_private *devpriv = dev->private;
- dma_addr_t phys_buf;
- u16 chan;
- int i;
- int ret;
-
- /* Enable DEBI and audio pins, enable I2C interface */
- s626_mc_enable(dev, S626_MC1_DEBI | S626_MC1_AUDIO | S626_MC1_I2C,
- S626_P_MC1);
-
- /*
- * Configure DEBI operating mode
- *
- * Local bus is 16 bits wide
- * Declare DEBI transfer timeout interval
- * Set up byte lane steering
- * Intel-compatible local bus (DEBI never times out)
- */
- writel(S626_DEBI_CFG_SLAVE16 |
- (S626_DEBI_TOUT << S626_DEBI_CFG_TOUT_BIT) | S626_DEBI_SWAP |
- S626_DEBI_CFG_INTEL, dev->mmio + S626_P_DEBICFG);
-
- /* Disable MMU paging */
- writel(S626_DEBI_PAGE_DISABLE, dev->mmio + S626_P_DEBIPAGE);
-
- /* Init GPIO so that ADC Start* is negated */
- writel(S626_GPIO_BASE | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
-
- /* I2C device address for onboard eeprom (revb) */
- devpriv->i2c_adrs = 0xA0;
-
- /*
- * Issue an I2C ABORT command to halt any I2C
- * operation in progress and reset BUSY flag.
- */
- writel(S626_I2C_CLKSEL | S626_I2C_ABORT,
- dev->mmio + S626_P_I2CSTAT);
- s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
- if (ret)
- return ret;
-
- /*
- * Per SAA7146 data sheet, write to STATUS
- * reg twice to reset all I2C error flags.
- */
- for (i = 0; i < 2; i++) {
- writel(S626_I2C_CLKSEL, dev->mmio + S626_P_I2CSTAT);
- s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
- ret = comedi_timeout(dev, NULL,
- NULL, s626_i2c_handshake_eoc, 0);
- if (ret)
- return ret;
- }
-
- /*
- * Init audio interface functional attributes: set DAC/ADC
- * serial clock rates, invert DAC serial clock so that
- * DAC data setup times are satisfied, enable DAC serial
- * clock out.
- */
- writel(S626_ACON2_INIT, dev->mmio + S626_P_ACON2);
-
- /*
- * Set up TSL1 slot list, which is used to control the
- * accumulation of ADC data: S626_RSD1 = shift data in on SD1.
- * S626_SIB_A1 = store data uint8_t at next available location
- * in FB BUFFER1 register.
- */
- writel(S626_RSD1 | S626_SIB_A1, dev->mmio + S626_P_TSL1);
- writel(S626_RSD1 | S626_SIB_A1 | S626_EOS,
- dev->mmio + S626_P_TSL1 + 4);
-
- /* Enable TSL1 slot list so that it executes all the time */
- writel(S626_ACON1_ADCSTART, dev->mmio + S626_P_ACON1);
-
- /*
- * Initialize RPS registers used for ADC
- */
-
- /* Physical start of RPS program */
- writel((u32)devpriv->rps_buf.physical_base,
- dev->mmio + S626_P_RPSADDR1);
- /* RPS program performs no explicit mem writes */
- writel(0, dev->mmio + S626_P_RPSPAGE1);
- /* Disable RPS timeouts */
- writel(0, dev->mmio + S626_P_RPS1_TOUT);
-
-#if 0
- /*
- * SAA7146 BUG WORKAROUND
- *
- * Initialize SAA7146 ADC interface to a known state by
- * invoking ADCs until FB BUFFER 1 register shows that it
- * is correctly receiving ADC data. This is necessary
- * because the SAA7146 ADC interface does not start up in
- * a defined state after a PCI reset.
- */
- {
- struct comedi_subdevice *s = dev->read_subdev;
- u8 poll_list;
- u16 adc_data;
- u16 start_val;
- u16 index;
- unsigned int data[16];
-
- /* Create a simple polling list for analog input channel 0 */
- poll_list = S626_EOPL;
- s626_reset_adc(dev, &poll_list);
-
- /* Get initial ADC value */
- s626_ai_rinsn(dev, s, NULL, data);
- start_val = data[0];
-
- /*
- * VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED
- * EXECUTION.
- *
- * Invoke ADCs until the new ADC value differs from the initial
- * value or a timeout occurs. The timeout protects against the
- * possibility that the driver is restarting and the ADC data is
- * a fixed value resulting from the applied ADC analog input
- * being unusually quiet or at the rail.
- */
- for (index = 0; index < 500; index++) {
- s626_ai_rinsn(dev, s, NULL, data);
- adc_data = data[0];
- if (adc_data != start_val)
- break;
- }
- }
-#endif /* SAA7146 BUG WORKAROUND */
-
- /*
- * Initialize the DAC interface
- */
-
- /*
- * Init Audio2's output DMAC attributes:
- * burst length = 1 DWORD
- * threshold = 1 DWORD.
- */
- writel(0, dev->mmio + S626_P_PCI_BT_A);
-
- /*
- * Init Audio2's output DMA physical addresses. The protection
- * address is set to 1 DWORD past the base address so that a
- * single DWORD will be transferred each time a DMA transfer is
- * enabled.
- */
- phys_buf = devpriv->ana_buf.physical_base +
- (S626_DAC_WDMABUF_OS * sizeof(u32));
- writel((u32)phys_buf, dev->mmio + S626_P_BASEA2_OUT);
- writel((u32)(phys_buf + sizeof(u32)),
- dev->mmio + S626_P_PROTA2_OUT);
-
- /*
- * Cache Audio2's output DMA buffer logical address. This is
- * where DAC data is buffered for A2 output DMA transfers.
- */
- devpriv->dac_wbuf = (u32 *)devpriv->ana_buf.logical_base +
- S626_DAC_WDMABUF_OS;
-
- /*
- * Audio2's output channels does not use paging. The
- * protection violation handling bit is set so that the
- * DMAC will automatically halt and its PCI address pointer
- * will be reset when the protection address is reached.
- */
- writel(8, dev->mmio + S626_P_PAGEA2_OUT);
-
- /*
- * Initialize time slot list 2 (TSL2), which is used to control
- * the clock generation for and serialization of data to be sent
- * to the DAC devices. Slot 0 is a NOP that is used to trap TSL
- * execution; this permits other slots to be safely modified
- * without first turning off the TSL sequencer (which is
- * apparently impossible to do). Also, SD3 (which is driven by a
- * pull-up resistor) is shifted in and stored to the MSB of
- * FB_BUFFER2 to be used as evidence that the slot sequence has
- * not yet finished executing.
- */
-
- /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */
- writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2 | S626_EOS,
- dev->mmio + S626_VECTPORT(0));
-
- /*
- * Initialize slot 1, which is constant. Slot 1 causes a
- * DWORD to be transferred from audio channel 2's output FIFO
- * to the FIFO's output buffer so that it can be serialized
- * and sent to the DAC during subsequent slots. All remaining
- * slots are dynamically populated as required by the target
- * DAC device.
- */
-
- /* Slot 1: Fetch DWORD from Audio2's output FIFO */
- writel(S626_LF_A2, dev->mmio + S626_VECTPORT(1));
-
- /* Start DAC's audio interface (TSL2) running */
- writel(S626_ACON1_DACSTART, dev->mmio + S626_P_ACON1);
-
- /*
- * Init Trim DACs to calibrated values. Do it twice because the
- * SAA7146 audio channel does not always reset properly and
- * sometimes causes the first few TrimDAC writes to malfunction.
- */
- s626_load_trim_dacs(dev);
- ret = s626_load_trim_dacs(dev);
- if (ret)
- return ret;
-
- /*
- * Manually init all gate array hardware in case this is a soft
- * reset (we have no way of determining whether this is a warm
- * or cold start). This is necessary because the gate array will
- * reset only in response to a PCI hard reset; there is no soft
- * reset function.
- */
-
- /*
- * Init all DAC outputs to 0V and init all DAC setpoint and
- * polarity images.
- */
- for (chan = 0; chan < S626_DAC_CHANNELS; chan++) {
- ret = s626_set_dac(dev, chan, 0);
- if (ret)
- return ret;
- }
-
- /* Init counters */
- s626_counters_init(dev);
-
- /*
- * Without modifying the state of the Battery Backup enab, disable
- * the watchdog timer, set DIO channels 0-5 to operate in the
- * standard DIO (vs. counter overflow) mode, disable the battery
- * charger, and reset the watchdog interval selector to zero.
- */
- s626_write_misc2(dev, (s626_debi_read(dev, S626_LP_RDMISC2) &
- S626_MISC2_BATT_ENABLE));
-
- /* Initialize the digital I/O subsystem */
- s626_dio_init(dev);
-
- return 0;
-}
-
-static int s626_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct s626_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
-
- dev->mmio = pci_ioremap_bar(pcidev, 0);
- if (!dev->mmio)
- return -ENOMEM;
-
- /* disable master interrupt */
- writel(0, dev->mmio + S626_P_IER);
-
- /* soft reset */
- writel(S626_MC1_SOFT_RESET, dev->mmio + S626_P_MC1);
-
- /* DMA FIXME DMA// */
-
- ret = s626_allocate_dma_buffers(dev);
- if (ret)
- return ret;
-
- if (pcidev->irq) {
- ret = request_irq(pcidev->irq, s626_irq_handler, IRQF_SHARED,
- dev->board_name, dev);
-
- if (ret == 0)
- dev->irq = pcidev->irq;
- }
-
- ret = comedi_alloc_subdevices(dev, 6);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF;
- s->n_chan = S626_ADC_CHANNELS;
- s->maxdata = 0x3fff;
- s->range_table = &s626_range_table;
- s->len_chanlist = S626_ADC_CHANNELS;
- s->insn_read = s626_ai_insn_read;
- if (dev->irq) {
- dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->do_cmd = s626_ai_cmd;
- s->do_cmdtest = s626_ai_cmdtest;
- s->cancel = s626_ai_cancel;
- }
-
- s = &dev->subdevices[1];
- /* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = S626_DAC_CHANNELS;
- s->maxdata = 0x3fff;
- s->range_table = &range_bipolar10;
- s->insn_write = s626_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- s = &dev->subdevices[2];
- /* digital I/O subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->io_bits = 0xffff;
- s->private = (void *)0; /* DIO group 0 */
- s->range_table = &range_digital;
- s->insn_config = s626_dio_insn_config;
- s->insn_bits = s626_dio_insn_bits;
-
- s = &dev->subdevices[3];
- /* digital I/O subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->io_bits = 0xffff;
- s->private = (void *)1; /* DIO group 1 */
- s->range_table = &range_digital;
- s->insn_config = s626_dio_insn_config;
- s->insn_bits = s626_dio_insn_bits;
-
- s = &dev->subdevices[4];
- /* digital I/O subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->io_bits = 0xffff;
- s->private = (void *)2; /* DIO group 2 */
- s->range_table = &range_digital;
- s->insn_config = s626_dio_insn_config;
- s->insn_bits = s626_dio_insn_bits;
-
- s = &dev->subdevices[5];
- /* encoder (counter) subdevice */
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
- s->n_chan = S626_ENCODER_CHANNELS;
- s->maxdata = 0xffffff;
- s->range_table = &range_unknown;
- s->insn_config = s626_enc_insn_config;
- s->insn_read = s626_enc_insn_read;
- s->insn_write = s626_enc_insn_write;
-
- return s626_initialize(dev);
-}
-
-static void s626_detach(struct comedi_device *dev)
-{
- struct s626_private *devpriv = dev->private;
-
- if (devpriv) {
- /* stop ai_command */
- devpriv->ai_cmd_running = 0;
-
- if (dev->mmio) {
- /* interrupt mask */
- /* Disable master interrupt */
- writel(0, dev->mmio + S626_P_IER);
- /* Clear board's IRQ status flag */
- writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1,
- dev->mmio + S626_P_ISR);
-
- /* Disable the watchdog timer and battery charger. */
- s626_write_misc2(dev, 0);
-
- /* Close all interfaces on 7146 device */
- writel(S626_MC1_SHUTDOWN, dev->mmio + S626_P_MC1);
- writel(S626_ACON1_BASE, dev->mmio + S626_P_ACON1);
- }
- }
- comedi_pci_detach(dev);
- s626_free_dma_buffers(dev);
-}
-
-static struct comedi_driver s626_driver = {
- .driver_name = "s626",
- .module = THIS_MODULE,
- .auto_attach = s626_auto_attach,
- .detach = s626_detach,
-};
-
-static int s626_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &s626_driver, id->driver_data);
-}
-
-/*
- * For devices with vendor:device id == 0x1131:0x7146 you must specify
- * also subvendor:subdevice ids, because otherwise it will conflict with
- * Philips SAA7146 media/dvb based cards.
- */
-static const struct pci_device_id s626_pci_table[] = {
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146,
- 0x6000, 0x0272) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, s626_pci_table);
-
-static struct pci_driver s626_pci_driver = {
- .name = "s626",
- .id_table = s626_pci_table,
- .probe = s626_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(s626_driver, s626_pci_driver);
-
-MODULE_AUTHOR("Gianluca Palli <gpalli@deis.unibo.it>");
-MODULE_DESCRIPTION("Sensoray 626 Comedi driver module");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
deleted file mode 100644
index 749252b1d26b..000000000000
--- a/drivers/staging/comedi/drivers/s626.h
+++ /dev/null
@@ -1,869 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * comedi/drivers/s626.h
- * Sensoray s626 Comedi driver, header file
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- *
- * Based on Sensoray Model 626 Linux driver Version 0.2
- * Copyright (C) 2002-2004 Sensoray Co., Inc.
- */
-
-#ifndef S626_H_INCLUDED
-#define S626_H_INCLUDED
-
-#define S626_DMABUF_SIZE 4096 /* 4k pages */
-
-#define S626_ADC_CHANNELS 16
-#define S626_DAC_CHANNELS 4
-#define S626_ENCODER_CHANNELS 6
-#define S626_DIO_CHANNELS 48
-#define S626_DIO_BANKS 3 /* Number of DIO groups. */
-#define S626_DIO_EXTCHANS 40 /*
- * Number of extended-capability
- * DIO channels.
- */
-
-#define S626_NUM_TRIMDACS 12 /* Number of valid TrimDAC channels. */
-
-/* PCI bus interface types. */
-#define S626_INTEL 1 /* Intel bus type. */
-#define S626_MOTOROLA 2 /* Motorola bus type. */
-
-#define S626_PLATFORM S626_INTEL /* *** SELECT PLATFORM TYPE *** */
-
-#define S626_RANGE_5V 0x10 /* +/-5V range */
-#define S626_RANGE_10V 0x00 /* +/-10V range */
-
-#define S626_EOPL 0x80 /* End of ADC poll list marker. */
-#define S626_GSEL_BIPOLAR5V 0x00F0 /* S626_LP_GSEL setting 5V bipolar. */
-#define S626_GSEL_BIPOLAR10V 0x00A0 /* S626_LP_GSEL setting 10V bipolar. */
-
-/* Error codes that must be visible to this base class. */
-#define S626_ERR_ILLEGAL_PARM 0x00010000 /*
- * Illegal function parameter
- * value was specified.
- */
-#define S626_ERR_I2C 0x00020000 /* I2C error. */
-#define S626_ERR_COUNTERSETUP 0x00200000 /*
- * Illegal setup specified for
- * counter channel.
- */
-#define S626_ERR_DEBI_TIMEOUT 0x00400000 /* DEBI transfer timed out. */
-
-/*
- * Organization (physical order) and size (in DWORDs) of logical DMA buffers
- * contained by ANA_DMABUF.
- */
-#define S626_ADC_DMABUF_DWORDS 40 /*
- * ADC DMA buffer must hold 16 samples,
- * plus pre/post garbage samples.
- */
-#define S626_DAC_WDMABUF_DWORDS 1 /*
- * DAC output DMA buffer holds a single
- * sample.
- */
-
-/* All remaining space in 4KB DMA buffer is available for the RPS1 program. */
-
-/* Address offsets, in DWORDS, from base of DMA buffer. */
-#define S626_DAC_WDMABUF_OS S626_ADC_DMABUF_DWORDS
-
-/* Interrupt enable bit in ISR and IER. */
-#define S626_IRQ_GPIO3 0x00000040 /* IRQ enable for GPIO3. */
-#define S626_IRQ_RPS1 0x10000000
-#define S626_ISR_AFOU 0x00000800
-/* Audio fifo under/overflow detected. */
-
-#define S626_IRQ_COINT1A 0x0400 /* counter 1A overflow interrupt mask */
-#define S626_IRQ_COINT1B 0x0800 /* counter 1B overflow interrupt mask */
-#define S626_IRQ_COINT2A 0x1000 /* counter 2A overflow interrupt mask */
-#define S626_IRQ_COINT2B 0x2000 /* counter 2B overflow interrupt mask */
-#define S626_IRQ_COINT3A 0x4000 /* counter 3A overflow interrupt mask */
-#define S626_IRQ_COINT3B 0x8000 /* counter 3B overflow interrupt mask */
-
-/* RPS command codes. */
-#define S626_RPS_CLRSIGNAL 0x00000000 /* CLEAR SIGNAL */
-#define S626_RPS_SETSIGNAL 0x10000000 /* SET SIGNAL */
-#define S626_RPS_NOP 0x00000000 /* NOP */
-#define S626_RPS_PAUSE 0x20000000 /* PAUSE */
-#define S626_RPS_UPLOAD 0x40000000 /* UPLOAD */
-#define S626_RPS_JUMP 0x80000000 /* JUMP */
-#define S626_RPS_LDREG 0x90000100 /* LDREG (1 uint32_t only) */
-#define S626_RPS_STREG 0xA0000100 /* STREG (1 uint32_t only) */
-#define S626_RPS_STOP 0x50000000 /* STOP */
-#define S626_RPS_IRQ 0x60000000 /* IRQ */
-
-#define S626_RPS_LOGICAL_OR 0x08000000 /* Logical OR conditionals. */
-#define S626_RPS_INVERT 0x04000000 /*
- * Test for negated
- * semaphores.
- */
-#define S626_RPS_DEBI 0x00000002 /* DEBI done */
-
-#define S626_RPS_SIG0 0x00200000 /*
- * RPS semaphore 0
- * (used by ADC).
- */
-#define S626_RPS_SIG1 0x00400000 /*
- * RPS semaphore 1
- * (used by DAC).
- */
-#define S626_RPS_SIG2 0x00800000 /*
- * RPS semaphore 2
- * (not used).
- */
-#define S626_RPS_GPIO2 0x00080000 /* RPS GPIO2 */
-#define S626_RPS_GPIO3 0x00100000 /* RPS GPIO3 */
-
-#define S626_RPS_SIGADC S626_RPS_SIG0 /*
- * Trigger/status for
- * ADC's RPS program.
- */
-#define S626_RPS_SIGDAC S626_RPS_SIG1 /*
- * Trigger/status for
- * DAC's RPS program.
- */
-
-/* RPS clock parameters. */
-#define S626_RPSCLK_SCALAR 8 /*
- * This is apparent ratio of
- * PCI/RPS clks (undocumented!!).
- */
-#define S626_RPSCLK_PER_US (33 / S626_RPSCLK_SCALAR)
- /*
- * Number of RPS clocks in one
- * microsecond.
- */
-
-/* Event counter source addresses. */
-#define S626_SBA_RPS_A0 0x27 /* Time of RPS0 busy, in PCI clocks. */
-
-/* GPIO constants. */
-#define S626_GPIO_BASE 0x10004000 /*
- * GPIO 0,2,3 = inputs,
- * GPIO3 = IRQ; GPIO1 = out.
- */
-#define S626_GPIO1_LO 0x00000000 /* GPIO1 set to LOW. */
-#define S626_GPIO1_HI 0x00001000 /* GPIO1 set to HIGH. */
-
-/* Primary Status Register (PSR) constants. */
-#define S626_PSR_DEBI_E 0x00040000 /* DEBI event flag. */
-#define S626_PSR_DEBI_S 0x00080000 /* DEBI status flag. */
-#define S626_PSR_A2_IN 0x00008000 /*
- * Audio output DMA2 protection
- * address reached.
- */
-#define S626_PSR_AFOU 0x00000800 /*
- * Audio FIFO under/overflow
- * detected.
- */
-#define S626_PSR_GPIO2 0x00000020 /*
- * GPIO2 input pin: 0=AdcBusy,
- * 1=AdcIdle.
- */
-#define S626_PSR_EC0S 0x00000001 /*
- * Event counter 0 threshold
- * reached.
- */
-
-/* Secondary Status Register (SSR) constants. */
-#define S626_SSR_AF2_OUT 0x00000200 /*
- * Audio 2 output FIFO
- * under/overflow detected.
- */
-
-/* Master Control Register 1 (MC1) constants. */
-#define S626_MC1_SOFT_RESET 0x80000000 /* Invoke 7146 soft reset. */
-#define S626_MC1_SHUTDOWN 0x3FFF0000 /*
- * Shut down all MC1-controlled
- * enables.
- */
-
-#define S626_MC1_ERPS1 0x2000 /* Enab/disable RPS task 1. */
-#define S626_MC1_ERPS0 0x1000 /* Enab/disable RPS task 0. */
-#define S626_MC1_DEBI 0x0800 /* Enab/disable DEBI pins. */
-#define S626_MC1_AUDIO 0x0200 /* Enab/disable audio port pins. */
-#define S626_MC1_I2C 0x0100 /* Enab/disable I2C interface. */
-#define S626_MC1_A2OUT 0x0008 /* Enab/disable transfer on A2 out. */
-#define S626_MC1_A2IN 0x0004 /* Enab/disable transfer on A2 in. */
-#define S626_MC1_A1IN 0x0001 /* Enab/disable transfer on A1 in. */
-
-/* Master Control Register 2 (MC2) constants. */
-#define S626_MC2_UPLD_DEBI 0x0002 /* Upload DEBI. */
-#define S626_MC2_UPLD_IIC 0x0001 /* Upload I2C. */
-#define S626_MC2_RPSSIG2 0x2000 /* RPS signal 2 (not used). */
-#define S626_MC2_RPSSIG1 0x1000 /* RPS signal 1 (DAC RPS busy). */
-#define S626_MC2_RPSSIG0 0x0800 /* RPS signal 0 (ADC RPS busy). */
-
-#define S626_MC2_ADC_RPS S626_MC2_RPSSIG0 /* ADC RPS busy. */
-#define S626_MC2_DAC_RPS S626_MC2_RPSSIG1 /* DAC RPS busy. */
-
-/* PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
-#define S626_P_PCI_BT_A 0x004C /* Audio DMA burst/threshold control. */
-#define S626_P_DEBICFG 0x007C /* DEBI configuration. */
-#define S626_P_DEBICMD 0x0080 /* DEBI command. */
-#define S626_P_DEBIPAGE 0x0084 /* DEBI page. */
-#define S626_P_DEBIAD 0x0088 /* DEBI target address. */
-#define S626_P_I2CCTRL 0x008C /* I2C control. */
-#define S626_P_I2CSTAT 0x0090 /* I2C status. */
-#define S626_P_BASEA2_IN 0x00AC /*
- * Audio input 2 base physical DMAbuf
- * address.
- */
-#define S626_P_PROTA2_IN 0x00B0 /*
- * Audio input 2 physical DMAbuf
- * protection address.
- */
-#define S626_P_PAGEA2_IN 0x00B4 /* Audio input 2 paging attributes. */
-#define S626_P_BASEA2_OUT 0x00B8 /*
- * Audio output 2 base physical DMAbuf
- * address.
- */
-#define S626_P_PROTA2_OUT 0x00BC /*
- * Audio output 2 physical DMAbuf
- * protection address.
- */
-#define S626_P_PAGEA2_OUT 0x00C0 /* Audio output 2 paging attributes. */
-#define S626_P_RPSPAGE0 0x00C4 /* RPS0 page. */
-#define S626_P_RPSPAGE1 0x00C8 /* RPS1 page. */
-#define S626_P_RPS0_TOUT 0x00D4 /* RPS0 time-out. */
-#define S626_P_RPS1_TOUT 0x00D8 /* RPS1 time-out. */
-#define S626_P_IER 0x00DC /* Interrupt enable. */
-#define S626_P_GPIO 0x00E0 /* General-purpose I/O. */
-#define S626_P_EC1SSR 0x00E4 /* Event counter set 1 source select. */
-#define S626_P_ECT1R 0x00EC /* Event counter threshold set 1. */
-#define S626_P_ACON1 0x00F4 /* Audio control 1. */
-#define S626_P_ACON2 0x00F8 /* Audio control 2. */
-#define S626_P_MC1 0x00FC /* Master control 1. */
-#define S626_P_MC2 0x0100 /* Master control 2. */
-#define S626_P_RPSADDR0 0x0104 /* RPS0 instruction pointer. */
-#define S626_P_RPSADDR1 0x0108 /* RPS1 instruction pointer. */
-#define S626_P_ISR 0x010C /* Interrupt status. */
-#define S626_P_PSR 0x0110 /* Primary status. */
-#define S626_P_SSR 0x0114 /* Secondary status. */
-#define S626_P_EC1R 0x0118 /* Event counter set 1. */
-#define S626_P_ADP4 0x0138 /*
- * Logical audio DMA pointer of audio
- * input FIFO A2_IN.
- */
-#define S626_P_FB_BUFFER1 0x0144 /* Audio feedback buffer 1. */
-#define S626_P_FB_BUFFER2 0x0148 /* Audio feedback buffer 2. */
-#define S626_P_TSL1 0x0180 /* Audio time slot list 1. */
-#define S626_P_TSL2 0x01C0 /* Audio time slot list 2. */
-
-/* LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
-/* Analog I/O registers: */
-#define S626_LP_DACPOL 0x0082 /* Write DAC polarity. */
-#define S626_LP_GSEL 0x0084 /* Write ADC gain. */
-#define S626_LP_ISEL 0x0086 /* Write ADC channel select. */
-
-/* Digital I/O registers */
-#define S626_LP_RDDIN(x) (0x0040 + (x) * 0x10) /* R: digital input */
-#define S626_LP_WRINTSEL(x) (0x0042 + (x) * 0x10) /* W: int enable */
-#define S626_LP_WREDGSEL(x) (0x0044 + (x) * 0x10) /* W: edge selection */
-#define S626_LP_WRCAPSEL(x) (0x0046 + (x) * 0x10) /* W: capture enable */
-#define S626_LP_RDCAPFLG(x) (0x0048 + (x) * 0x10) /* R: edges captured */
-#define S626_LP_WRDOUT(x) (0x0048 + (x) * 0x10) /* W: digital output */
-#define S626_LP_RDINTSEL(x) (0x004a + (x) * 0x10) /* R: int enable */
-#define S626_LP_RDEDGSEL(x) (0x004c + (x) * 0x10) /* R: edge selection */
-#define S626_LP_RDCAPSEL(x) (0x004e + (x) * 0x10) /* R: capture enable */
-
-/* Counter registers (read/write): 0A 1A 2A 0B 1B 2B */
-#define S626_LP_CRA(x) (0x0000 + (((x) % 3) * 0x4))
-#define S626_LP_CRB(x) (0x0002 + (((x) % 3) * 0x4))
-
-/* Counter PreLoad (write) and Latch (read) Registers: 0A 1A 2A 0B 1B 2B */
-#define S626_LP_CNTR(x) (0x000c + (((x) < 3) ? 0x0 : 0x4) + \
- (((x) % 3) * 0x8))
-
-/* Miscellaneous Registers (read/write): */
-#define S626_LP_MISC1 0x0088 /* Read/write Misc1. */
-#define S626_LP_WRMISC2 0x0090 /* Write Misc2. */
-#define S626_LP_RDMISC2 0x0082 /* Read Misc2. */
-
-/* Bit masks for MISC1 register that are the same for reads and writes. */
-#define S626_MISC1_WENABLE 0x8000 /*
- * enab writes to MISC2 (except Clear
- * Watchdog bit).
- */
-#define S626_MISC1_WDISABLE 0x0000 /* Disable writes to MISC2. */
-#define S626_MISC1_EDCAP 0x1000 /*
- * Enable edge capture on DIO chans
- * specified by S626_LP_WRCAPSELx.
- */
-#define S626_MISC1_NOEDCAP 0x0000 /*
- * Disable edge capture on specified
- * DIO chans.
- */
-
-/* Bit masks for MISC1 register reads. */
-#define S626_RDMISC1_WDTIMEOUT 0x4000 /* Watchdog timer timed out. */
-
-/* Bit masks for MISC2 register writes. */
-#define S626_WRMISC2_WDCLEAR 0x8000 /* Reset watchdog timer to zero. */
-#define S626_WRMISC2_CHARGE_ENABLE 0x4000 /* Enable battery trickle charging. */
-
-/* Bit masks for MISC2 register that are the same for reads and writes. */
-#define S626_MISC2_BATT_ENABLE 0x0008 /* Backup battery enable. */
-#define S626_MISC2_WDENABLE 0x0004 /* Watchdog timer enable. */
-#define S626_MISC2_WDPERIOD_MASK 0x0003 /* Watchdog interval select mask. */
-
-/* Bit masks for ACON1 register. */
-#define S626_A2_RUN 0x40000000 /* Run A2 based on TSL2. */
-#define S626_A1_RUN 0x20000000 /* Run A1 based on TSL1. */
-#define S626_A1_SWAP 0x00200000 /* Use big-endian for A1. */
-#define S626_A2_SWAP 0x00100000 /* Use big-endian for A2. */
-#define S626_WS_MODES 0x00019999 /*
- * WS0 = TSL1 trigger input,
- * WS1-WS4 = CS* outputs.
- */
-
-#if (S626_PLATFORM == S626_INTEL) /*
- * Base ACON1 config: always run
- * A1 based on TSL1.
- */
-#define S626_ACON1_BASE (S626_WS_MODES | S626_A1_RUN)
-#elif S626_PLATFORM == S626_MOTOROLA
-#define S626_ACON1_BASE \
- (S626_WS_MODES | S626_A1_RUN | S626_A1_SWAP | S626_A2_SWAP)
-#endif
-
-#define S626_ACON1_ADCSTART S626_ACON1_BASE /*
- * Start ADC: run A1
- * based on TSL1.
- */
-#define S626_ACON1_DACSTART (S626_ACON1_BASE | S626_A2_RUN)
-/* Start transmit to DAC: run A2 based on TSL2. */
-#define S626_ACON1_DACSTOP S626_ACON1_BASE /* Halt A2. */
-
-/* Bit masks for ACON2 register. */
-#define S626_A1_CLKSRC_BCLK1 0x00000000 /* A1 bit rate = BCLK1 (ADC). */
-#define S626_A2_CLKSRC_X1 0x00800000 /*
- * A2 bit rate = ACLK/1
- * (DACs).
- */
-#define S626_A2_CLKSRC_X2 0x00C00000 /*
- * A2 bit rate = ACLK/2
- * (DACs).
- */
-#define S626_A2_CLKSRC_X4 0x01400000 /*
- * A2 bit rate = ACLK/4
- * (DACs).
- */
-#define S626_INVERT_BCLK2 0x00100000 /* Invert BCLK2 (DACs). */
-#define S626_BCLK2_OE 0x00040000 /* Enable BCLK2 (DACs). */
-#define S626_ACON2_XORMASK 0x000C0000 /*
- * XOR mask for ACON2
- * active-low bits.
- */
-
-#define S626_ACON2_INIT (S626_ACON2_XORMASK ^ \
- (S626_A1_CLKSRC_BCLK1 | S626_A2_CLKSRC_X2 | \
- S626_INVERT_BCLK2 | S626_BCLK2_OE))
-
-/* Bit masks for timeslot records. */
-#define S626_WS1 0x40000000 /* WS output to assert. */
-#define S626_WS2 0x20000000
-#define S626_WS3 0x10000000
-#define S626_WS4 0x08000000
-#define S626_RSD1 0x01000000 /* Shift A1 data in on SD1. */
-#define S626_SDW_A1 0x00800000 /*
- * Store rcv'd char at next char
- * slot of DWORD1 buffer.
- */
-#define S626_SIB_A1 0x00400000 /*
- * Store rcv'd char at next
- * char slot of FB1 buffer.
- */
-#define S626_SF_A1 0x00200000 /*
- * Write unsigned long
- * buffer to input FIFO.
- */
-
-/* Select parallel-to-serial converter's data source: */
-#define S626_XFIFO_0 0x00000000 /* Data fifo byte 0. */
-#define S626_XFIFO_1 0x00000010 /* Data fifo byte 1. */
-#define S626_XFIFO_2 0x00000020 /* Data fifo byte 2. */
-#define S626_XFIFO_3 0x00000030 /* Data fifo byte 3. */
-#define S626_XFB0 0x00000040 /* FB_BUFFER byte 0. */
-#define S626_XFB1 0x00000050 /* FB_BUFFER byte 1. */
-#define S626_XFB2 0x00000060 /* FB_BUFFER byte 2. */
-#define S626_XFB3 0x00000070 /* FB_BUFFER byte 3. */
-#define S626_SIB_A2 0x00000200 /*
- * Store next dword from A2's
- * input shifter to FB2
- * buffer.
- */
-#define S626_SF_A2 0x00000100 /*
- * Store next dword from A2's
- * input shifter to its input
- * fifo.
- */
-#define S626_LF_A2 0x00000080 /*
- * Load next dword from A2's
- * output fifo into its
- * output dword buffer.
- */
-#define S626_XSD2 0x00000008 /* Shift data out on SD2. */
-#define S626_RSD3 0x00001800 /* Shift data in on SD3. */
-#define S626_RSD2 0x00001000 /* Shift data in on SD2. */
-#define S626_LOW_A2 0x00000002 /*
- * Drive last SD low for 7 clks,
- * then tri-state.
- */
-#define S626_EOS 0x00000001 /* End of superframe. */
-
-/* I2C configuration constants. */
-#define S626_I2C_CLKSEL 0x0400 /*
- * I2C bit rate =
- * PCIclk/480 = 68.75 KHz.
- */
-#define S626_I2C_BITRATE 68.75 /*
- * I2C bus data bit rate
- * (determined by
- * S626_I2C_CLKSEL) in KHz.
- */
-#define S626_I2C_WRTIME 15.0 /*
- * Worst case time, in msec,
- * for EEPROM internal write
- * op.
- */
-
-/* I2C manifest constants. */
-
-/* Max retries to wait for EEPROM write. */
-#define S626_I2C_RETRIES (S626_I2C_WRTIME * S626_I2C_BITRATE / 9.0)
-#define S626_I2C_ERR 0x0002 /* I2C control/status flag ERROR. */
-#define S626_I2C_BUSY 0x0001 /* I2C control/status flag BUSY. */
-#define S626_I2C_ABORT 0x0080 /* I2C status flag ABORT. */
-#define S626_I2C_ATTRSTART 0x3 /* I2C attribute START. */
-#define S626_I2C_ATTRCONT 0x2 /* I2C attribute CONT. */
-#define S626_I2C_ATTRSTOP 0x1 /* I2C attribute STOP. */
-#define S626_I2C_ATTRNOP 0x0 /* I2C attribute NOP. */
-
-/* Code macros used for constructing I2C command bytes. */
-#define S626_I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
-#define S626_I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
-#define S626_I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8))
-
-/* DEBI command constants. */
-#define S626_DEBI_CMD_SIZE16 (2 << 17) /*
- * Transfer size is always
- * 2 bytes.
- */
-#define S626_DEBI_CMD_READ 0x00010000 /* Read operation. */
-#define S626_DEBI_CMD_WRITE 0x00000000 /* Write operation. */
-
-/* Read immediate 2 bytes. */
-#define S626_DEBI_CMD_RDWORD (S626_DEBI_CMD_READ | S626_DEBI_CMD_SIZE16)
-
-/* Write immediate 2 bytes. */
-#define S626_DEBI_CMD_WRWORD (S626_DEBI_CMD_WRITE | S626_DEBI_CMD_SIZE16)
-
-/* DEBI configuration constants. */
-#define S626_DEBI_CFG_XIRQ_EN 0x80000000 /*
- * Enable external interrupt
- * on GPIO3.
- */
-#define S626_DEBI_CFG_XRESUME 0x40000000 /* Resume block */
- /*
- * Transfer when XIRQ
- * deasserted.
- */
-#define S626_DEBI_CFG_TOQ 0x03C00000 /* Timeout (15 PCI cycles). */
-#define S626_DEBI_CFG_FAST 0x10000000 /* Fast mode enable. */
-
-/* 4-bit field that specifies DEBI timeout value in PCI clock cycles: */
-#define S626_DEBI_CFG_TOUT_BIT 22 /*
- * Finish DEBI cycle after this many
- * clocks.
- */
-
-/* 2-bit field that specifies Endian byte lane steering: */
-#define S626_DEBI_CFG_SWAP_NONE 0x00000000 /*
- * Straight - don't swap any
- * bytes (Intel).
- */
-#define S626_DEBI_CFG_SWAP_2 0x00100000 /* 2-byte swap (Motorola). */
-#define S626_DEBI_CFG_SWAP_4 0x00200000 /* 4-byte swap. */
-#define S626_DEBI_CFG_SLAVE16 0x00080000 /*
- * Slave is able to serve
- * 16-bit cycles.
- */
-#define S626_DEBI_CFG_INC 0x00040000 /*
- * Enable address increment
- * for block transfers.
- */
-#define S626_DEBI_CFG_INTEL 0x00020000 /* Intel style local bus. */
-#define S626_DEBI_CFG_TIMEROFF 0x00010000 /* Disable timer. */
-
-#if S626_PLATFORM == S626_INTEL
-
-#define S626_DEBI_TOUT 7 /*
- * Wait 7 PCI clocks (212 ns) before
- * polling RDY.
- */
-
-/* Intel byte lane steering (pass through all byte lanes). */
-#define S626_DEBI_SWAP S626_DEBI_CFG_SWAP_NONE
-
-#elif S626_PLATFORM == S626_MOTOROLA
-
-#define S626_DEBI_TOUT 15 /*
- * Wait 15 PCI clocks (454 ns) maximum
- * before timing out.
- */
-
-/* Motorola byte lane steering. */
-#define S626_DEBI_SWAP S626_DEBI_CFG_SWAP_2
-
-#endif
-
-/* DEBI page table constants. */
-#define S626_DEBI_PAGE_DISABLE 0x00000000 /* Paging disable. */
-
-/* ******* EXTRA FROM OTHER SENSORAY * .h ******* */
-
-/* LoadSrc values: */
-#define S626_LOADSRC_INDX 0 /* Preload core in response to Index. */
-#define S626_LOADSRC_OVER 1 /*
- * Preload core in response to
- * Overflow.
- */
-#define S626_LOADSRCB_OVERA 2 /*
- * Preload B core in response to
- * A Overflow.
- */
-#define S626_LOADSRC_NONE 3 /* Never preload core. */
-
-/* IntSrc values: */
-#define S626_INTSRC_NONE 0 /* Interrupts disabled. */
-#define S626_INTSRC_OVER 1 /* Interrupt on Overflow. */
-#define S626_INTSRC_INDX 2 /* Interrupt on Index. */
-#define S626_INTSRC_BOTH 3 /* Interrupt on Index or Overflow. */
-
-/* LatchSrc values: */
-#define S626_LATCHSRC_AB_READ 0 /* Latch on read. */
-#define S626_LATCHSRC_A_INDXA 1 /* Latch A on A Index. */
-#define S626_LATCHSRC_B_INDXB 2 /* Latch B on B Index. */
-#define S626_LATCHSRC_B_OVERA 3 /* Latch B on A Overflow. */
-
-/* IndxSrc values: */
-#define S626_INDXSRC_ENCODER 0 /* Encoder. */
-#define S626_INDXSRC_DIGIN 1 /* Digital inputs. */
-#define S626_INDXSRC_SOFT 2 /* S/w controlled by IndxPol bit. */
-#define S626_INDXSRC_DISABLED 3 /* Index disabled. */
-
-/* IndxPol values: */
-#define S626_INDXPOL_POS 0 /* Index input is active high. */
-#define S626_INDXPOL_NEG 1 /* Index input is active low. */
-
-/* Logical encoder mode values: */
-#define S626_ENCMODE_COUNTER 0 /* Counter mode. */
-#define S626_ENCMODE_TIMER 2 /* Timer mode. */
-#define S626_ENCMODE_EXTENDER 3 /* Extender mode. */
-
-/* Physical CntSrc values (for Counter A source and Counter B source): */
-#define S626_CNTSRC_ENCODER 0 /* Encoder */
-#define S626_CNTSRC_DIGIN 1 /* Digital inputs */
-#define S626_CNTSRC_SYSCLK 2 /* System clock up */
-#define S626_CNTSRC_SYSCLK_DOWN 3 /* System clock down */
-
-/* ClkPol values: */
-#define S626_CLKPOL_POS 0 /*
- * Counter/Extender clock is
- * active high.
- */
-#define S626_CLKPOL_NEG 1 /*
- * Counter/Extender clock is
- * active low.
- */
-#define S626_CNTDIR_UP 0 /* Timer counts up. */
-#define S626_CNTDIR_DOWN 1 /* Timer counts down. */
-
-/* ClkEnab values: */
-#define S626_CLKENAB_ALWAYS 0 /* Clock always enabled. */
-#define S626_CLKENAB_INDEX 1 /* Clock is enabled by index. */
-
-/* ClkMult values: */
-#define S626_CLKMULT_4X 0 /* 4x clock multiplier. */
-#define S626_CLKMULT_2X 1 /* 2x clock multiplier. */
-#define S626_CLKMULT_1X 2 /* 1x clock multiplier. */
-#define S626_CLKMULT_SPECIAL 3 /* Special clock multiplier value. */
-
-/* Sanity-check limits for parameters. */
-
-#define S626_NUM_COUNTERS 6 /*
- * Maximum valid counter
- * logical channel number.
- */
-#define S626_NUM_INTSOURCES 4
-#define S626_NUM_LATCHSOURCES 4
-#define S626_NUM_CLKMULTS 4
-#define S626_NUM_CLKSOURCES 4
-#define S626_NUM_CLKPOLS 2
-#define S626_NUM_INDEXPOLS 2
-#define S626_NUM_INDEXSOURCES 2
-#define S626_NUM_LOADTRIGS 4
-
-/* General macros for manipulating bitfields: */
-#define S626_MAKE(x, w, p) (((x) & ((1 << (w)) - 1)) << (p))
-#define S626_UNMAKE(v, w, p) (((v) >> (p)) & ((1 << (w)) - 1))
-
-/* Bit field positions in CRA: */
-#define S626_CRABIT_INDXSRC_B 14 /* B index source. */
-#define S626_CRABIT_CNTSRC_B 12 /* B counter source. */
-#define S626_CRABIT_INDXPOL_A 11 /* A index polarity. */
-#define S626_CRABIT_LOADSRC_A 9 /* A preload trigger. */
-#define S626_CRABIT_CLKMULT_A 7 /* A clock multiplier. */
-#define S626_CRABIT_INTSRC_A 5 /* A interrupt source. */
-#define S626_CRABIT_CLKPOL_A 4 /* A clock polarity. */
-#define S626_CRABIT_INDXSRC_A 2 /* A index source. */
-#define S626_CRABIT_CNTSRC_A 0 /* A counter source. */
-
-/* Bit field widths in CRA: */
-#define S626_CRAWID_INDXSRC_B 2
-#define S626_CRAWID_CNTSRC_B 2
-#define S626_CRAWID_INDXPOL_A 1
-#define S626_CRAWID_LOADSRC_A 2
-#define S626_CRAWID_CLKMULT_A 2
-#define S626_CRAWID_INTSRC_A 2
-#define S626_CRAWID_CLKPOL_A 1
-#define S626_CRAWID_INDXSRC_A 2
-#define S626_CRAWID_CNTSRC_A 2
-
-/* Bit field masks for CRA: */
-#define S626_CRAMSK_INDXSRC_B S626_SET_CRA_INDXSRC_B(~0)
-#define S626_CRAMSK_CNTSRC_B S626_SET_CRA_CNTSRC_B(~0)
-#define S626_CRAMSK_INDXPOL_A S626_SET_CRA_INDXPOL_A(~0)
-#define S626_CRAMSK_LOADSRC_A S626_SET_CRA_LOADSRC_A(~0)
-#define S626_CRAMSK_CLKMULT_A S626_SET_CRA_CLKMULT_A(~0)
-#define S626_CRAMSK_INTSRC_A S626_SET_CRA_INTSRC_A(~0)
-#define S626_CRAMSK_CLKPOL_A S626_SET_CRA_CLKPOL_A(~0)
-#define S626_CRAMSK_INDXSRC_A S626_SET_CRA_INDXSRC_A(~0)
-#define S626_CRAMSK_CNTSRC_A S626_SET_CRA_CNTSRC_A(~0)
-
-/* Construct parts of the CRA value: */
-#define S626_SET_CRA_INDXSRC_B(x) \
- S626_MAKE((x), S626_CRAWID_INDXSRC_B, S626_CRABIT_INDXSRC_B)
-#define S626_SET_CRA_CNTSRC_B(x) \
- S626_MAKE((x), S626_CRAWID_CNTSRC_B, S626_CRABIT_CNTSRC_B)
-#define S626_SET_CRA_INDXPOL_A(x) \
- S626_MAKE((x), S626_CRAWID_INDXPOL_A, S626_CRABIT_INDXPOL_A)
-#define S626_SET_CRA_LOADSRC_A(x) \
- S626_MAKE((x), S626_CRAWID_LOADSRC_A, S626_CRABIT_LOADSRC_A)
-#define S626_SET_CRA_CLKMULT_A(x) \
- S626_MAKE((x), S626_CRAWID_CLKMULT_A, S626_CRABIT_CLKMULT_A)
-#define S626_SET_CRA_INTSRC_A(x) \
- S626_MAKE((x), S626_CRAWID_INTSRC_A, S626_CRABIT_INTSRC_A)
-#define S626_SET_CRA_CLKPOL_A(x) \
- S626_MAKE((x), S626_CRAWID_CLKPOL_A, S626_CRABIT_CLKPOL_A)
-#define S626_SET_CRA_INDXSRC_A(x) \
- S626_MAKE((x), S626_CRAWID_INDXSRC_A, S626_CRABIT_INDXSRC_A)
-#define S626_SET_CRA_CNTSRC_A(x) \
- S626_MAKE((x), S626_CRAWID_CNTSRC_A, S626_CRABIT_CNTSRC_A)
-
-/* Extract parts of the CRA value: */
-#define S626_GET_CRA_INDXSRC_B(v) \
- S626_UNMAKE((v), S626_CRAWID_INDXSRC_B, S626_CRABIT_INDXSRC_B)
-#define S626_GET_CRA_CNTSRC_B(v) \
- S626_UNMAKE((v), S626_CRAWID_CNTSRC_B, S626_CRABIT_CNTSRC_B)
-#define S626_GET_CRA_INDXPOL_A(v) \
- S626_UNMAKE((v), S626_CRAWID_INDXPOL_A, S626_CRABIT_INDXPOL_A)
-#define S626_GET_CRA_LOADSRC_A(v) \
- S626_UNMAKE((v), S626_CRAWID_LOADSRC_A, S626_CRABIT_LOADSRC_A)
-#define S626_GET_CRA_CLKMULT_A(v) \
- S626_UNMAKE((v), S626_CRAWID_CLKMULT_A, S626_CRABIT_CLKMULT_A)
-#define S626_GET_CRA_INTSRC_A(v) \
- S626_UNMAKE((v), S626_CRAWID_INTSRC_A, S626_CRABIT_INTSRC_A)
-#define S626_GET_CRA_CLKPOL_A(v) \
- S626_UNMAKE((v), S626_CRAWID_CLKPOL_A, S626_CRABIT_CLKPOL_A)
-#define S626_GET_CRA_INDXSRC_A(v) \
- S626_UNMAKE((v), S626_CRAWID_INDXSRC_A, S626_CRABIT_INDXSRC_A)
-#define S626_GET_CRA_CNTSRC_A(v) \
- S626_UNMAKE((v), S626_CRAWID_CNTSRC_A, S626_CRABIT_CNTSRC_A)
-
-/* Bit field positions in CRB: */
-#define S626_CRBBIT_INTRESETCMD 15 /* (w) Interrupt reset command. */
-#define S626_CRBBIT_CNTDIR_B 15 /* (r) B counter direction. */
-#define S626_CRBBIT_INTRESET_B 14 /* (w) B interrupt reset enable. */
-#define S626_CRBBIT_OVERDO_A 14 /* (r) A overflow routed to dig. out. */
-#define S626_CRBBIT_INTRESET_A 13 /* (w) A interrupt reset enable. */
-#define S626_CRBBIT_OVERDO_B 13 /* (r) B overflow routed to dig. out. */
-#define S626_CRBBIT_CLKENAB_A 12 /* A clock enable. */
-#define S626_CRBBIT_INTSRC_B 10 /* B interrupt source. */
-#define S626_CRBBIT_LATCHSRC 8 /* A/B latch source. */
-#define S626_CRBBIT_LOADSRC_B 6 /* B preload trigger. */
-#define S626_CRBBIT_CLEAR_B 7 /* B cleared when A overflows. */
-#define S626_CRBBIT_CLKMULT_B 3 /* B clock multiplier. */
-#define S626_CRBBIT_CLKENAB_B 2 /* B clock enable. */
-#define S626_CRBBIT_INDXPOL_B 1 /* B index polarity. */
-#define S626_CRBBIT_CLKPOL_B 0 /* B clock polarity. */
-
-/* Bit field widths in CRB: */
-#define S626_CRBWID_INTRESETCMD 1
-#define S626_CRBWID_CNTDIR_B 1
-#define S626_CRBWID_INTRESET_B 1
-#define S626_CRBWID_OVERDO_A 1
-#define S626_CRBWID_INTRESET_A 1
-#define S626_CRBWID_OVERDO_B 1
-#define S626_CRBWID_CLKENAB_A 1
-#define S626_CRBWID_INTSRC_B 2
-#define S626_CRBWID_LATCHSRC 2
-#define S626_CRBWID_LOADSRC_B 2
-#define S626_CRBWID_CLEAR_B 1
-#define S626_CRBWID_CLKMULT_B 2
-#define S626_CRBWID_CLKENAB_B 1
-#define S626_CRBWID_INDXPOL_B 1
-#define S626_CRBWID_CLKPOL_B 1
-
-/* Bit field masks for CRB: */
-#define S626_CRBMSK_INTRESETCMD S626_SET_CRB_INTRESETCMD(~0) /* (w) */
-#define S626_CRBMSK_CNTDIR_B S626_CRBMSK_INTRESETCMD /* (r) */
-#define S626_CRBMSK_INTRESET_B S626_SET_CRB_INTRESET_B(~0) /* (w) */
-#define S626_CRBMSK_OVERDO_A S626_CRBMSK_INTRESET_B /* (r) */
-#define S626_CRBMSK_INTRESET_A S626_SET_CRB_INTRESET_A(~0) /* (w) */
-#define S626_CRBMSK_OVERDO_B S626_CRBMSK_INTRESET_A /* (r) */
-#define S626_CRBMSK_CLKENAB_A S626_SET_CRB_CLKENAB_A(~0)
-#define S626_CRBMSK_INTSRC_B S626_SET_CRB_INTSRC_B(~0)
-#define S626_CRBMSK_LATCHSRC S626_SET_CRB_LATCHSRC(~0)
-#define S626_CRBMSK_LOADSRC_B S626_SET_CRB_LOADSRC_B(~0)
-#define S626_CRBMSK_CLEAR_B S626_SET_CRB_CLEAR_B(~0)
-#define S626_CRBMSK_CLKMULT_B S626_SET_CRB_CLKMULT_B(~0)
-#define S626_CRBMSK_CLKENAB_B S626_SET_CRB_CLKENAB_B(~0)
-#define S626_CRBMSK_INDXPOL_B S626_SET_CRB_INDXPOL_B(~0)
-#define S626_CRBMSK_CLKPOL_B S626_SET_CRB_CLKPOL_B(~0)
-
-/* Interrupt reset control bits. */
-#define S626_CRBMSK_INTCTRL (S626_CRBMSK_INTRESETCMD | \
- S626_CRBMSK_INTRESET_A | \
- S626_CRBMSK_INTRESET_B)
-
-/* Construct parts of the CRB value: */
-#define S626_SET_CRB_INTRESETCMD(x) \
- S626_MAKE((x), S626_CRBWID_INTRESETCMD, S626_CRBBIT_INTRESETCMD)
-#define S626_SET_CRB_INTRESET_B(x) \
- S626_MAKE((x), S626_CRBWID_INTRESET_B, S626_CRBBIT_INTRESET_B)
-#define S626_SET_CRB_INTRESET_A(x) \
- S626_MAKE((x), S626_CRBWID_INTRESET_A, S626_CRBBIT_INTRESET_A)
-#define S626_SET_CRB_CLKENAB_A(x) \
- S626_MAKE((x), S626_CRBWID_CLKENAB_A, S626_CRBBIT_CLKENAB_A)
-#define S626_SET_CRB_INTSRC_B(x) \
- S626_MAKE((x), S626_CRBWID_INTSRC_B, S626_CRBBIT_INTSRC_B)
-#define S626_SET_CRB_LATCHSRC(x) \
- S626_MAKE((x), S626_CRBWID_LATCHSRC, S626_CRBBIT_LATCHSRC)
-#define S626_SET_CRB_LOADSRC_B(x) \
- S626_MAKE((x), S626_CRBWID_LOADSRC_B, S626_CRBBIT_LOADSRC_B)
-#define S626_SET_CRB_CLEAR_B(x) \
- S626_MAKE((x), S626_CRBWID_CLEAR_B, S626_CRBBIT_CLEAR_B)
-#define S626_SET_CRB_CLKMULT_B(x) \
- S626_MAKE((x), S626_CRBWID_CLKMULT_B, S626_CRBBIT_CLKMULT_B)
-#define S626_SET_CRB_CLKENAB_B(x) \
- S626_MAKE((x), S626_CRBWID_CLKENAB_B, S626_CRBBIT_CLKENAB_B)
-#define S626_SET_CRB_INDXPOL_B(x) \
- S626_MAKE((x), S626_CRBWID_INDXPOL_B, S626_CRBBIT_INDXPOL_B)
-#define S626_SET_CRB_CLKPOL_B(x) \
- S626_MAKE((x), S626_CRBWID_CLKPOL_B, S626_CRBBIT_CLKPOL_B)
-
-/* Extract parts of the CRB value: */
-#define S626_GET_CRB_CNTDIR_B(v) \
- S626_UNMAKE((v), S626_CRBWID_CNTDIR_B, S626_CRBBIT_CNTDIR_B)
-#define S626_GET_CRB_OVERDO_A(v) \
- S626_UNMAKE((v), S626_CRBWID_OVERDO_A, S626_CRBBIT_OVERDO_A)
-#define S626_GET_CRB_OVERDO_B(v) \
- S626_UNMAKE((v), S626_CRBWID_OVERDO_B, S626_CRBBIT_OVERDO_B)
-#define S626_GET_CRB_CLKENAB_A(v) \
- S626_UNMAKE((v), S626_CRBWID_CLKENAB_A, S626_CRBBIT_CLKENAB_A)
-#define S626_GET_CRB_INTSRC_B(v) \
- S626_UNMAKE((v), S626_CRBWID_INTSRC_B, S626_CRBBIT_INTSRC_B)
-#define S626_GET_CRB_LATCHSRC(v) \
- S626_UNMAKE((v), S626_CRBWID_LATCHSRC, S626_CRBBIT_LATCHSRC)
-#define S626_GET_CRB_LOADSRC_B(v) \
- S626_UNMAKE((v), S626_CRBWID_LOADSRC_B, S626_CRBBIT_LOADSRC_B)
-#define S626_GET_CRB_CLEAR_B(v) \
- S626_UNMAKE((v), S626_CRBWID_CLEAR_B, S626_CRBBIT_CLEAR_B)
-#define S626_GET_CRB_CLKMULT_B(v) \
- S626_UNMAKE((v), S626_CRBWID_CLKMULT_B, S626_CRBBIT_CLKMULT_B)
-#define S626_GET_CRB_CLKENAB_B(v) \
- S626_UNMAKE((v), S626_CRBWID_CLKENAB_B, S626_CRBBIT_CLKENAB_B)
-#define S626_GET_CRB_INDXPOL_B(v) \
- S626_UNMAKE((v), S626_CRBWID_INDXPOL_B, S626_CRBBIT_INDXPOL_B)
-#define S626_GET_CRB_CLKPOL_B(v) \
- S626_UNMAKE((v), S626_CRBWID_CLKPOL_B, S626_CRBBIT_CLKPOL_B)
-
-/* Bit field positions for standardized SETUP structure: */
-#define S626_STDBIT_INTSRC 13
-#define S626_STDBIT_LATCHSRC 11
-#define S626_STDBIT_LOADSRC 9
-#define S626_STDBIT_INDXSRC 7
-#define S626_STDBIT_INDXPOL 6
-#define S626_STDBIT_ENCMODE 4
-#define S626_STDBIT_CLKPOL 3
-#define S626_STDBIT_CLKMULT 1
-#define S626_STDBIT_CLKENAB 0
-
-/* Bit field widths for standardized SETUP structure: */
-#define S626_STDWID_INTSRC 2
-#define S626_STDWID_LATCHSRC 2
-#define S626_STDWID_LOADSRC 2
-#define S626_STDWID_INDXSRC 2
-#define S626_STDWID_INDXPOL 1
-#define S626_STDWID_ENCMODE 2
-#define S626_STDWID_CLKPOL 1
-#define S626_STDWID_CLKMULT 2
-#define S626_STDWID_CLKENAB 1
-
-/* Bit field masks for standardized SETUP structure: */
-#define S626_STDMSK_INTSRC S626_SET_STD_INTSRC(~0)
-#define S626_STDMSK_LATCHSRC S626_SET_STD_LATCHSRC(~0)
-#define S626_STDMSK_LOADSRC S626_SET_STD_LOADSRC(~0)
-#define S626_STDMSK_INDXSRC S626_SET_STD_INDXSRC(~0)
-#define S626_STDMSK_INDXPOL S626_SET_STD_INDXPOL(~0)
-#define S626_STDMSK_ENCMODE S626_SET_STD_ENCMODE(~0)
-#define S626_STDMSK_CLKPOL S626_SET_STD_CLKPOL(~0)
-#define S626_STDMSK_CLKMULT S626_SET_STD_CLKMULT(~0)
-#define S626_STDMSK_CLKENAB S626_SET_STD_CLKENAB(~0)
-
-/* Construct parts of standardized SETUP structure: */
-#define S626_SET_STD_INTSRC(x) \
- S626_MAKE((x), S626_STDWID_INTSRC, S626_STDBIT_INTSRC)
-#define S626_SET_STD_LATCHSRC(x) \
- S626_MAKE((x), S626_STDWID_LATCHSRC, S626_STDBIT_LATCHSRC)
-#define S626_SET_STD_LOADSRC(x) \
- S626_MAKE((x), S626_STDWID_LOADSRC, S626_STDBIT_LOADSRC)
-#define S626_SET_STD_INDXSRC(x) \
- S626_MAKE((x), S626_STDWID_INDXSRC, S626_STDBIT_INDXSRC)
-#define S626_SET_STD_INDXPOL(x) \
- S626_MAKE((x), S626_STDWID_INDXPOL, S626_STDBIT_INDXPOL)
-#define S626_SET_STD_ENCMODE(x) \
- S626_MAKE((x), S626_STDWID_ENCMODE, S626_STDBIT_ENCMODE)
-#define S626_SET_STD_CLKPOL(x) \
- S626_MAKE((x), S626_STDWID_CLKPOL, S626_STDBIT_CLKPOL)
-#define S626_SET_STD_CLKMULT(x) \
- S626_MAKE((x), S626_STDWID_CLKMULT, S626_STDBIT_CLKMULT)
-#define S626_SET_STD_CLKENAB(x) \
- S626_MAKE((x), S626_STDWID_CLKENAB, S626_STDBIT_CLKENAB)
-
-/* Extract parts of standardized SETUP structure: */
-#define S626_GET_STD_INTSRC(v) \
- S626_UNMAKE((v), S626_STDWID_INTSRC, S626_STDBIT_INTSRC)
-#define S626_GET_STD_LATCHSRC(v) \
- S626_UNMAKE((v), S626_STDWID_LATCHSRC, S626_STDBIT_LATCHSRC)
-#define S626_GET_STD_LOADSRC(v) \
- S626_UNMAKE((v), S626_STDWID_LOADSRC, S626_STDBIT_LOADSRC)
-#define S626_GET_STD_INDXSRC(v) \
- S626_UNMAKE((v), S626_STDWID_INDXSRC, S626_STDBIT_INDXSRC)
-#define S626_GET_STD_INDXPOL(v) \
- S626_UNMAKE((v), S626_STDWID_INDXPOL, S626_STDBIT_INDXPOL)
-#define S626_GET_STD_ENCMODE(v) \
- S626_UNMAKE((v), S626_STDWID_ENCMODE, S626_STDBIT_ENCMODE)
-#define S626_GET_STD_CLKPOL(v) \
- S626_UNMAKE((v), S626_STDWID_CLKPOL, S626_STDBIT_CLKPOL)
-#define S626_GET_STD_CLKMULT(v) \
- S626_UNMAKE((v), S626_STDWID_CLKMULT, S626_STDBIT_CLKMULT)
-#define S626_GET_STD_CLKENAB(v) \
- S626_UNMAKE((v), S626_STDWID_CLKENAB, S626_STDBIT_CLKENAB)
-
-#endif
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
deleted file mode 100644
index 016d315aa584..000000000000
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ /dev/null
@@ -1,180 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * ssv_dnp.c
- * generic comedi driver for SSV Embedded Systems' DIL/Net-PCs
- * Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: ssv_dnp
- * Description: SSV Embedded Systems DIL/Net-PC
- * Author: Robert Schwebel <robert@schwebel.de>
- * Devices: [SSV Embedded Systems] DIL/Net-PC 1486 (dnp-1486)
- * Status: unknown
- */
-
-/* include files ----------------------------------------------------------- */
-
-#include <linux/module.h>
-#include "../comedidev.h"
-
-/* Some global definitions: the registers of the DNP ----------------------- */
-/* */
-/* For port A and B the mode register has bits corresponding to the output */
-/* pins, where Bit-N = 0 -> input, Bit-N = 1 -> output. Note that bits */
-/* 4 to 7 correspond to pin 0..3 for port C data register. Ensure that bits */
-/* 0..3 remain unchanged! For details about Port C Mode Register see */
-/* the remarks in dnp_insn_config() below. */
-
-#define CSCIR 0x22 /* Chip Setup and Control Index Register */
-#define CSCDR 0x23 /* Chip Setup and Control Data Register */
-#define PAMR 0xa5 /* Port A Mode Register */
-#define PADR 0xa9 /* Port A Data Register */
-#define PBMR 0xa4 /* Port B Mode Register */
-#define PBDR 0xa8 /* Port B Data Register */
-#define PCMR 0xa3 /* Port C Mode Register */
-#define PCDR 0xa7 /* Port C Data Register */
-
-static int dnp_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
- unsigned int val;
-
- /*
- * Ports A and B are straight forward: each bit corresponds to an
- * output pin with the same order. Port C is different: bits 0...3
- * correspond to bits 4...7 of the output register (PCDR).
- */
-
- mask = comedi_dio_update_state(s, data);
- if (mask) {
- outb(PADR, CSCIR);
- outb(s->state & 0xff, CSCDR);
-
- outb(PBDR, CSCIR);
- outb((s->state >> 8) & 0xff, CSCDR);
-
- outb(PCDR, CSCIR);
- val = inb(CSCDR) & 0x0f;
- outb(((s->state >> 12) & 0xf0) | val, CSCDR);
- }
-
- outb(PADR, CSCIR);
- val = inb(CSCDR);
- outb(PBDR, CSCIR);
- val |= (inb(CSCDR) << 8);
- outb(PCDR, CSCIR);
- val |= ((inb(CSCDR) & 0xf0) << 12);
-
- data[1] = val;
-
- return insn->n;
-}
-
-static int dnp_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int mask;
- unsigned int val;
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- if (chan < 8) { /* Port A */
- mask = 1 << chan;
- outb(PAMR, CSCIR);
- } else if (chan < 16) { /* Port B */
- mask = 1 << (chan - 8);
- outb(PBMR, CSCIR);
- } else { /* Port C */
- /*
- * We have to pay attention with port C.
- * This is the meaning of PCMR:
- * Bit in PCMR: 7 6 5 4 3 2 1 0
- * Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch
- *
- * Multiplication by 2 brings bits into correct position
- * for PCMR!
- */
- mask = 1 << ((chan - 16) * 2);
- outb(PCMR, CSCIR);
- }
-
- val = inb(CSCDR);
- if (data[0] == COMEDI_OUTPUT)
- val |= mask;
- else
- val &= ~mask;
- outb(val, CSCDR);
-
- return insn->n;
-}
-
-static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- struct comedi_subdevice *s;
- int ret;
-
- /*
- * We use I/O ports 0x22, 0x23 and 0xa3-0xa9, which are always
- * allocated for the primary 8259, so we don't need to allocate
- * them ourselves.
- */
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* digital i/o subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 20;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = dnp_dio_insn_bits;
- s->insn_config = dnp_dio_insn_config;
-
- /* configure all ports as input (default) */
- outb(PAMR, CSCIR);
- outb(0x00, CSCDR);
- outb(PBMR, CSCIR);
- outb(0x00, CSCDR);
- outb(PCMR, CSCIR);
- outb((inb(CSCDR) & 0xAA), CSCDR);
-
- return 0;
-}
-
-static void dnp_detach(struct comedi_device *dev)
-{
- outb(PAMR, CSCIR);
- outb(0x00, CSCDR);
- outb(PBMR, CSCIR);
- outb(0x00, CSCDR);
- outb(PCMR, CSCIR);
- outb((inb(CSCDR) & 0xAA), CSCDR);
-}
-
-static struct comedi_driver dnp_driver = {
- .driver_name = "dnp-1486",
- .module = THIS_MODULE,
- .attach = dnp_attach,
- .detach = dnp_detach,
-};
-module_comedi_driver(dnp_driver);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/tests/Makefile b/drivers/staging/comedi/drivers/tests/Makefile
deleted file mode 100644
index 5ff7cdc32a32..000000000000
--- a/drivers/staging/comedi/drivers/tests/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Makefile for comedi drivers unit tests
-#
-ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG
-
-obj-$(CONFIG_COMEDI_TESTS_EXAMPLE) += comedi_example_test.o
-obj-$(CONFIG_COMEDI_TESTS_NI_ROUTES) += ni_routes_test.o
-CFLAGS_ni_routes_test.o := -DDEBUG
diff --git a/drivers/staging/comedi/drivers/tests/comedi_example_test.c b/drivers/staging/comedi/drivers/tests/comedi_example_test.c
deleted file mode 100644
index e5aaaeab7bdd..000000000000
--- a/drivers/staging/comedi/drivers/tests/comedi_example_test.c
+++ /dev/null
@@ -1,72 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/tests/comedi_example_test.c
- * Example set of unit tests.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-#include <linux/module.h>
-
-#include "unittest.h"
-
-/* *** BEGIN fake board data *** */
-struct comedi_device {
- const char *board_name;
- int item;
-};
-
-static struct comedi_device dev = {
- .board_name = "fake_device",
-};
-
-/* *** END fake board data *** */
-
-/* *** BEGIN fake data init *** */
-static void init_fake(void)
-{
- dev.item = 10;
-}
-
-/* *** END fake data init *** */
-
-static void test0(void)
-{
- init_fake();
- unittest(dev.item != 11, "negative result\n");
- unittest(dev.item == 10, "positive result\n");
-}
-
-/* **** BEGIN simple module entry/exit functions **** */
-static int __init unittest_enter(void)
-{
- static const unittest_fptr unit_tests[] = {
- test0,
- NULL,
- };
-
- exec_unittests("example", unit_tests);
- return 0;
-}
-
-static void __exit unittest_exit(void) { }
-
-module_init(unittest_enter);
-module_exit(unittest_exit);
-
-MODULE_AUTHOR("Spencer Olson <olsonse@umich.edu>");
-MODULE_DESCRIPTION("Comedi unit-tests example");
-MODULE_LICENSE("GPL");
-/* **** END simple module entry/exit functions **** */
diff --git a/drivers/staging/comedi/drivers/tests/ni_routes_test.c b/drivers/staging/comedi/drivers/tests/ni_routes_test.c
deleted file mode 100644
index 32073850d545..000000000000
--- a/drivers/staging/comedi/drivers/tests/ni_routes_test.c
+++ /dev/null
@@ -1,611 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/tests/ni_routes_test.c
- * Unit tests for NI routes (ni_routes.c module).
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- *
- * This program 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.
- */
-
-#include <linux/module.h>
-
-#include "../ni_stc.h"
-#include "../ni_routes.h"
-#include "unittest.h"
-
-#define RVI(table, src, dest) ((table)[(dest) * NI_NUM_NAMES + (src)])
-#define O(x) ((x) + NI_NAMES_BASE)
-#define B(x) ((x) - NI_NAMES_BASE)
-#define V(x) ((x) | 0x80)
-
-/* *** BEGIN fake board data *** */
-static const char *pci_6070e = "pci-6070e";
-static const char *pci_6220 = "pci-6220";
-static const char *pci_fake = "pci-fake";
-
-static const char *ni_eseries = "ni_eseries";
-static const char *ni_mseries = "ni_mseries";
-
-static struct ni_board_struct board = {
- .name = NULL,
-};
-
-static struct ni_private private = {
- .is_m_series = 0,
-};
-
-static const int bad_dest = O(8), dest0 = O(0), desti = O(5);
-static const int ith_dest_index = 2;
-static const int no_val_dest = O(7), no_val_index = 4;
-
-/* These have to be defs to be used in init code below */
-#define rgout0_src0 (O(100))
-#define rgout0_src1 (O(101))
-#define brd0_src0 (O(110))
-#define brd0_src1 (O(111))
-#define brd1_src0 (O(120))
-#define brd1_src1 (O(121))
-#define brd2_src0 (O(130))
-#define brd2_src1 (O(131))
-#define brd3_src0 (O(140))
-#define brd3_src1 (O(141))
-
-/* I1 and I2 should not call O(...). Mostly here to shut checkpatch.pl up */
-#define I1(x1) \
- ((int[]){ \
- (x1), 0 \
- })
-#define I2(x1, x2) \
- ((int[]){ \
- (x1), (x2), 0 \
- })
-#define I3(x1, x2, x3) \
- ((int[]){ \
- (x1), (x2), (x3), 0 \
- })
-
-/* O9 is build to call O(...) for each arg */
-#define O9(x1, x2, x3, x4, x5, x6, x7, x8, x9) \
- ((int[]){ \
- O(x1), O(x2), O(x3), O(x4), O(x5), O(x6), O(x7), O(x8), O(x9), \
- 0 \
- })
-
-static struct ni_device_routes DR = {
- .device = "testdev",
- .routes = (struct ni_route_set[]){
- {.dest = O(0), .src = O9(/**/1, 2, 3, 4, 5, 6, 7, 8, 9)},
- {.dest = O(1), .src = O9(0, /**/2, 3, 4, 5, 6, 7, 8, 9)},
- /* ith route_set */
- {.dest = O(5), .src = O9(0, 1, 2, 3, 4,/**/ 6, 7, 8, 9)},
- {.dest = O(6), .src = O9(0, 1, 2, 3, 4, 5,/**/ 7, 8, 9)},
- /* next one will not have valid reg values */
- {.dest = O(7), .src = O9(0, 1, 2, 3, 4, 5, 6,/**/ 8, 9)},
- {.dest = O(9), .src = O9(0, 1, 2, 3, 4, 5, 6, 7, 8/**/)},
-
- /* indirect routes done through muxes */
- {.dest = TRIGGER_LINE(0), .src = I1(rgout0_src0)},
- {.dest = TRIGGER_LINE(1), .src = I3(rgout0_src0,
- brd3_src0,
- brd3_src1)},
- {.dest = TRIGGER_LINE(2), .src = I3(rgout0_src1,
- brd2_src0,
- brd2_src1)},
- {.dest = TRIGGER_LINE(3), .src = I3(rgout0_src1,
- brd1_src0,
- brd1_src1)},
- {.dest = TRIGGER_LINE(4), .src = I2(brd0_src0,
- brd0_src1)},
- {.dest = 0},
- },
-};
-
-#undef I1
-#undef I2
-#undef O9
-
-#define RV9(x1, x2, x3, x4, x5, x6, x7, x8, x9) \
- [x1] = V(x1), [x2] = V(x2), [x3] = V(x3), [x4] = V(x4), \
- [x5] = V(x5), [x6] = V(x6), [x7] = V(x7), [x8] = V(x8), \
- [x9] = V(x9),
-
-/* This table is indexed as RV[destination][source] */
-static const u8 RV[NI_NUM_NAMES][NI_NUM_NAMES] = {
- [0] = {RV9(/**/1, 2, 3, 4, 5, 6, 7, 8, 9)},
- [1] = {RV9(0,/**/ 2, 3, 4, 5, 6, 7, 8, 9)},
- [2] = {RV9(0, 1,/**/3, 4, 5, 6, 7, 8, 9)},
- [3] = {RV9(0, 1, 2,/**/4, 5, 6, 7, 8, 9)},
- [4] = {RV9(0, 1, 2, 3,/**/5, 6, 7, 8, 9)},
- [5] = {RV9(0, 1, 2, 3, 4,/**/6, 7, 8, 9)},
- [6] = {RV9(0, 1, 2, 3, 4, 5,/**/7, 8, 9)},
- /* [7] is intentionaly left absent to test invalid routes */
- [8] = {RV9(0, 1, 2, 3, 4, 5, 6, 7,/**/9)},
- [9] = {RV9(0, 1, 2, 3, 4, 5, 6, 7, 8/**/)},
- /* some tests for needing extra muxes */
- [B(NI_RGOUT0)] = {[B(rgout0_src0)] = V(0),
- [B(rgout0_src1)] = V(1)},
- [B(NI_RTSI_BRD(0))] = {[B(brd0_src0)] = V(0),
- [B(brd0_src1)] = V(1)},
- [B(NI_RTSI_BRD(1))] = {[B(brd1_src0)] = V(0),
- [B(brd1_src1)] = V(1)},
- [B(NI_RTSI_BRD(2))] = {[B(brd2_src0)] = V(0),
- [B(brd2_src1)] = V(1)},
- [B(NI_RTSI_BRD(3))] = {[B(brd3_src0)] = V(0),
- [B(brd3_src1)] = V(1)},
-};
-
-#undef RV9
-
-/* *** END fake board data *** */
-
-/* *** BEGIN board data initializers *** */
-static void init_private(void)
-{
- memset(&private, 0, sizeof(struct ni_private));
-}
-
-static void init_pci_6070e(void)
-{
- board.name = pci_6070e;
- init_private();
- private.is_m_series = 0;
-}
-
-static void init_pci_6220(void)
-{
- board.name = pci_6220;
- init_private();
- private.is_m_series = 1;
-}
-
-static void init_pci_fake(void)
-{
- board.name = pci_fake;
- init_private();
- private.routing_tables.route_values = &RV[0][0];
- private.routing_tables.valid_routes = &DR;
-}
-
-/* *** END board data initializers *** */
-
-/* Tests that route_sets are in order of the signal destination. */
-static bool route_set_dests_in_order(const struct ni_device_routes *devroutes)
-{
- int i;
- int last = NI_NAMES_BASE - 1;
-
- for (i = 0; i < devroutes->n_route_sets; ++i) {
- if (last >= devroutes->routes[i].dest)
- return false;
- last = devroutes->routes[i].dest;
- }
- return true;
-}
-
-/* Tests that all route_set->src are in order of the signal source. */
-static bool route_set_sources_in_order(const struct ni_device_routes *devroutes)
-{
- int i;
-
- for (i = 0; i < devroutes->n_route_sets; ++i) {
- int j;
- int last = NI_NAMES_BASE - 1;
-
- for (j = 0; j < devroutes->routes[i].n_src; ++j) {
- if (last >= devroutes->routes[i].src[j])
- return false;
- last = devroutes->routes[i].src[j];
- }
- }
- return true;
-}
-
-static void test_ni_assign_device_routes(void)
-{
- const struct ni_device_routes *devroutes;
- const u8 *table, *oldtable;
-
- init_pci_6070e();
- ni_assign_device_routes(ni_eseries, pci_6070e, NULL,
- &private.routing_tables);
- devroutes = private.routing_tables.valid_routes;
- table = private.routing_tables.route_values;
-
- unittest(strncmp(devroutes->device, pci_6070e, 10) == 0,
- "find device pci-6070e\n");
- unittest(devroutes->n_route_sets == 37,
- "number of pci-6070e route_sets == 37\n");
- unittest(devroutes->routes->dest == NI_PFI(0),
- "first pci-6070e route_set is for NI_PFI(0)\n");
- unittest(devroutes->routes->n_src == 1,
- "first pci-6070e route_set length == 1\n");
- unittest(devroutes->routes->src[0] == NI_AI_StartTrigger,
- "first pci-6070e route_set src. == NI_AI_StartTrigger\n");
- unittest(devroutes->routes[10].dest == TRIGGER_LINE(0),
- "10th pci-6070e route_set is for TRIGGER_LINE(0)\n");
- unittest(devroutes->routes[10].n_src == 10,
- "10th pci-6070e route_set length == 10\n");
- unittest(devroutes->routes[10].src[0] == NI_CtrSource(0),
- "10th pci-6070e route_set src. == NI_CtrSource(0)\n");
- unittest(route_set_dests_in_order(devroutes),
- "all pci-6070e route_sets in order of signal destination\n");
- unittest(route_set_sources_in_order(devroutes),
- "all pci-6070e route_set->src's in order of signal source\n");
-
- unittest(RVI(table, B(PXI_Star), B(NI_AI_SampleClock)) == V(17) &&
- RVI(table, B(NI_10MHzRefClock), B(TRIGGER_LINE(0))) == 0 &&
- RVI(table, B(NI_AI_ConvertClock), B(NI_PFI(0))) == 0 &&
- RVI(table, B(NI_AI_ConvertClock), B(NI_PFI(2))) == V(NI_PFI_OUTPUT_AI_CONVERT),
- "pci-6070e finds e-series route_values table\n");
-
- oldtable = table;
- init_pci_6220();
- ni_assign_device_routes(ni_mseries, pci_6220, NULL,
- &private.routing_tables);
- devroutes = private.routing_tables.valid_routes;
- table = private.routing_tables.route_values;
-
- unittest(strncmp(devroutes->device, pci_6220, 10) == 0,
- "find device pci-6220\n");
- unittest(oldtable != table, "pci-6220 find other route_values table\n");
-
- unittest(RVI(table, B(PXI_Star), B(NI_AI_SampleClock)) == V(20) &&
- RVI(table, B(NI_10MHzRefClock), B(TRIGGER_LINE(0))) == V(12) &&
- RVI(table, B(NI_AI_ConvertClock), B(NI_PFI(0))) == V(3) &&
- RVI(table, B(NI_AI_ConvertClock), B(NI_PFI(2))) == V(3),
- "pci-6220 finds m-series route_values table\n");
-}
-
-static void test_ni_sort_device_routes(void)
-{
- /* We begin by sorting the device routes for use in later tests */
- ni_sort_device_routes(&DR);
- /* now we test that sorting. */
- unittest(route_set_dests_in_order(&DR),
- "all route_sets of fake data in order of sig. destination\n");
- unittest(route_set_sources_in_order(&DR),
- "all route_set->src's of fake data in order of sig. source\n");
-}
-
-static void test_ni_find_route_set(void)
-{
- unittest(!ni_find_route_set(bad_dest, &DR),
- "check for nonexistent route_set\n");
- unittest(ni_find_route_set(dest0, &DR) == &DR.routes[0],
- "find first route_set\n");
- unittest(ni_find_route_set(desti, &DR) == &DR.routes[ith_dest_index],
- "find ith route_set\n");
- unittest(ni_find_route_set(no_val_dest, &DR) ==
- &DR.routes[no_val_index],
- "find no_val route_set in spite of missing values\n");
- unittest(ni_find_route_set(DR.routes[DR.n_route_sets - 1].dest, &DR) ==
- &DR.routes[DR.n_route_sets - 1],
- "find last route_set\n");
-}
-
-static void test_ni_route_set_has_source(void)
-{
- unittest(!ni_route_set_has_source(&DR.routes[0], O(0)),
- "check for bad source\n");
- unittest(ni_route_set_has_source(&DR.routes[0], O(1)),
- "find first source\n");
- unittest(ni_route_set_has_source(&DR.routes[0], O(5)),
- "find fifth source\n");
- unittest(ni_route_set_has_source(&DR.routes[0], O(9)),
- "find last source\n");
-}
-
-static void test_ni_route_to_register(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(ni_route_to_register(O(0), O(0), T) < 0,
- "check for bad route 0-->0\n");
- unittest(ni_route_to_register(O(1), O(0), T) == 1,
- "validate first destination\n");
- unittest(ni_route_to_register(O(6), O(5), T) == 6,
- "validate middle destination\n");
- unittest(ni_route_to_register(O(8), O(9), T) == 8,
- "validate last destination\n");
-
- /* choice of trigger line in the following is somewhat random */
- unittest(ni_route_to_register(rgout0_src0, TRIGGER_LINE(0), T) == 0,
- "validate indirect route through rgout0 to TRIGGER_LINE(0)\n");
- unittest(ni_route_to_register(rgout0_src0, TRIGGER_LINE(1), T) == 0,
- "validate indirect route through rgout0 to TRIGGER_LINE(1)\n");
- unittest(ni_route_to_register(rgout0_src1, TRIGGER_LINE(2), T) == 1,
- "validate indirect route through rgout0 to TRIGGER_LINE(2)\n");
- unittest(ni_route_to_register(rgout0_src1, TRIGGER_LINE(3), T) == 1,
- "validate indirect route through rgout0 to TRIGGER_LINE(3)\n");
-
- unittest(ni_route_to_register(brd0_src0, TRIGGER_LINE(4), T) ==
- BIT(6),
- "validate indirect route through brd0 to TRIGGER_LINE(4)\n");
- unittest(ni_route_to_register(brd0_src1, TRIGGER_LINE(4), T) ==
- BIT(6),
- "validate indirect route through brd0 to TRIGGER_LINE(4)\n");
- unittest(ni_route_to_register(brd1_src0, TRIGGER_LINE(3), T) ==
- BIT(6),
- "validate indirect route through brd1 to TRIGGER_LINE(3)\n");
- unittest(ni_route_to_register(brd1_src1, TRIGGER_LINE(3), T) ==
- BIT(6),
- "validate indirect route through brd1 to TRIGGER_LINE(3)\n");
- unittest(ni_route_to_register(brd2_src0, TRIGGER_LINE(2), T) ==
- BIT(6),
- "validate indirect route through brd2 to TRIGGER_LINE(2)\n");
- unittest(ni_route_to_register(brd2_src1, TRIGGER_LINE(2), T) ==
- BIT(6),
- "validate indirect route through brd2 to TRIGGER_LINE(2)\n");
- unittest(ni_route_to_register(brd3_src0, TRIGGER_LINE(1), T) ==
- BIT(6),
- "validate indirect route through brd3 to TRIGGER_LINE(1)\n");
- unittest(ni_route_to_register(brd3_src1, TRIGGER_LINE(1), T) ==
- BIT(6),
- "validate indirect route through brd3 to TRIGGER_LINE(1)\n");
-}
-
-static void test_ni_lookup_route_register(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(ni_lookup_route_register(O(0), O(0), T) == -EINVAL,
- "check for bad route 0-->0\n");
- unittest(ni_lookup_route_register(O(1), O(0), T) == 1,
- "validate first destination\n");
- unittest(ni_lookup_route_register(O(6), O(5), T) == 6,
- "validate middle destination\n");
- unittest(ni_lookup_route_register(O(8), O(9), T) == 8,
- "validate last destination\n");
- unittest(ni_lookup_route_register(O(10), O(9), T) == -EINVAL,
- "lookup invalid destination\n");
-
- unittest(ni_lookup_route_register(rgout0_src0, TRIGGER_LINE(0), T) ==
- -EINVAL,
- "rgout0_src0: no direct lookup of indirect route\n");
- unittest(ni_lookup_route_register(rgout0_src0, NI_RGOUT0, T) == 0,
- "rgout0_src0: lookup indirect route register\n");
- unittest(ni_lookup_route_register(rgout0_src1, TRIGGER_LINE(2), T) ==
- -EINVAL,
- "rgout0_src1: no direct lookup of indirect route\n");
- unittest(ni_lookup_route_register(rgout0_src1, NI_RGOUT0, T) == 1,
- "rgout0_src1: lookup indirect route register\n");
-
- unittest(ni_lookup_route_register(brd0_src0, TRIGGER_LINE(4), T) ==
- -EINVAL,
- "brd0_src0: no direct lookup of indirect route\n");
- unittest(ni_lookup_route_register(brd0_src0, NI_RTSI_BRD(0), T) == 0,
- "brd0_src0: lookup indirect route register\n");
- unittest(ni_lookup_route_register(brd0_src1, TRIGGER_LINE(4), T) ==
- -EINVAL,
- "brd0_src1: no direct lookup of indirect route\n");
- unittest(ni_lookup_route_register(brd0_src1, NI_RTSI_BRD(0), T) == 1,
- "brd0_src1: lookup indirect route register\n");
-}
-
-static void test_route_is_valid(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(!route_is_valid(O(0), O(0), T),
- "check for bad route 0-->0\n");
- unittest(route_is_valid(O(0), O(1), T),
- "validate first destination\n");
- unittest(route_is_valid(O(5), O(6), T),
- "validate middle destination\n");
- unittest(route_is_valid(O(8), O(9), T),
- "validate last destination\n");
-}
-
-static void test_ni_is_cmd_dest(void)
-{
- init_pci_fake();
- unittest(ni_is_cmd_dest(NI_AI_SampleClock),
- "check that AI/SampleClock is cmd destination\n");
- unittest(ni_is_cmd_dest(NI_AI_StartTrigger),
- "check that AI/StartTrigger is cmd destination\n");
- unittest(ni_is_cmd_dest(NI_AI_ConvertClock),
- "check that AI/ConvertClock is cmd destination\n");
- unittest(ni_is_cmd_dest(NI_AO_SampleClock),
- "check that AO/SampleClock is cmd destination\n");
- unittest(ni_is_cmd_dest(NI_DO_SampleClock),
- "check that DO/SampleClock is cmd destination\n");
- unittest(!ni_is_cmd_dest(NI_AO_SampleClockTimebase),
- "check that AO/SampleClockTimebase _not_ cmd destination\n");
-}
-
-static void test_channel_is_pfi(void)
-{
- init_pci_fake();
- unittest(channel_is_pfi(NI_PFI(0)), "check First pfi channel\n");
- unittest(channel_is_pfi(NI_PFI(10)), "check 10th pfi channel\n");
- unittest(channel_is_pfi(NI_PFI(-1)), "check last pfi channel\n");
- unittest(!channel_is_pfi(NI_PFI(-1) + 1),
- "check first non pfi channel\n");
-}
-
-static void test_channel_is_rtsi(void)
-{
- init_pci_fake();
- unittest(channel_is_rtsi(TRIGGER_LINE(0)),
- "check First rtsi channel\n");
- unittest(channel_is_rtsi(TRIGGER_LINE(3)),
- "check 3rd rtsi channel\n");
- unittest(channel_is_rtsi(TRIGGER_LINE(-1)),
- "check last rtsi channel\n");
- unittest(!channel_is_rtsi(TRIGGER_LINE(-1) + 1),
- "check first non rtsi channel\n");
-}
-
-static void test_ni_count_valid_routes(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(ni_count_valid_routes(T) == 57, "count all valid routes\n");
-}
-
-static void test_ni_get_valid_routes(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
- unsigned int pair_data[2];
-
- init_pci_fake();
- unittest(ni_get_valid_routes(T, 0, NULL) == 57,
- "count all valid routes through ni_get_valid_routes\n");
-
- unittest(ni_get_valid_routes(T, 1, pair_data) == 1,
- "copied first valid route from ni_get_valid_routes\n");
- unittest(pair_data[0] == O(1),
- "source of first valid pair from ni_get_valid_routes\n");
- unittest(pair_data[1] == O(0),
- "destination of first valid pair from ni_get_valid_routes\n");
-}
-
-static void test_ni_find_route_source(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(ni_find_route_source(4, O(4), T) == -EINVAL,
- "check for bad source 4-->4\n");
- unittest(ni_find_route_source(0, O(1), T) == O(0),
- "find first source\n");
- unittest(ni_find_route_source(4, O(6), T) == O(4),
- "find middle source\n");
- unittest(ni_find_route_source(9, O(8), T) == O(9),
- "find last source");
- unittest(ni_find_route_source(8, O(9), T) == O(8),
- "find invalid source (without checking device routes)\n");
-}
-
-static void test_route_register_is_valid(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(!route_register_is_valid(4, O(4), T),
- "check for bad source 4-->4\n");
- unittest(route_register_is_valid(0, O(1), T),
- "find first source\n");
- unittest(route_register_is_valid(4, O(6), T),
- "find middle source\n");
- unittest(route_register_is_valid(9, O(8), T),
- "find last source");
-}
-
-static void test_ni_check_trigger_arg(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(ni_check_trigger_arg(0, O(0), T) == -EINVAL,
- "check bad direct trigger arg for first reg->dest\n");
- unittest(ni_check_trigger_arg(0, O(1), T) == 0,
- "check direct trigger arg for first reg->dest\n");
- unittest(ni_check_trigger_arg(4, O(6), T) == 0,
- "check direct trigger arg for middle reg->dest\n");
- unittest(ni_check_trigger_arg(9, O(8), T) == 0,
- "check direct trigger arg for last reg->dest\n");
-
- unittest(ni_check_trigger_arg_roffs(-1, O(0), T, 1) == -EINVAL,
- "check bad direct trigger arg for first reg->dest w/offs\n");
- unittest(ni_check_trigger_arg_roffs(0, O(1), T, 0) == 0,
- "check direct trigger arg for first reg->dest w/offs\n");
- unittest(ni_check_trigger_arg_roffs(3, O(6), T, 1) == 0,
- "check direct trigger arg for middle reg->dest w/offs\n");
- unittest(ni_check_trigger_arg_roffs(7, O(8), T, 2) == 0,
- "check direct trigger arg for last reg->dest w/offs\n");
-
- unittest(ni_check_trigger_arg(O(0), O(0), T) == -EINVAL,
- "check bad trigger arg for first src->dest\n");
- unittest(ni_check_trigger_arg(O(0), O(1), T) == 0,
- "check trigger arg for first src->dest\n");
- unittest(ni_check_trigger_arg(O(5), O(6), T) == 0,
- "check trigger arg for middle src->dest\n");
- unittest(ni_check_trigger_arg(O(8), O(9), T) == 0,
- "check trigger arg for last src->dest\n");
-}
-
-static void test_ni_get_reg_value(void)
-{
- const struct ni_route_tables *T = &private.routing_tables;
-
- init_pci_fake();
- unittest(ni_get_reg_value(0, O(0), T) == -1,
- "check bad direct trigger arg for first reg->dest\n");
- unittest(ni_get_reg_value(0, O(1), T) == 0,
- "check direct trigger arg for first reg->dest\n");
- unittest(ni_get_reg_value(4, O(6), T) == 4,
- "check direct trigger arg for middle reg->dest\n");
- unittest(ni_get_reg_value(9, O(8), T) == 9,
- "check direct trigger arg for last reg->dest\n");
-
- unittest(ni_get_reg_value_roffs(-1, O(0), T, 1) == -1,
- "check bad direct trigger arg for first reg->dest w/offs\n");
- unittest(ni_get_reg_value_roffs(0, O(1), T, 0) == 0,
- "check direct trigger arg for first reg->dest w/offs\n");
- unittest(ni_get_reg_value_roffs(3, O(6), T, 1) == 4,
- "check direct trigger arg for middle reg->dest w/offs\n");
- unittest(ni_get_reg_value_roffs(7, O(8), T, 2) == 9,
- "check direct trigger arg for last reg->dest w/offs\n");
-
- unittest(ni_get_reg_value(O(0), O(0), T) == -1,
- "check bad trigger arg for first src->dest\n");
- unittest(ni_get_reg_value(O(0), O(1), T) == 0,
- "check trigger arg for first src->dest\n");
- unittest(ni_get_reg_value(O(5), O(6), T) == 5,
- "check trigger arg for middle src->dest\n");
- unittest(ni_get_reg_value(O(8), O(9), T) == 8,
- "check trigger arg for last src->dest\n");
-}
-
-/* **** BEGIN simple module entry/exit functions **** */
-static int __init ni_routes_unittest(void)
-{
- static const unittest_fptr unit_tests[] = {
- test_ni_assign_device_routes,
- test_ni_sort_device_routes,
- test_ni_find_route_set,
- test_ni_route_set_has_source,
- test_ni_route_to_register,
- test_ni_lookup_route_register,
- test_route_is_valid,
- test_ni_is_cmd_dest,
- test_channel_is_pfi,
- test_channel_is_rtsi,
- test_ni_count_valid_routes,
- test_ni_get_valid_routes,
- test_ni_find_route_source,
- test_route_register_is_valid,
- test_ni_check_trigger_arg,
- test_ni_get_reg_value,
- NULL,
- };
-
- exec_unittests("ni_routes", unit_tests);
- return 0;
-}
-
-static void __exit ni_routes_unittest_exit(void) { }
-
-module_init(ni_routes_unittest);
-module_exit(ni_routes_unittest_exit);
-
-MODULE_AUTHOR("Comedi https://www.comedi.org");
-MODULE_DESCRIPTION("Comedi unit-tests for ni_routes module");
-MODULE_LICENSE("GPL");
-/* **** END simple module entry/exit functions **** */
diff --git a/drivers/staging/comedi/drivers/tests/unittest.h b/drivers/staging/comedi/drivers/tests/unittest.h
deleted file mode 100644
index 2da3beea2479..000000000000
--- a/drivers/staging/comedi/drivers/tests/unittest.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/* vim: set ts=8 sw=8 noet tw=80 nowrap: */
-/*
- * comedi/drivers/tests/unittest.h
- * Simple framework for unittests for comedi drivers.
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
- * based of parts of drivers/of/unittest.c
- *
- * This program 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.
- */
-
-#ifndef _COMEDI_DRIVERS_TESTS_UNITTEST_H
-#define _COMEDI_DRIVERS_TESTS_UNITTEST_H
-
-static struct unittest_results {
- int passed;
- int failed;
-} unittest_results;
-
-typedef void (*unittest_fptr)(void);
-
-#define unittest(result, fmt, ...) ({ \
- bool failed = !(result); \
- if (failed) { \
- ++unittest_results.failed; \
- pr_err("FAIL %s():%i " fmt, __func__, __LINE__, \
- ##__VA_ARGS__); \
- } else { \
- ++unittest_results.passed; \
- pr_debug("pass %s():%i " fmt, __func__, __LINE__, \
- ##__VA_ARGS__); \
- } \
- failed; \
-})
-
-/**
- * Execute an array of unit tests.
- * @name: Name of set of unit tests--will be shown at INFO log level.
- * @unit_tests: A null-terminated list of unit tests to execute.
- */
-static inline void exec_unittests(const char *name,
- const unittest_fptr *unit_tests)
-{
- pr_info("begin comedi:\"%s\" unittests\n", name);
-
- for (; (*unit_tests) != NULL; ++unit_tests)
- (*unit_tests)();
-
- pr_info("end of comedi:\"%s\" unittests - %i passed, %i failed\n", name,
- unittest_results.passed, unittest_results.failed);
-}
-
-#endif /* _COMEDI_DRIVERS_TESTS_UNITTEST_H */
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
deleted file mode 100644
index 0350f303d557..000000000000
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ /dev/null
@@ -1,1729 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * usbdux.c
- * Copyright (C) 2003-2014 Bernd Porr, mail@berndporr.me.uk
- */
-
-/*
- * Driver: usbdux
- * Description: University of Stirling USB DAQ & INCITE Technology Limited
- * Devices: [ITL] USB-DUX (usbdux)
- * Author: Bernd Porr <mail@berndporr.me.uk>
- * Updated: 10 Oct 2014
- * Status: Stable
- *
- * Connection scheme for the counter at the digital port:
- * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
- * The sampling rate of the counter is approximately 500Hz.
- *
- * Note that under USB2.0 the length of the channel list determines
- * the max sampling rate. If you sample only one channel you get 8kHz
- * sampling rate. If you sample two channels you get 4kHz and so on.
- */
-
-/*
- * I must give credit here to Chris Baugher who
- * wrote the driver for AT-MIO-16d. I used some parts of this
- * driver. I also must give credits to David Brownell
- * who supported me with the USB development.
- *
- * Bernd Porr
- *
- *
- * Revision history:
- * 0.94: D/A output should work now with any channel list combinations
- * 0.95: .owner commented out for kernel vers below 2.4.19
- * sanity checks in ai/ao_cmd
- * 0.96: trying to get it working with 2.6, moved all memory alloc to comedi's
- * attach final USB IDs
- * moved memory allocation completely to the corresponding comedi
- * functions firmware upload is by fxload and no longer by comedi (due to
- * enumeration)
- * 0.97: USB IDs received, adjusted table
- * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
- * to the usb subsystem and moved all comedi related memory
- * alloc to comedi.
- * | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
- * 0.99: USB 2.0: changed protocol to isochronous transfer
- * IRQ transfer is too buggy and too risky in 2.0
- * for the high speed ISO transfer is now a working version
- * available
- * 0.99b: Increased the iso transfer buffer for high sp.to 10 buffers. Some VIA
- * chipsets miss out IRQs. Deeper buffering is needed.
- * 1.00: full USB 2.0 support for the A/D converter. Now: max 8kHz sampling
- * rate.
- * Firmware vers 1.00 is needed for this.
- * Two 16 bit up/down/reset counter with a sampling rate of 1kHz
- * And loads of cleaning up, in particular streamlining the
- * bulk transfers.
- * 1.1: moved EP4 transfers to EP1 to make space for a PWM output on EP4
- * 1.2: added PWM support via EP4
- * 2.0: PWM seems to be stable and is not interfering with the other functions
- * 2.1: changed PWM API
- * 2.2: added firmware kernel request to fix an udev problem
- * 2.3: corrected a bug in bulk timeouts which were far too short
- * 2.4: fixed a bug which causes the driver to hang when it ran out of data.
- * Thanks to Jan-Matthias Braun and Ian to spot the bug and fix it.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/fcntl.h>
-#include <linux/compiler.h>
-
-#include "../comedi_usb.h"
-
-/* constants for firmware upload and download */
-#define USBDUX_FIRMWARE "usbdux_firmware.bin"
-#define USBDUX_FIRMWARE_MAX_LEN 0x2000
-#define USBDUX_FIRMWARE_CMD 0xa0
-#define VENDOR_DIR_IN 0xc0
-#define VENDOR_DIR_OUT 0x40
-#define USBDUX_CPU_CS 0xe600
-
-/* usbdux bulk transfer commands */
-#define USBDUX_CMD_MULT_AI 0
-#define USBDUX_CMD_AO 1
-#define USBDUX_CMD_DIO_CFG 2
-#define USBDUX_CMD_DIO_BITS 3
-#define USBDUX_CMD_SINGLE_AI 4
-#define USBDUX_CMD_TIMER_RD 5
-#define USBDUX_CMD_TIMER_WR 6
-#define USBDUX_CMD_PWM_ON 7
-#define USBDUX_CMD_PWM_OFF 8
-
-/* timeout for the USB-transfer in ms */
-#define BULK_TIMEOUT 1000
-
-/* 300Hz max frequ under PWM */
-#define MIN_PWM_PERIOD ((long)(1E9 / 300))
-
-/* Default PWM frequency */
-#define PWM_DEFAULT_PERIOD ((long)(1E9 / 100))
-
-/* Size of one A/D value */
-#define SIZEADIN ((sizeof(u16)))
-
-/*
- * Size of the input-buffer IN BYTES
- * Always multiple of 8 for 8 microframes which is needed in the highspeed mode
- */
-#define SIZEINBUF (8 * SIZEADIN)
-
-/* 16 bytes. */
-#define SIZEINSNBUF 16
-
-/* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT ((sizeof(u8) + sizeof(u16)))
-
-/*
- * Size of the output-buffer in bytes
- * Actually only the first 4 triplets are used but for the
- * high speed mode we need to pad it to 8 (microframes).
- */
-#define SIZEOUTBUF (8 * SIZEDAOUT)
-
-/*
- * Size of the buffer for the dux commands: just now max size is determined
- * by the analogue out + command byte + panic bytes...
- */
-#define SIZEOFDUXBUFFER (8 * SIZEDAOUT + 2)
-
-/* Number of in-URBs which receive the data: min=2 */
-#define NUMOFINBUFFERSFULL 5
-
-/* Number of out-URBs which send the data: min=2 */
-#define NUMOFOUTBUFFERSFULL 5
-
-/* Number of in-URBs which receive the data: min=5 */
-/* must have more buffers due to buggy USB ctr */
-#define NUMOFINBUFFERSHIGH 10
-
-/* Number of out-URBs which send the data: min=5 */
-/* must have more buffers due to buggy USB ctr */
-#define NUMOFOUTBUFFERSHIGH 10
-
-/* number of retries to get the right dux command */
-#define RETRIES 10
-
-static const struct comedi_lrange range_usbdux_ai_range = {
- 4, {
- BIP_RANGE(4.096),
- BIP_RANGE(4.096 / 2),
- UNI_RANGE(4.096),
- UNI_RANGE(4.096 / 2)
- }
-};
-
-static const struct comedi_lrange range_usbdux_ao_range = {
- 2, {
- BIP_RANGE(4.096),
- UNI_RANGE(4.096)
- }
-};
-
-struct usbdux_private {
- /* actual number of in-buffers */
- int n_ai_urbs;
- /* actual number of out-buffers */
- int n_ao_urbs;
- /* ISO-transfer handling: buffers */
- struct urb **ai_urbs;
- struct urb **ao_urbs;
- /* pwm-transfer handling */
- struct urb *pwm_urb;
- /* PWM period */
- unsigned int pwm_period;
- /* PWM internal delay for the GPIF in the FX2 */
- u8 pwm_delay;
- /* size of the PWM buffer which holds the bit pattern */
- int pwm_buf_sz;
- /* input buffer for the ISO-transfer */
- __le16 *in_buf;
- /* input buffer for single insn */
- __le16 *insn_buf;
-
- unsigned int high_speed:1;
- unsigned int ai_cmd_running:1;
- unsigned int ao_cmd_running:1;
- unsigned int pwm_cmd_running:1;
-
- /* time between samples in units of the timer */
- unsigned int ai_timer;
- unsigned int ao_timer;
- /* counter between aquisitions */
- unsigned int ai_counter;
- unsigned int ao_counter;
- /* interval in frames/uframes */
- unsigned int ai_interval;
- /* commands */
- u8 *dux_commands;
- struct mutex mut;
-};
-
-static void usbdux_unlink_urbs(struct urb **urbs, int num_urbs)
-{
- int i;
-
- for (i = 0; i < num_urbs; i++)
- usb_kill_urb(urbs[i]);
-}
-
-static void usbdux_ai_stop(struct comedi_device *dev, int do_unlink)
-{
- struct usbdux_private *devpriv = dev->private;
-
- if (do_unlink && devpriv->ai_urbs)
- usbdux_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
-
- devpriv->ai_cmd_running = 0;
-}
-
-static int usbdux_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbdux_private *devpriv = dev->private;
-
- /* prevent other CPUs from submitting new commands just now */
- mutex_lock(&devpriv->mut);
- /* unlink only if the urb really has been submitted */
- usbdux_ai_stop(dev, devpriv->ai_cmd_running);
- mutex_unlock(&devpriv->mut);
-
- return 0;
-}
-
-static void usbduxsub_ai_handle_urb(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct urb *urb)
-{
- struct usbdux_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- int ret;
- int i;
-
- devpriv->ai_counter--;
- if (devpriv->ai_counter == 0) {
- devpriv->ai_counter = devpriv->ai_timer;
-
- /* get the data from the USB bus and hand it over to comedi */
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
- u16 val = le16_to_cpu(devpriv->in_buf[i]);
-
- /* bipolar data is two's-complement */
- if (comedi_range_is_bipolar(s, range))
- val = comedi_offset_munge(s, val);
-
- /* transfer data */
- if (!comedi_buf_write_samples(s, &val, 1))
- return;
- }
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
- }
-
- /* if command is still running, resubmit urb */
- if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
- urb->dev = comedi_to_usb_dev(dev);
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "urb resubmit failed in int-context! err=%d\n",
- ret);
- if (ret == -EL2NSYNC)
- dev_err(dev->class_dev,
- "buggy USB host controller or bug in IRQ handler!\n");
- async->events |= COMEDI_CB_ERROR;
- }
- }
-}
-
-static void usbduxsub_ai_isoc_irq(struct urb *urb)
-{
- struct comedi_device *dev = urb->context;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct usbdux_private *devpriv = dev->private;
-
- /* exit if not running a command, do not resubmit urb */
- if (!devpriv->ai_cmd_running)
- return;
-
- switch (urb->status) {
- case 0:
- /* copy the result in the transfer buffer */
- memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
- usbduxsub_ai_handle_urb(dev, s, urb);
- break;
-
- case -EILSEQ:
- /*
- * error in the ISOchronous data
- * we don't copy the data into the transfer buffer
- * and recycle the last data byte
- */
- dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
- usbduxsub_ai_handle_urb(dev, s, urb);
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- case -ECONNABORTED:
- /* after an unlink command, unplug, ... etc */
- async->events |= COMEDI_CB_ERROR;
- break;
-
- default:
- /* a real error */
- dev_err(dev->class_dev,
- "Non-zero urb status received in ai intr context: %d\n",
- urb->status);
- async->events |= COMEDI_CB_ERROR;
- break;
- }
-
- /*
- * comedi_handle_events() cannot be used in this driver. The (*cancel)
- * operation would unlink the urb.
- */
- if (async->events & COMEDI_CB_CANCEL_MASK)
- usbdux_ai_stop(dev, 0);
-
- comedi_event(dev, s);
-}
-
-static void usbdux_ao_stop(struct comedi_device *dev, int do_unlink)
-{
- struct usbdux_private *devpriv = dev->private;
-
- if (do_unlink && devpriv->ao_urbs)
- usbdux_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
-
- devpriv->ao_cmd_running = 0;
-}
-
-static int usbdux_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbdux_private *devpriv = dev->private;
-
- /* prevent other CPUs from submitting a command just now */
- mutex_lock(&devpriv->mut);
- /* unlink only if it is really running */
- usbdux_ao_stop(dev, devpriv->ao_cmd_running);
- mutex_unlock(&devpriv->mut);
-
- return 0;
-}
-
-static void usbduxsub_ao_handle_urb(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct urb *urb)
-{
- struct usbdux_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u8 *datap;
- int ret;
- int i;
-
- devpriv->ao_counter--;
- if (devpriv->ao_counter == 0) {
- devpriv->ao_counter = devpriv->ao_timer;
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- return;
- }
-
- /* transmit data to the USB bus */
- datap = urb->transfer_buffer;
- *datap++ = cmd->chanlist_len;
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned short val;
-
- if (!comedi_buf_read_samples(s, &val, 1)) {
- dev_err(dev->class_dev, "buffer underflow\n");
- async->events |= COMEDI_CB_OVERFLOW;
- return;
- }
-
- /* pointer to the DA */
- *datap++ = val & 0xff;
- *datap++ = (val >> 8) & 0xff;
- *datap++ = chan << 6;
- s->readback[chan] = val;
- }
- }
-
- /* if command is still running, resubmit urb for BULK transfer */
- if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
- urb->transfer_buffer_length = SIZEOUTBUF;
- urb->dev = comedi_to_usb_dev(dev);
- urb->status = 0;
- if (devpriv->high_speed)
- urb->interval = 8; /* uframes */
- else
- urb->interval = 1; /* frames */
- urb->number_of_packets = 1;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEOUTBUF;
- urb->iso_frame_desc[0].status = 0;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "ao urb resubm failed in int-cont. ret=%d",
- ret);
- if (ret == -EL2NSYNC)
- dev_err(dev->class_dev,
- "buggy USB host controller or bug in IRQ handling!\n");
- async->events |= COMEDI_CB_ERROR;
- }
- }
-}
-
-static void usbduxsub_ao_isoc_irq(struct urb *urb)
-{
- struct comedi_device *dev = urb->context;
- struct comedi_subdevice *s = dev->write_subdev;
- struct comedi_async *async = s->async;
- struct usbdux_private *devpriv = dev->private;
-
- /* exit if not running a command, do not resubmit urb */
- if (!devpriv->ao_cmd_running)
- return;
-
- switch (urb->status) {
- case 0:
- usbduxsub_ao_handle_urb(dev, s, urb);
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- case -ECONNABORTED:
- /* after an unlink command, unplug, ... etc */
- async->events |= COMEDI_CB_ERROR;
- break;
-
- default:
- /* a real error */
- dev_err(dev->class_dev,
- "Non-zero urb status received in ao intr context: %d\n",
- urb->status);
- async->events |= COMEDI_CB_ERROR;
- break;
- }
-
- /*
- * comedi_handle_events() cannot be used in this driver. The (*cancel)
- * operation would unlink the urb.
- */
- if (async->events & COMEDI_CB_CANCEL_MASK)
- usbdux_ao_stop(dev, 0);
-
- comedi_event(dev, s);
-}
-
-static int usbdux_submit_urbs(struct comedi_device *dev,
- struct urb **urbs, int num_urbs,
- int input_urb)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbdux_private *devpriv = dev->private;
- struct urb *urb;
- int ret;
- int i;
-
- /* Submit all URBs and start the transfer on the bus */
- for (i = 0; i < num_urbs; i++) {
- urb = urbs[i];
-
- /* in case of a resubmission after an unlink... */
- if (input_urb)
- urb->interval = devpriv->ai_interval;
- urb->context = dev;
- urb->dev = usb;
- urb->status = 0;
- urb->transfer_flags = URB_ISO_ASAP;
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-static int usbdux_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- struct usbdux_private *devpriv = dev->private;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* full speed does 1kHz scans every USB frame */
- unsigned int arg = 1000000;
- unsigned int min_arg = arg;
-
- if (devpriv->high_speed) {
- /*
- * In high speed mode microframes are possible.
- * However, during one microframe we can roughly
- * sample one channel. Thus, the more channels
- * are in the channel list the more time we need.
- */
- int i = 1;
-
- /* find a power of 2 for the number of channels */
- while (i < cmd->chanlist_len)
- i = i * 2;
-
- arg /= 8;
- min_arg = arg * i;
- }
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- min_arg);
- /* calc the real sampling rate with the rounding errors */
- arg = (cmd->scan_begin_arg / arg) * arg;
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- return 0;
-}
-
-/*
- * creates the ADC command for the MAX1271
- * range is the range value from comedi
- */
-static u8 create_adc_command(unsigned int chan, unsigned int range)
-{
- u8 p = (range <= 1);
- u8 r = ((range % 2) == 0);
-
- return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
-}
-
-static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbdux_private *devpriv = dev->private;
- int nsent;
-
- devpriv->dux_commands[0] = cmd_type;
-
- return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
- devpriv->dux_commands, SIZEOFDUXBUFFER,
- &nsent, BULK_TIMEOUT);
-}
-
-static int receive_dux_commands(struct comedi_device *dev, unsigned int command)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbdux_private *devpriv = dev->private;
- int ret;
- int nrec;
- int i;
-
- for (i = 0; i < RETRIES; i++) {
- ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
- devpriv->insn_buf, SIZEINSNBUF,
- &nrec, BULK_TIMEOUT);
- if (ret < 0)
- return ret;
- if (le16_to_cpu(devpriv->insn_buf[0]) == command)
- return ret;
- }
- /* command not received */
- return -EFAULT;
-}
-
-static int usbdux_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct usbdux_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- mutex_lock(&devpriv->mut);
-
- if (!devpriv->ai_cmd_running) {
- devpriv->ai_cmd_running = 1;
- ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
- devpriv->n_ai_urbs, 1);
- if (ret < 0) {
- devpriv->ai_cmd_running = 0;
- goto ai_trig_exit;
- }
- s->async->inttrig = NULL;
- } else {
- ret = -EBUSY;
- }
-
-ai_trig_exit:
- mutex_unlock(&devpriv->mut);
- return ret;
-}
-
-static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct usbdux_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int len = cmd->chanlist_len;
- int ret = -EBUSY;
- int i;
-
- /* block other CPUs from starting an ai_cmd */
- mutex_lock(&devpriv->mut);
-
- if (devpriv->ai_cmd_running)
- goto ai_cmd_exit;
-
- devpriv->dux_commands[1] = len;
- for (i = 0; i < len; ++i) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int range = CR_RANGE(cmd->chanlist[i]);
-
- devpriv->dux_commands[i + 2] = create_adc_command(chan, range);
- }
-
- ret = send_dux_commands(dev, USBDUX_CMD_MULT_AI);
- if (ret < 0)
- goto ai_cmd_exit;
-
- if (devpriv->high_speed) {
- /*
- * every channel gets a time window of 125us. Thus, if we
- * sample all 8 channels we need 1ms. If we sample only one
- * channel we need only 125us
- */
- devpriv->ai_interval = 1;
- /* find a power of 2 for the interval */
- while (devpriv->ai_interval < len)
- devpriv->ai_interval *= 2;
-
- devpriv->ai_timer = cmd->scan_begin_arg /
- (125000 * devpriv->ai_interval);
- } else {
- /* interval always 1ms */
- devpriv->ai_interval = 1;
- devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
- }
- if (devpriv->ai_timer < 1) {
- ret = -EINVAL;
- goto ai_cmd_exit;
- }
-
- devpriv->ai_counter = devpriv->ai_timer;
-
- if (cmd->start_src == TRIG_NOW) {
- /* enable this acquisition operation */
- devpriv->ai_cmd_running = 1;
- ret = usbdux_submit_urbs(dev, devpriv->ai_urbs,
- devpriv->n_ai_urbs, 1);
- if (ret < 0) {
- devpriv->ai_cmd_running = 0;
- /* fixme: unlink here?? */
- goto ai_cmd_exit;
- }
- s->async->inttrig = NULL;
- } else {
- /* TRIG_INT */
- /* don't enable the acquision operation */
- /* wait for an internal signal */
- s->async->inttrig = usbdux_ai_inttrig;
- }
-
-ai_cmd_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-/* Mode 0 is used to get a single conversion on demand */
-static int usbdux_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbdux_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- unsigned int val;
- int ret = -EBUSY;
- int i;
-
- mutex_lock(&devpriv->mut);
-
- if (devpriv->ai_cmd_running)
- goto ai_read_exit;
-
- /* set command for the first channel */
- devpriv->dux_commands[1] = create_adc_command(chan, range);
-
- /* adc commands */
- ret = send_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
- if (ret < 0)
- goto ai_read_exit;
-
- for (i = 0; i < insn->n; i++) {
- ret = receive_dux_commands(dev, USBDUX_CMD_SINGLE_AI);
- if (ret < 0)
- goto ai_read_exit;
-
- val = le16_to_cpu(devpriv->insn_buf[1]);
-
- /* bipolar data is two's-complement */
- if (comedi_range_is_bipolar(s, range))
- val = comedi_offset_munge(s, val);
-
- data[i] = val;
- }
-
-ai_read_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret ? ret : insn->n;
-}
-
-static int usbdux_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbdux_private *devpriv = dev->private;
- int ret;
-
- mutex_lock(&devpriv->mut);
- ret = comedi_readback_insn_read(dev, s, insn, data);
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int usbdux_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbdux_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- __le16 *p = (__le16 *)&devpriv->dux_commands[2];
- int ret = -EBUSY;
- int i;
-
- mutex_lock(&devpriv->mut);
-
- if (devpriv->ao_cmd_running)
- goto ao_write_exit;
-
- /* number of channels: 1 */
- devpriv->dux_commands[1] = 1;
- /* channel number */
- devpriv->dux_commands[4] = chan << 6;
-
- for (i = 0; i < insn->n; i++) {
- unsigned int val = data[i];
-
- /* one 16 bit value */
- *p = cpu_to_le16(val);
-
- ret = send_dux_commands(dev, USBDUX_CMD_AO);
- if (ret < 0)
- goto ao_write_exit;
-
- s->readback[chan] = val;
- }
-
-ao_write_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret ? ret : insn->n;
-}
-
-static int usbdux_ao_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct usbdux_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- mutex_lock(&devpriv->mut);
-
- if (!devpriv->ao_cmd_running) {
- devpriv->ao_cmd_running = 1;
- ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
- devpriv->n_ao_urbs, 0);
- if (ret < 0) {
- devpriv->ao_cmd_running = 0;
- goto ao_trig_exit;
- }
- s->async->inttrig = NULL;
- } else {
- ret = -EBUSY;
- }
-
-ao_trig_exit:
- mutex_unlock(&devpriv->mut);
- return ret;
-}
-
-static int usbdux_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
- unsigned int flags;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
-
- if (0) { /* (devpriv->high_speed) */
- /* the sampling rate is set by the coversion rate */
- flags = TRIG_FOLLOW;
- } else {
- /* start a new scan (output at once) with a timer */
- flags = TRIG_TIMER;
- }
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, flags);
-
- if (0) { /* (devpriv->high_speed) */
- /*
- * in usb-2.0 only one conversion it transmitted
- * but with 8kHz/n
- */
- flags = TRIG_TIMER;
- } else {
- /*
- * all conversion events happen simultaneously with
- * a rate of 1kHz/n
- */
- flags = TRIG_NOW;
- }
- err |= comedi_check_trigger_src(&cmd->convert_src, flags);
-
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-
- if (cmd->scan_begin_src == TRIG_TIMER) {
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- 1000000);
- }
-
- /* not used now, is for later use */
- if (cmd->convert_src == TRIG_TIMER)
- err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 125000);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- return 0;
-}
-
-static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct usbdux_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret = -EBUSY;
-
- mutex_lock(&devpriv->mut);
-
- if (devpriv->ao_cmd_running)
- goto ao_cmd_exit;
-
- /* we count in steps of 1ms (125us) */
- /* 125us mode not used yet */
- if (0) { /* (devpriv->high_speed) */
- /* 125us */
- /* timing of the conversion itself: every 125 us */
- devpriv->ao_timer = cmd->convert_arg / 125000;
- } else {
- /* 1ms */
- /* timing of the scan: we get all channels at once */
- devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
- if (devpriv->ao_timer < 1) {
- ret = -EINVAL;
- goto ao_cmd_exit;
- }
- }
-
- devpriv->ao_counter = devpriv->ao_timer;
-
- if (cmd->start_src == TRIG_NOW) {
- /* enable this acquisition operation */
- devpriv->ao_cmd_running = 1;
- ret = usbdux_submit_urbs(dev, devpriv->ao_urbs,
- devpriv->n_ao_urbs, 0);
- if (ret < 0) {
- devpriv->ao_cmd_running = 0;
- /* fixme: unlink here?? */
- goto ao_cmd_exit;
- }
- s->async->inttrig = NULL;
- } else {
- /* TRIG_INT */
- /* submit the urbs later */
- /* wait for an internal signal */
- s->async->inttrig = usbdux_ao_inttrig;
- }
-
-ao_cmd_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int usbdux_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- /*
- * We don't tell the firmware here as it would take 8 frames
- * to submit the information. We do it in the insn_bits.
- */
- return insn->n;
-}
-
-static int usbdux_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbdux_private *devpriv = dev->private;
- int ret;
-
- mutex_lock(&devpriv->mut);
-
- comedi_dio_update_state(s, data);
-
- /* Always update the hardware. See the (*insn_config). */
- devpriv->dux_commands[1] = s->io_bits;
- devpriv->dux_commands[2] = s->state;
-
- /*
- * This command also tells the firmware to return
- * the digital input lines.
- */
- ret = send_dux_commands(dev, USBDUX_CMD_DIO_BITS);
- if (ret < 0)
- goto dio_exit;
- ret = receive_dux_commands(dev, USBDUX_CMD_DIO_BITS);
- if (ret < 0)
- goto dio_exit;
-
- data[1] = le16_to_cpu(devpriv->insn_buf[1]);
-
-dio_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret ? ret : insn->n;
-}
-
-static int usbdux_counter_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbdux_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret = 0;
- int i;
-
- mutex_lock(&devpriv->mut);
-
- for (i = 0; i < insn->n; i++) {
- ret = send_dux_commands(dev, USBDUX_CMD_TIMER_RD);
- if (ret < 0)
- goto counter_read_exit;
- ret = receive_dux_commands(dev, USBDUX_CMD_TIMER_RD);
- if (ret < 0)
- goto counter_read_exit;
-
- data[i] = le16_to_cpu(devpriv->insn_buf[chan + 1]);
- }
-
-counter_read_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret ? ret : insn->n;
-}
-
-static int usbdux_counter_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbdux_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- __le16 *p = (__le16 *)&devpriv->dux_commands[2];
- int ret = 0;
- int i;
-
- mutex_lock(&devpriv->mut);
-
- devpriv->dux_commands[1] = chan;
-
- for (i = 0; i < insn->n; i++) {
- *p = cpu_to_le16(data[i]);
-
- ret = send_dux_commands(dev, USBDUX_CMD_TIMER_WR);
- if (ret < 0)
- break;
- }
-
- mutex_unlock(&devpriv->mut);
-
- return ret ? ret : insn->n;
-}
-
-static int usbdux_counter_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- /* nothing to do so far */
- return 2;
-}
-
-static void usbduxsub_unlink_pwm_urbs(struct comedi_device *dev)
-{
- struct usbdux_private *devpriv = dev->private;
-
- usb_kill_urb(devpriv->pwm_urb);
-}
-
-static void usbdux_pwm_stop(struct comedi_device *dev, int do_unlink)
-{
- struct usbdux_private *devpriv = dev->private;
-
- if (do_unlink)
- usbduxsub_unlink_pwm_urbs(dev);
-
- devpriv->pwm_cmd_running = 0;
-}
-
-static int usbdux_pwm_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbdux_private *devpriv = dev->private;
- int ret;
-
- mutex_lock(&devpriv->mut);
- /* unlink only if it is really running */
- usbdux_pwm_stop(dev, devpriv->pwm_cmd_running);
- ret = send_dux_commands(dev, USBDUX_CMD_PWM_OFF);
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static void usbduxsub_pwm_irq(struct urb *urb)
-{
- struct comedi_device *dev = urb->context;
- struct usbdux_private *devpriv = dev->private;
- int ret;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- case -ECONNABORTED:
- /*
- * after an unlink command, unplug, ... etc
- * no unlink needed here. Already shutting down.
- */
- if (devpriv->pwm_cmd_running)
- usbdux_pwm_stop(dev, 0);
-
- return;
-
- default:
- /* a real error */
- if (devpriv->pwm_cmd_running) {
- dev_err(dev->class_dev,
- "Non-zero urb status received in pwm intr context: %d\n",
- urb->status);
- usbdux_pwm_stop(dev, 0);
- }
- return;
- }
-
- /* are we actually running? */
- if (!devpriv->pwm_cmd_running)
- return;
-
- urb->transfer_buffer_length = devpriv->pwm_buf_sz;
- urb->dev = comedi_to_usb_dev(dev);
- urb->status = 0;
- if (devpriv->pwm_cmd_running) {
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "pwm urb resubm failed in int-cont. ret=%d",
- ret);
- if (ret == -EL2NSYNC)
- dev_err(dev->class_dev,
- "buggy USB host controller or bug in IRQ handling!\n");
-
- /* don't do an unlink here */
- usbdux_pwm_stop(dev, 0);
- }
- }
-}
-
-static int usbduxsub_submit_pwm_urbs(struct comedi_device *dev)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbdux_private *devpriv = dev->private;
- struct urb *urb = devpriv->pwm_urb;
-
- /* in case of a resubmission after an unlink... */
- usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
- urb->transfer_buffer,
- devpriv->pwm_buf_sz,
- usbduxsub_pwm_irq,
- dev);
-
- return usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-static int usbdux_pwm_period(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int period)
-{
- struct usbdux_private *devpriv = dev->private;
- int fx2delay;
-
- if (period < MIN_PWM_PERIOD)
- return -EAGAIN;
-
- fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
- if (fx2delay > 255)
- return -EAGAIN;
-
- devpriv->pwm_delay = fx2delay;
- devpriv->pwm_period = period;
-
- return 0;
-}
-
-static int usbdux_pwm_start(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbdux_private *devpriv = dev->private;
- int ret = 0;
-
- mutex_lock(&devpriv->mut);
-
- if (devpriv->pwm_cmd_running)
- goto pwm_start_exit;
-
- devpriv->dux_commands[1] = devpriv->pwm_delay;
- ret = send_dux_commands(dev, USBDUX_CMD_PWM_ON);
- if (ret < 0)
- goto pwm_start_exit;
-
- /* initialise the buffer */
- memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
-
- devpriv->pwm_cmd_running = 1;
- ret = usbduxsub_submit_pwm_urbs(dev);
- if (ret < 0)
- devpriv->pwm_cmd_running = 0;
-
-pwm_start_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static void usbdux_pwm_pattern(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chan,
- unsigned int value,
- unsigned int sign)
-{
- struct usbdux_private *devpriv = dev->private;
- char pwm_mask = (1 << chan); /* DIO bit for the PWM data */
- char sgn_mask = (16 << chan); /* DIO bit for the sign */
- char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
- int szbuf = devpriv->pwm_buf_sz;
- int i;
-
- for (i = 0; i < szbuf; i++) {
- char c = *buf;
-
- c &= ~pwm_mask;
- if (i < value)
- c |= pwm_mask;
- if (!sign)
- c &= ~sgn_mask;
- else
- c |= sgn_mask;
- *buf++ = c;
- }
-}
-
-static int usbdux_pwm_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /*
- * It doesn't make sense to support more than one value here
- * because it would just overwrite the PWM buffer.
- */
- if (insn->n != 1)
- return -EINVAL;
-
- /*
- * The sign is set via a special INSN only, this gives us 8 bits
- * for normal operation, sign is 0 by default.
- */
- usbdux_pwm_pattern(dev, s, chan, data[0], 0);
-
- return insn->n;
-}
-
-static int usbdux_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbdux_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- /*
- * if not zero the PWM is limited to a certain time which is
- * not supported here
- */
- if (data[1] != 0)
- return -EINVAL;
- return usbdux_pwm_start(dev, s);
- case INSN_CONFIG_DISARM:
- return usbdux_pwm_cancel(dev, s);
- case INSN_CONFIG_GET_PWM_STATUS:
- data[1] = devpriv->pwm_cmd_running;
- return 0;
- case INSN_CONFIG_PWM_SET_PERIOD:
- return usbdux_pwm_period(dev, s, data[1]);
- case INSN_CONFIG_PWM_GET_PERIOD:
- data[1] = devpriv->pwm_period;
- return 0;
- case INSN_CONFIG_PWM_SET_H_BRIDGE:
- /*
- * data[1] = value
- * data[2] = sign (for a relay)
- */
- usbdux_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
- return 0;
- case INSN_CONFIG_PWM_GET_H_BRIDGE:
- /* values are not kept in this driver, nothing to return here */
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-static int usbdux_firmware_upload(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- u8 *buf;
- u8 *tmp;
- int ret;
-
- if (!data)
- return 0;
-
- if (size > USBDUX_FIRMWARE_MAX_LEN) {
- dev_err(dev->class_dev,
- "usbdux firmware binary it too large for FX2.\n");
- return -ENOMEM;
- }
-
- /* we generate a local buffer for the firmware */
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- /* we need a malloc'ed buffer for usb_control_msg() */
- tmp = kmalloc(1, GFP_KERNEL);
- if (!tmp) {
- kfree(buf);
- return -ENOMEM;
- }
-
- /* stop the current firmware on the device */
- *tmp = 1; /* 7f92 to one */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUX_FIRMWARE_CMD,
- VENDOR_DIR_OUT,
- USBDUX_CPU_CS, 0x0000,
- tmp, 1,
- BULK_TIMEOUT);
- if (ret < 0) {
- dev_err(dev->class_dev, "can not stop firmware\n");
- goto done;
- }
-
- /* upload the new firmware to the device */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUX_FIRMWARE_CMD,
- VENDOR_DIR_OUT,
- 0, 0x0000,
- buf, size,
- BULK_TIMEOUT);
- if (ret < 0) {
- dev_err(dev->class_dev, "firmware upload failed\n");
- goto done;
- }
-
- /* start the new firmware on the device */
- *tmp = 0; /* 7f92 to zero */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUX_FIRMWARE_CMD,
- VENDOR_DIR_OUT,
- USBDUX_CPU_CS, 0x0000,
- tmp, 1,
- BULK_TIMEOUT);
- if (ret < 0)
- dev_err(dev->class_dev, "can not start firmware\n");
-
-done:
- kfree(tmp);
- kfree(buf);
- return ret;
-}
-
-static int usbdux_alloc_usb_buffers(struct comedi_device *dev)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbdux_private *devpriv = dev->private;
- struct urb *urb;
- int i;
-
- devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
- devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
- devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
- devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(void *),
- GFP_KERNEL);
- devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(void *),
- GFP_KERNEL);
- if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
- !devpriv->ai_urbs || !devpriv->ao_urbs)
- return -ENOMEM;
-
- for (i = 0; i < devpriv->n_ai_urbs; i++) {
- /* one frame: 1ms */
- urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- devpriv->ai_urbs[i] = urb;
-
- urb->dev = usb;
- urb->context = dev;
- urb->pipe = usb_rcvisocpipe(usb, 6);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
- if (!urb->transfer_buffer)
- return -ENOMEM;
-
- urb->complete = usbduxsub_ai_isoc_irq;
- urb->number_of_packets = 1;
- urb->transfer_buffer_length = SIZEINBUF;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEINBUF;
- }
-
- for (i = 0; i < devpriv->n_ao_urbs; i++) {
- /* one frame: 1ms */
- urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- devpriv->ao_urbs[i] = urb;
-
- urb->dev = usb;
- urb->context = dev;
- urb->pipe = usb_sndisocpipe(usb, 2);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
- if (!urb->transfer_buffer)
- return -ENOMEM;
-
- urb->complete = usbduxsub_ao_isoc_irq;
- urb->number_of_packets = 1;
- urb->transfer_buffer_length = SIZEOUTBUF;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEOUTBUF;
- if (devpriv->high_speed)
- urb->interval = 8; /* uframes */
- else
- urb->interval = 1; /* frames */
- }
-
- /* pwm */
- if (devpriv->pwm_buf_sz) {
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- devpriv->pwm_urb = urb;
-
- /* max bulk ep size in high speed */
- urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
- GFP_KERNEL);
- if (!urb->transfer_buffer)
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void usbdux_free_usb_buffers(struct comedi_device *dev)
-{
- struct usbdux_private *devpriv = dev->private;
- struct urb *urb;
- int i;
-
- urb = devpriv->pwm_urb;
- if (urb) {
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- if (devpriv->ao_urbs) {
- for (i = 0; i < devpriv->n_ao_urbs; i++) {
- urb = devpriv->ao_urbs[i];
- if (urb) {
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- }
- kfree(devpriv->ao_urbs);
- }
- if (devpriv->ai_urbs) {
- for (i = 0; i < devpriv->n_ai_urbs; i++) {
- urb = devpriv->ai_urbs[i];
- if (urb) {
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- }
- kfree(devpriv->ai_urbs);
- }
- kfree(devpriv->insn_buf);
- kfree(devpriv->in_buf);
- kfree(devpriv->dux_commands);
-}
-
-static int usbdux_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbdux_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- mutex_init(&devpriv->mut);
-
- usb_set_intfdata(intf, devpriv);
-
- devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
- if (devpriv->high_speed) {
- devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
- devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
- devpriv->pwm_buf_sz = 512;
- } else {
- devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
- devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
- }
-
- ret = usbdux_alloc_usb_buffers(dev);
- if (ret)
- return ret;
-
- /* setting to alternate setting 3: enabling iso ep and bulk ep. */
- ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
- 3);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "could not set alternate setting 3 in high speed\n");
- return ret;
- }
-
- ret = comedi_load_firmware(dev, &usb->dev, USBDUX_FIRMWARE,
- usbdux_firmware_upload, 0);
- if (ret < 0)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 5 : 4);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
- s->n_chan = 8;
- s->maxdata = 0x0fff;
- s->len_chanlist = 8;
- s->range_table = &range_usbdux_ai_range;
- s->insn_read = usbdux_ai_insn_read;
- s->do_cmdtest = usbdux_ai_cmdtest;
- s->do_cmd = usbdux_ai_cmd;
- s->cancel = usbdux_ai_cancel;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- dev->write_subdev = s;
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
- s->n_chan = 4;
- s->maxdata = 0x0fff;
- s->len_chanlist = s->n_chan;
- s->range_table = &range_usbdux_ao_range;
- s->do_cmdtest = usbdux_ao_cmdtest;
- s->do_cmd = usbdux_ao_cmd;
- s->cancel = usbdux_ao_cancel;
- s->insn_read = usbdux_ao_insn_read;
- s->insn_write = usbdux_ao_insn_write;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = usbdux_dio_insn_bits;
- s->insn_config = usbdux_dio_insn_config;
-
- /* Counter subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->insn_read = usbdux_counter_read;
- s->insn_write = usbdux_counter_write;
- s->insn_config = usbdux_counter_config;
-
- if (devpriv->high_speed) {
- /* PWM subdevice */
- s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_PWM;
- s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
- s->n_chan = 8;
- s->maxdata = devpriv->pwm_buf_sz;
- s->insn_write = usbdux_pwm_write;
- s->insn_config = usbdux_pwm_config;
-
- usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
- }
-
- return 0;
-}
-
-static void usbdux_detach(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usbdux_private *devpriv = dev->private;
-
- usb_set_intfdata(intf, NULL);
-
- if (!devpriv)
- return;
-
- mutex_lock(&devpriv->mut);
-
- /* force unlink all urbs */
- usbdux_pwm_stop(dev, 1);
- usbdux_ao_stop(dev, 1);
- usbdux_ai_stop(dev, 1);
-
- usbdux_free_usb_buffers(dev);
-
- mutex_unlock(&devpriv->mut);
-
- mutex_destroy(&devpriv->mut);
-}
-
-static struct comedi_driver usbdux_driver = {
- .driver_name = "usbdux",
- .module = THIS_MODULE,
- .auto_attach = usbdux_auto_attach,
- .detach = usbdux_detach,
-};
-
-static int usbdux_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return comedi_usb_auto_config(intf, &usbdux_driver, 0);
-}
-
-static const struct usb_device_id usbdux_usb_table[] = {
- { USB_DEVICE(0x13d8, 0x0001) },
- { USB_DEVICE(0x13d8, 0x0002) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, usbdux_usb_table);
-
-static struct usb_driver usbdux_usb_driver = {
- .name = "usbdux",
- .probe = usbdux_usb_probe,
- .disconnect = comedi_usb_auto_unconfig,
- .id_table = usbdux_usb_table,
-};
-module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver);
-
-MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
-MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(USBDUX_FIRMWARE);
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
deleted file mode 100644
index 4af012968cb6..000000000000
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ /dev/null
@@ -1,1039 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2004-2019 Bernd Porr, mail@berndporr.me.uk
- */
-
-/*
- * Driver: usbduxfast
- * Description: University of Stirling USB DAQ & INCITE Technology Limited
- * Devices: [ITL] USB-DUX-FAST (usbduxfast)
- * Author: Bernd Porr <mail@berndporr.me.uk>
- * Updated: 16 Nov 2019
- * Status: stable
- */
-
-/*
- * I must give credit here to Chris Baugher who
- * wrote the driver for AT-MIO-16d. I used some parts of this
- * driver. I also must give credits to David Brownell
- * who supported me with the USB development.
- *
- * Bernd Porr
- *
- *
- * Revision history:
- * 1.0: Fixed a rounding error in usbduxfast_ai_cmdtest
- * 0.9: Dropping the first data packet which seems to be from the last transfer.
- * Buffer overflows in the FX2 are handed over to comedi.
- * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
- * Added insn command basically for testing. Sample rate is
- * 1MHz/16ch=62.5kHz
- * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
- * 0.99a: added external trigger.
- * 1.00: added firmware kernel request to the driver which fixed
- * udev coldplug problem
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/fcntl.h>
-#include <linux/compiler.h>
-#include "../comedi_usb.h"
-
-/*
- * timeout for the USB-transfer
- */
-#define EZTIMEOUT 30
-
-/*
- * constants for "firmware" upload and download
- */
-#define FIRMWARE "usbduxfast_firmware.bin"
-#define FIRMWARE_MAX_LEN 0x2000
-#define USBDUXFASTSUB_FIRMWARE 0xA0
-#define VENDOR_DIR_IN 0xC0
-#define VENDOR_DIR_OUT 0x40
-
-/*
- * internal addresses of the 8051 processor
- */
-#define USBDUXFASTSUB_CPUCS 0xE600
-
-/*
- * max length of the transfer-buffer for software upload
- */
-#define TB_LEN 0x2000
-
-/*
- * input endpoint number
- */
-#define BULKINEP 6
-
-/*
- * endpoint for the A/D channellist: bulk OUT
- */
-#define CHANNELLISTEP 4
-
-/*
- * number of channels
- */
-#define NUMCHANNELS 32
-
-/*
- * size of the waveform descriptor
- */
-#define WAVESIZE 0x20
-
-/*
- * size of one A/D value
- */
-#define SIZEADIN (sizeof(s16))
-
-/*
- * size of the input-buffer IN BYTES
- */
-#define SIZEINBUF 512
-
-/*
- * 16 bytes
- */
-#define SIZEINSNBUF 512
-
-/*
- * size of the buffer for the dux commands in bytes
- */
-#define SIZEOFDUXBUF 256
-
-/*
- * number of in-URBs which receive the data: min=5
- */
-#define NUMOFINBUFFERSHIGH 10
-
-/*
- * min delay steps for more than one channel
- * basically when the mux gives up ;-)
- *
- * steps at 30MHz in the FX2
- */
-#define MIN_SAMPLING_PERIOD 9
-
-/*
- * max number of 1/30MHz delay steps
- */
-#define MAX_SAMPLING_PERIOD 500
-
-/*
- * number of received packets to ignore before we start handing data
- * over to comedi, it's quad buffering and we have to ignore 4 packets
- */
-#define PACKETS_TO_IGNORE 4
-
-/*
- * comedi constants
- */
-static const struct comedi_lrange range_usbduxfast_ai_range = {
- 2, {
- BIP_RANGE(0.75),
- BIP_RANGE(0.5)
- }
-};
-
-/*
- * private structure of one subdevice
- *
- * this is the structure which holds all the data of this driver
- * one sub device just now: A/D
- */
-struct usbduxfast_private {
- struct urb *urb; /* BULK-transfer handling: urb */
- u8 *duxbuf;
- s8 *inbuf;
- short int ai_cmd_running; /* asynchronous command is running */
- int ignore; /* counter which ignores the first buffers */
- struct mutex mut;
-};
-
-/*
- * bulk transfers to usbduxfast
- */
-#define SENDADCOMMANDS 0
-#define SENDINITEP6 1
-
-static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxfast_private *devpriv = dev->private;
- int nsent;
- int ret;
-
- devpriv->duxbuf[0] = cmd_type;
-
- ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, CHANNELLISTEP),
- devpriv->duxbuf, SIZEOFDUXBUF,
- &nsent, 10000);
- if (ret < 0)
- dev_err(dev->class_dev,
- "could not transmit command to the usb-device, err=%d\n",
- ret);
- return ret;
-}
-
-static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
- u8 len, u8 op, u8 out, u8 log)
-{
- struct usbduxfast_private *devpriv = dev->private;
-
- /* Set the GPIF bytes, the first byte is the command byte */
- devpriv->duxbuf[1 + 0x00 + index] = len;
- devpriv->duxbuf[1 + 0x08 + index] = op;
- devpriv->duxbuf[1 + 0x10 + index] = out;
- devpriv->duxbuf[1 + 0x18 + index] = log;
-}
-
-static int usbduxfast_ai_stop(struct comedi_device *dev, int do_unlink)
-{
- struct usbduxfast_private *devpriv = dev->private;
-
- /* stop aquistion */
- devpriv->ai_cmd_running = 0;
-
- if (do_unlink && devpriv->urb) {
- /* kill the running transfer */
- usb_kill_urb(devpriv->urb);
- }
-
- return 0;
-}
-
-static int usbduxfast_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxfast_private *devpriv = dev->private;
- int ret;
-
- mutex_lock(&devpriv->mut);
- ret = usbduxfast_ai_stop(dev, 1);
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static void usbduxfast_ai_handle_urb(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct urb *urb)
-{
- struct usbduxfast_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- int ret;
-
- if (devpriv->ignore) {
- devpriv->ignore--;
- } else {
- unsigned int nsamples;
-
- nsamples = comedi_bytes_to_samples(s, urb->actual_length);
- nsamples = comedi_nsamples_left(s, nsamples);
- comedi_buf_write_samples(s, urb->transfer_buffer, nsamples);
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
- }
-
- /* if command is still running, resubmit urb for BULK transfer */
- if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
- urb->dev = comedi_to_usb_dev(dev);
- urb->status = 0;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(dev->class_dev, "urb resubm failed: %d", ret);
- async->events |= COMEDI_CB_ERROR;
- }
- }
-}
-
-static void usbduxfast_ai_interrupt(struct urb *urb)
-{
- struct comedi_device *dev = urb->context;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
- struct usbduxfast_private *devpriv = dev->private;
-
- /* exit if not running a command, do not resubmit urb */
- if (!devpriv->ai_cmd_running)
- return;
-
- switch (urb->status) {
- case 0:
- usbduxfast_ai_handle_urb(dev, s, urb);
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- case -ECONNABORTED:
- /* after an unlink command, unplug, ... etc */
- async->events |= COMEDI_CB_ERROR;
- break;
-
- default:
- /* a real error */
- dev_err(dev->class_dev,
- "non-zero urb status received in ai intr context: %d\n",
- urb->status);
- async->events |= COMEDI_CB_ERROR;
- break;
- }
-
- /*
- * comedi_handle_events() cannot be used in this driver. The (*cancel)
- * operation would unlink the urb.
- */
- if (async->events & COMEDI_CB_CANCEL_MASK)
- usbduxfast_ai_stop(dev, 0);
-
- comedi_event(dev, s);
-}
-
-static int usbduxfast_submit_urb(struct comedi_device *dev)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxfast_private *devpriv = dev->private;
- int ret;
-
- usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
- devpriv->inbuf, SIZEINBUF,
- usbduxfast_ai_interrupt, dev);
-
- ret = usb_submit_urb(devpriv->urb, GFP_ATOMIC);
- if (ret) {
- dev_err(dev->class_dev, "usb_submit_urb error %d\n", ret);
- return ret;
- }
- return 0;
-}
-
-static int usbduxfast_ai_check_chanlist(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- unsigned int gain0 = CR_RANGE(cmd->chanlist[0]);
- int i;
-
- if (cmd->chanlist_len > 3 && cmd->chanlist_len != 16) {
- dev_err(dev->class_dev, "unsupported combination of channels\n");
- return -EINVAL;
- }
-
- for (i = 0; i < cmd->chanlist_len; ++i) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned int gain = CR_RANGE(cmd->chanlist[i]);
-
- if (chan != i) {
- dev_err(dev->class_dev,
- "channels are not consecutive\n");
- return -EINVAL;
- }
- if (gain != gain0 && cmd->chanlist_len > 3) {
- dev_err(dev->class_dev,
- "gain must be the same for all channels\n");
- return -EINVAL;
- }
- }
- return 0;
-}
-
-static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
- int err2 = 0;
- unsigned int steps;
- unsigned int arg;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src,
- TRIG_NOW | TRIG_EXT | TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (!cmd->chanlist_len)
- err |= -EINVAL;
-
- /* external start trigger is only valid for 1 or 16 channels */
- if (cmd->start_src == TRIG_EXT &&
- cmd->chanlist_len != 1 && cmd->chanlist_len != 16)
- err |= -EINVAL;
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- /*
- * Validate the conversion timing:
- * for 1 channel the timing in 30MHz "steps" is:
- * steps <= MAX_SAMPLING_PERIOD
- * for all other chanlist_len it is:
- * MIN_SAMPLING_PERIOD <= steps <= MAX_SAMPLING_PERIOD
- */
- steps = (cmd->convert_arg * 30) / 1000;
- if (cmd->chanlist_len != 1)
- err2 |= comedi_check_trigger_arg_min(&steps,
- MIN_SAMPLING_PERIOD);
- else
- err2 |= comedi_check_trigger_arg_min(&steps, 1);
- err2 |= comedi_check_trigger_arg_max(&steps, MAX_SAMPLING_PERIOD);
- if (err2) {
- err |= err2;
- arg = (steps * 1000) / 30;
- err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
- }
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- /* Step 5: check channel list if it exists */
- if (cmd->chanlist && cmd->chanlist_len > 0)
- err |= usbduxfast_ai_check_chanlist(dev, s, cmd);
- if (err)
- return 5;
-
- return 0;
-}
-
-static int usbduxfast_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct usbduxfast_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- mutex_lock(&devpriv->mut);
-
- if (!devpriv->ai_cmd_running) {
- devpriv->ai_cmd_running = 1;
- ret = usbduxfast_submit_urb(dev);
- if (ret < 0) {
- dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
- devpriv->ai_cmd_running = 0;
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- s->async->inttrig = NULL;
- } else {
- dev_err(dev->class_dev, "ai is already running\n");
- }
- mutex_unlock(&devpriv->mut);
- return 1;
-}
-
-static int usbduxfast_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxfast_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int rngmask = 0xff;
- int j, ret;
- long steps, steps_tmp;
-
- mutex_lock(&devpriv->mut);
- if (devpriv->ai_cmd_running) {
- ret = -EBUSY;
- goto cmd_exit;
- }
-
- /*
- * ignore the first buffers from the device if there
- * is an error condition
- */
- devpriv->ignore = PACKETS_TO_IGNORE;
-
- steps = (cmd->convert_arg * 30) / 1000;
-
- switch (cmd->chanlist_len) {
- case 1:
- /*
- * one channel
- */
-
- if (CR_RANGE(cmd->chanlist[0]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
-
- /*
- * for external trigger: looping in this state until
- * the RDY0 pin becomes zero
- */
-
- /* we loop here until ready has been set */
- if (cmd->start_src == TRIG_EXT) {
- /* branch back to state 0 */
- /* deceision state w/o data */
- /* RDY0 = 0 */
- usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
- } else { /* we just proceed to state 1 */
- usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
- }
-
- if (steps < MIN_SAMPLING_PERIOD) {
- /* for fast single channel aqu without mux */
- if (steps <= 1) {
- /*
- * we just stay here at state 1 and rexecute
- * the same state this gives us 30MHz sampling
- * rate
- */
-
- /* branch back to state 1 */
- /* deceision state with data */
- /* doesn't matter */
- usbduxfast_cmd_data(dev, 1,
- 0x89, 0x03, rngmask, 0xff);
- } else {
- /*
- * we loop through two states: data and delay
- * max rate is 15MHz
- */
- /* data */
- /* doesn't matter */
- usbduxfast_cmd_data(dev, 1, steps - 1,
- 0x02, rngmask, 0x00);
-
- /* branch back to state 1 */
- /* deceision state w/o data */
- /* doesn't matter */
- usbduxfast_cmd_data(dev, 2,
- 0x09, 0x01, rngmask, 0xff);
- }
- } else {
- /*
- * we loop through 3 states: 2x delay and 1x data
- * this gives a min sampling rate of 60kHz
- */
-
- /* we have 1 state with duration 1 */
- steps = steps - 1;
-
- /* do the first part of the delay */
- usbduxfast_cmd_data(dev, 1,
- steps / 2, 0x00, rngmask, 0x00);
-
- /* and the second part */
- usbduxfast_cmd_data(dev, 2, steps - steps / 2,
- 0x00, rngmask, 0x00);
-
- /* get the data and branch back */
-
- /* branch back to state 1 */
- /* deceision state w data */
- /* doesn't matter */
- usbduxfast_cmd_data(dev, 3,
- 0x09, 0x03, rngmask, 0xff);
- }
- break;
-
- case 2:
- /*
- * two channels
- * commit data to the FIFO
- */
-
- if (CR_RANGE(cmd->chanlist[0]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
-
- /* data */
- usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
-
- /* we have 1 state with duration 1: state 0 */
- steps_tmp = steps - 1;
-
- if (CR_RANGE(cmd->chanlist[1]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
-
- /* do the first part of the delay */
- /* count */
- usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
- 0x00, 0xfe & rngmask, 0x00);
-
- /* and the second part */
- usbduxfast_cmd_data(dev, 2, steps_tmp - steps_tmp / 2,
- 0x00, rngmask, 0x00);
-
- /* data */
- usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
-
- /*
- * we have 2 states with duration 1: step 6 and
- * the IDLE state
- */
- steps_tmp = steps - 2;
-
- if (CR_RANGE(cmd->chanlist[0]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
-
- /* do the first part of the delay */
- /* reset */
- usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
- 0x00, (0xff - 0x02) & rngmask, 0x00);
-
- /* and the second part */
- usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
- 0x00, rngmask, 0x00);
-
- usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
- break;
-
- case 3:
- /*
- * three channels
- */
- for (j = 0; j < 1; j++) {
- int index = j * 2;
-
- if (CR_RANGE(cmd->chanlist[j]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
- /*
- * commit data to the FIFO and do the first part
- * of the delay
- */
- /* data */
- /* no change */
- usbduxfast_cmd_data(dev, index, steps / 2,
- 0x02, rngmask, 0x00);
-
- if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
-
- /* do the second part of the delay */
- /* no data */
- /* count */
- usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
- 0x00, 0xfe & rngmask, 0x00);
- }
-
- /* 2 steps with duration 1: the idele step and step 6: */
- steps_tmp = steps - 2;
-
- /* commit data to the FIFO and do the first part of the delay */
- /* data */
- usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
- 0x02, rngmask, 0x00);
-
- if (CR_RANGE(cmd->chanlist[0]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
-
- /* do the second part of the delay */
- /* no data */
- /* reset */
- usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
- 0x00, (0xff - 0x02) & rngmask, 0x00);
-
- usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
- break;
-
- case 16:
- if (CR_RANGE(cmd->chanlist[0]) > 0)
- rngmask = 0xff - 0x04;
- else
- rngmask = 0xff;
-
- if (cmd->start_src == TRIG_EXT) {
- /*
- * we loop here until ready has been set
- */
-
- /* branch back to state 0 */
- /* deceision state w/o data */
- /* reset */
- /* RDY0 = 0 */
- usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
- (0xff - 0x02) & rngmask, 0x00);
- } else {
- /*
- * we just proceed to state 1
- */
-
- /* 30us reset pulse */
- /* reset */
- usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
- (0xff - 0x02) & rngmask, 0x00);
- }
-
- /* commit data to the FIFO */
- /* data */
- usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
-
- /* we have 2 states with duration 1 */
- steps = steps - 2;
-
- /* do the first part of the delay */
- usbduxfast_cmd_data(dev, 2, steps / 2,
- 0x00, 0xfe & rngmask, 0x00);
-
- /* and the second part */
- usbduxfast_cmd_data(dev, 3, steps - steps / 2,
- 0x00, rngmask, 0x00);
-
- /* branch back to state 1 */
- /* deceision state w/o data */
- /* doesn't matter */
- usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
-
- break;
- }
-
- /* 0 means that the AD commands are sent */
- ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
- if (ret < 0)
- goto cmd_exit;
-
- if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
- /* enable this acquisition operation */
- devpriv->ai_cmd_running = 1;
- ret = usbduxfast_submit_urb(dev);
- if (ret < 0) {
- devpriv->ai_cmd_running = 0;
- /* fixme: unlink here?? */
- goto cmd_exit;
- }
- s->async->inttrig = NULL;
- } else { /* TRIG_INT */
- s->async->inttrig = usbduxfast_ai_inttrig;
- }
-
-cmd_exit:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-/*
- * Mode 0 is used to get a single conversion on demand.
- */
-static int usbduxfast_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxfast_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int range = CR_RANGE(insn->chanspec);
- u8 rngmask = range ? (0xff - 0x04) : 0xff;
- int i, j, n, actual_length;
- int ret;
-
- mutex_lock(&devpriv->mut);
-
- if (devpriv->ai_cmd_running) {
- dev_err(dev->class_dev,
- "ai_insn_read not possible, async cmd is running\n");
- mutex_unlock(&devpriv->mut);
- return -EBUSY;
- }
-
- /* set command for the first channel */
-
- /* commit data to the FIFO */
- /* data */
- usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
-
- /* do the first part of the delay */
- usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
- usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
- usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
- usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
-
- /* second part */
- usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
- usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
-
- ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
- if (ret < 0) {
- mutex_unlock(&devpriv->mut);
- return ret;
- }
-
- for (i = 0; i < PACKETS_TO_IGNORE; i++) {
- ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
- devpriv->inbuf, SIZEINBUF,
- &actual_length, 10000);
- if (ret < 0) {
- dev_err(dev->class_dev, "insn timeout, no data\n");
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- }
-
- for (i = 0; i < insn->n;) {
- ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
- devpriv->inbuf, SIZEINBUF,
- &actual_length, 10000);
- if (ret < 0) {
- dev_err(dev->class_dev, "insn data error: %d\n", ret);
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- n = actual_length / sizeof(u16);
- if ((n % 16) != 0) {
- dev_err(dev->class_dev, "insn data packet corrupted\n");
- mutex_unlock(&devpriv->mut);
- return -EINVAL;
- }
- for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
- data[i] = ((u16 *)(devpriv->inbuf))[j];
- i++;
- }
- }
-
- mutex_unlock(&devpriv->mut);
-
- return insn->n;
-}
-
-static int usbduxfast_upload_firmware(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- u8 *buf;
- unsigned char *tmp;
- int ret;
-
- if (!data)
- return 0;
-
- if (size > FIRMWARE_MAX_LEN) {
- dev_err(dev->class_dev, "firmware binary too large for FX2\n");
- return -ENOMEM;
- }
-
- /* we generate a local buffer for the firmware */
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- /* we need a malloc'ed buffer for usb_control_msg() */
- tmp = kmalloc(1, GFP_KERNEL);
- if (!tmp) {
- kfree(buf);
- return -ENOMEM;
- }
-
- /* stop the current firmware on the device */
- *tmp = 1; /* 7f92 to one */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUXFASTSUB_FIRMWARE,
- VENDOR_DIR_OUT,
- USBDUXFASTSUB_CPUCS, 0x0000,
- tmp, 1,
- EZTIMEOUT);
- if (ret < 0) {
- dev_err(dev->class_dev, "can not stop firmware\n");
- goto done;
- }
-
- /* upload the new firmware to the device */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUXFASTSUB_FIRMWARE,
- VENDOR_DIR_OUT,
- 0, 0x0000,
- buf, size,
- EZTIMEOUT);
- if (ret < 0) {
- dev_err(dev->class_dev, "firmware upload failed\n");
- goto done;
- }
-
- /* start the new firmware on the device */
- *tmp = 0; /* 7f92 to zero */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUXFASTSUB_FIRMWARE,
- VENDOR_DIR_OUT,
- USBDUXFASTSUB_CPUCS, 0x0000,
- tmp, 1,
- EZTIMEOUT);
- if (ret < 0)
- dev_err(dev->class_dev, "can not start firmware\n");
-
-done:
- kfree(tmp);
- kfree(buf);
- return ret;
-}
-
-static int usbduxfast_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxfast_private *devpriv;
- struct comedi_subdevice *s;
- int ret;
-
- if (usb->speed != USB_SPEED_HIGH) {
- dev_err(dev->class_dev,
- "This driver needs USB 2.0 to operate. Aborting...\n");
- return -ENODEV;
- }
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- mutex_init(&devpriv->mut);
- usb_set_intfdata(intf, devpriv);
-
- devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
- if (!devpriv->duxbuf)
- return -ENOMEM;
-
- ret = usb_set_interface(usb,
- intf->altsetting->desc.bInterfaceNumber, 1);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "could not switch to alternate setting 1\n");
- return -ENODEV;
- }
-
- devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!devpriv->urb)
- return -ENOMEM;
-
- devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
- if (!devpriv->inbuf)
- return -ENOMEM;
-
- ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
- usbduxfast_upload_firmware, 0);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, 1);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
- s->n_chan = 16;
- s->maxdata = 0x1000; /* 12-bit + 1 overflow bit */
- s->range_table = &range_usbduxfast_ai_range;
- s->insn_read = usbduxfast_ai_insn_read;
- s->len_chanlist = s->n_chan;
- s->do_cmdtest = usbduxfast_ai_cmdtest;
- s->do_cmd = usbduxfast_ai_cmd;
- s->cancel = usbduxfast_ai_cancel;
-
- return 0;
-}
-
-static void usbduxfast_detach(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usbduxfast_private *devpriv = dev->private;
-
- if (!devpriv)
- return;
-
- mutex_lock(&devpriv->mut);
-
- usb_set_intfdata(intf, NULL);
-
- if (devpriv->urb) {
- /* waits until a running transfer is over */
- usb_kill_urb(devpriv->urb);
-
- kfree(devpriv->inbuf);
- usb_free_urb(devpriv->urb);
- }
-
- kfree(devpriv->duxbuf);
-
- mutex_unlock(&devpriv->mut);
-
- mutex_destroy(&devpriv->mut);
-}
-
-static struct comedi_driver usbduxfast_driver = {
- .driver_name = "usbduxfast",
- .module = THIS_MODULE,
- .auto_attach = usbduxfast_auto_attach,
- .detach = usbduxfast_detach,
-};
-
-static int usbduxfast_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
-}
-
-static const struct usb_device_id usbduxfast_usb_table[] = {
- /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
- { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
- { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
- { }
-};
-MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
-
-static struct usb_driver usbduxfast_usb_driver = {
- .name = "usbduxfast",
- .probe = usbduxfast_usb_probe,
- .disconnect = comedi_usb_auto_unconfig,
- .id_table = usbduxfast_usb_table,
-};
-module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
-
-MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com");
-MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(FIRMWARE);
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
deleted file mode 100644
index 54d7605e909f..000000000000
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ /dev/null
@@ -1,1616 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * usbduxsigma.c
- * Copyright (C) 2011-2015 Bernd Porr, mail@berndporr.me.uk
- */
-
-/*
- * Driver: usbduxsigma
- * Description: University of Stirling USB DAQ & INCITE Technology Limited
- * Devices: [ITL] USB-DUX-SIGMA (usbduxsigma)
- * Author: Bernd Porr <mail@berndporr.me.uk>
- * Updated: 20 July 2015
- * Status: stable
- */
-
-/*
- * I must give credit here to Chris Baugher who
- * wrote the driver for AT-MIO-16d. I used some parts of this
- * driver. I also must give credits to David Brownell
- * who supported me with the USB development.
- *
- * Note: the raw data from the A/D converter is 24 bit big endian
- * anything else is little endian to/from the dux board
- *
- *
- * Revision history:
- * 0.1: initial version
- * 0.2: all basic functions implemented, digital I/O only for one port
- * 0.3: proper vendor ID and driver name
- * 0.4: fixed D/A voltage range
- * 0.5: various bug fixes, health check at startup
- * 0.6: corrected wrong input range
- * 0.7: rewrite code that urb->interval is always 1
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/fcntl.h>
-#include <linux/compiler.h>
-#include <asm/unaligned.h>
-
-#include "../comedi_usb.h"
-
-/* timeout for the USB-transfer in ms*/
-#define BULK_TIMEOUT 1000
-
-/* constants for "firmware" upload and download */
-#define FIRMWARE "usbduxsigma_firmware.bin"
-#define FIRMWARE_MAX_LEN 0x4000
-#define USBDUXSUB_FIRMWARE 0xa0
-#define VENDOR_DIR_IN 0xc0
-#define VENDOR_DIR_OUT 0x40
-
-/* internal addresses of the 8051 processor */
-#define USBDUXSUB_CPUCS 0xE600
-
-/* 300Hz max frequ under PWM */
-#define MIN_PWM_PERIOD ((long)(1E9 / 300))
-
-/* Default PWM frequency */
-#define PWM_DEFAULT_PERIOD ((long)(1E9 / 100))
-
-/* Number of channels (16 AD and offset)*/
-#define NUMCHANNELS 16
-
-/* Size of one A/D value */
-#define SIZEADIN ((sizeof(u32)))
-
-/*
- * Size of the async input-buffer IN BYTES, the DIO state is transmitted
- * as the first byte.
- */
-#define SIZEINBUF (((NUMCHANNELS + 1) * SIZEADIN))
-
-/* 16 bytes. */
-#define SIZEINSNBUF 16
-
-/* Number of DA channels */
-#define NUMOUTCHANNELS 8
-
-/* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT ((sizeof(u8) + sizeof(uint16_t)))
-
-/*
- * Size of the output-buffer in bytes
- * Actually only the first 4 triplets are used but for the
- * high speed mode we need to pad it to 8 (microframes).
- */
-#define SIZEOUTBUF ((8 * SIZEDAOUT))
-
-/*
- * Size of the buffer for the dux commands: just now max size is determined
- * by the analogue out + command byte + panic bytes...
- */
-#define SIZEOFDUXBUFFER ((8 * SIZEDAOUT + 2))
-
-/* Number of in-URBs which receive the data: min=2 */
-#define NUMOFINBUFFERSFULL 5
-
-/* Number of out-URBs which send the data: min=2 */
-#define NUMOFOUTBUFFERSFULL 5
-
-/* Number of in-URBs which receive the data: min=5 */
-/* must have more buffers due to buggy USB ctr */
-#define NUMOFINBUFFERSHIGH 10
-
-/* Number of out-URBs which send the data: min=5 */
-/* must have more buffers due to buggy USB ctr */
-#define NUMOFOUTBUFFERSHIGH 10
-
-/* number of retries to get the right dux command */
-#define RETRIES 10
-
-/* bulk transfer commands to usbduxsigma */
-#define USBBUXSIGMA_AD_CMD 9
-#define USBDUXSIGMA_DA_CMD 1
-#define USBDUXSIGMA_DIO_CFG_CMD 2
-#define USBDUXSIGMA_DIO_BITS_CMD 3
-#define USBDUXSIGMA_SINGLE_AD_CMD 4
-#define USBDUXSIGMA_PWM_ON_CMD 7
-#define USBDUXSIGMA_PWM_OFF_CMD 8
-
-static const struct comedi_lrange usbduxsigma_ai_range = {
- 1, {
- BIP_RANGE(2.5 * 0x800000 / 0x780000 / 2.0)
- }
-};
-
-struct usbduxsigma_private {
- /* actual number of in-buffers */
- int n_ai_urbs;
- /* actual number of out-buffers */
- int n_ao_urbs;
- /* ISO-transfer handling: buffers */
- struct urb **ai_urbs;
- struct urb **ao_urbs;
- /* pwm-transfer handling */
- struct urb *pwm_urb;
- /* PWM period */
- unsigned int pwm_period;
- /* PWM internal delay for the GPIF in the FX2 */
- u8 pwm_delay;
- /* size of the PWM buffer which holds the bit pattern */
- int pwm_buf_sz;
- /* input buffer for the ISO-transfer */
- __be32 *in_buf;
- /* input buffer for single insn */
- u8 *insn_buf;
-
- unsigned high_speed:1;
- unsigned ai_cmd_running:1;
- unsigned ao_cmd_running:1;
- unsigned pwm_cmd_running:1;
-
- /* time between samples in units of the timer */
- unsigned int ai_timer;
- unsigned int ao_timer;
- /* counter between acquisitions */
- unsigned int ai_counter;
- unsigned int ao_counter;
- /* interval in frames/uframes */
- unsigned int ai_interval;
- /* commands */
- u8 *dux_commands;
- struct mutex mut;
-};
-
-static void usbduxsigma_unlink_urbs(struct urb **urbs, int num_urbs)
-{
- int i;
-
- for (i = 0; i < num_urbs; i++)
- usb_kill_urb(urbs[i]);
-}
-
-static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
-{
- struct usbduxsigma_private *devpriv = dev->private;
-
- if (do_unlink && devpriv->ai_urbs)
- usbduxsigma_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);
-
- devpriv->ai_cmd_running = 0;
-}
-
-static int usbduxsigma_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxsigma_private *devpriv = dev->private;
-
- mutex_lock(&devpriv->mut);
- /* unlink only if it is really running */
- usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
- mutex_unlock(&devpriv->mut);
-
- return 0;
-}
-
-static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct urb *urb)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u32 val;
- int ret;
- int i;
-
- if ((urb->actual_length > 0) && (urb->status != -EXDEV)) {
- devpriv->ai_counter--;
- if (devpriv->ai_counter == 0) {
- devpriv->ai_counter = devpriv->ai_timer;
-
- /*
- * Get the data from the USB bus and hand it over
- * to comedi. Note, first byte is the DIO state.
- */
- for (i = 0; i < cmd->chanlist_len; i++) {
- val = be32_to_cpu(devpriv->in_buf[i + 1]);
- val &= 0x00ffffff; /* strip status byte */
- val = comedi_offset_munge(s, val);
- if (!comedi_buf_write_samples(s, &val, 1))
- return;
- }
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg)
- async->events |= COMEDI_CB_EOA;
- }
- }
-
- /* if command is still running, resubmit urb */
- if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
- urb->dev = comedi_to_usb_dev(dev);
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(dev->class_dev, "urb resubmit failed (%d)\n",
- ret);
- if (ret == -EL2NSYNC)
- dev_err(dev->class_dev,
- "buggy USB host controller or bug in IRQ handler\n");
- async->events |= COMEDI_CB_ERROR;
- }
- }
-}
-
-static void usbduxsigma_ai_urb_complete(struct urb *urb)
-{
- struct comedi_device *dev = urb->context;
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async = s->async;
-
- /* exit if not running a command, do not resubmit urb */
- if (!devpriv->ai_cmd_running)
- return;
-
- switch (urb->status) {
- case 0:
- /* copy the result in the transfer buffer */
- memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
- usbduxsigma_ai_handle_urb(dev, s, urb);
- break;
-
- case -EILSEQ:
- /*
- * error in the ISOchronous data
- * we don't copy the data into the transfer buffer
- * and recycle the last data byte
- */
- dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
- usbduxsigma_ai_handle_urb(dev, s, urb);
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- case -ECONNABORTED:
- /* happens after an unlink command */
- async->events |= COMEDI_CB_ERROR;
- break;
-
- default:
- /* a real error */
- dev_err(dev->class_dev, "non-zero urb status (%d)\n",
- urb->status);
- async->events |= COMEDI_CB_ERROR;
- break;
- }
-
- /*
- * comedi_handle_events() cannot be used in this driver. The (*cancel)
- * operation would unlink the urb.
- */
- if (async->events & COMEDI_CB_CANCEL_MASK)
- usbduxsigma_ai_stop(dev, 0);
-
- comedi_event(dev, s);
-}
-
-static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink)
-{
- struct usbduxsigma_private *devpriv = dev->private;
-
- if (do_unlink && devpriv->ao_urbs)
- usbduxsigma_unlink_urbs(devpriv->ao_urbs, devpriv->n_ao_urbs);
-
- devpriv->ao_cmd_running = 0;
-}
-
-static int usbduxsigma_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxsigma_private *devpriv = dev->private;
-
- mutex_lock(&devpriv->mut);
- /* unlink only if it is really running */
- usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running);
- mutex_unlock(&devpriv->mut);
-
- return 0;
-}
-
-static void usbduxsigma_ao_handle_urb(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct urb *urb)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- u8 *datap;
- int ret;
- int i;
-
- devpriv->ao_counter--;
- if (devpriv->ao_counter == 0) {
- devpriv->ao_counter = devpriv->ao_timer;
-
- if (cmd->stop_src == TRIG_COUNT &&
- async->scans_done >= cmd->stop_arg) {
- async->events |= COMEDI_CB_EOA;
- return;
- }
-
- /* transmit data to the USB bus */
- datap = urb->transfer_buffer;
- *datap++ = cmd->chanlist_len;
- for (i = 0; i < cmd->chanlist_len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
- unsigned short val;
-
- if (!comedi_buf_read_samples(s, &val, 1)) {
- dev_err(dev->class_dev, "buffer underflow\n");
- async->events |= COMEDI_CB_OVERFLOW;
- return;
- }
-
- *datap++ = val;
- *datap++ = chan;
- s->readback[chan] = val;
- }
- }
-
- /* if command is still running, resubmit urb */
- if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
- urb->transfer_buffer_length = SIZEOUTBUF;
- urb->dev = comedi_to_usb_dev(dev);
- urb->status = 0;
- urb->interval = 1; /* (u)frames */
- urb->number_of_packets = 1;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEOUTBUF;
- urb->iso_frame_desc[0].status = 0;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(dev->class_dev, "urb resubmit failed (%d)\n",
- ret);
- if (ret == -EL2NSYNC)
- dev_err(dev->class_dev,
- "buggy USB host controller or bug in IRQ handler\n");
- async->events |= COMEDI_CB_ERROR;
- }
- }
-}
-
-static void usbduxsigma_ao_urb_complete(struct urb *urb)
-{
- struct comedi_device *dev = urb->context;
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- struct comedi_async *async = s->async;
-
- /* exit if not running a command, do not resubmit urb */
- if (!devpriv->ao_cmd_running)
- return;
-
- switch (urb->status) {
- case 0:
- usbduxsigma_ao_handle_urb(dev, s, urb);
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- case -ECONNABORTED:
- /* happens after an unlink command */
- async->events |= COMEDI_CB_ERROR;
- break;
-
- default:
- /* a real error */
- dev_err(dev->class_dev, "non-zero urb status (%d)\n",
- urb->status);
- async->events |= COMEDI_CB_ERROR;
- break;
- }
-
- /*
- * comedi_handle_events() cannot be used in this driver. The (*cancel)
- * operation would unlink the urb.
- */
- if (async->events & COMEDI_CB_CANCEL_MASK)
- usbduxsigma_ao_stop(dev, 0);
-
- comedi_event(dev, s);
-}
-
-static int usbduxsigma_submit_urbs(struct comedi_device *dev,
- struct urb **urbs, int num_urbs,
- int input_urb)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct urb *urb;
- int ret;
- int i;
-
- /* Submit all URBs and start the transfer on the bus */
- for (i = 0; i < num_urbs; i++) {
- urb = urbs[i];
-
- /* in case of a resubmission after an unlink... */
- if (input_urb)
- urb->interval = 1;
- urb->context = dev;
- urb->dev = usb;
- urb->status = 0;
- urb->transfer_flags = URB_ISO_ASAP;
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-static int usbduxsigma_chans_to_interval(int num_chan)
-{
- if (num_chan <= 2)
- return 2; /* 4kHz */
- if (num_chan <= 8)
- return 4; /* 2kHz */
- return 8; /* 1kHz */
-}
-
-static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- int high_speed = devpriv->high_speed;
- int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len);
- unsigned int tmp;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- if (high_speed) {
- /*
- * In high speed mode microframes are possible.
- * However, during one microframe we can roughly
- * sample two channels. Thus, the more channels
- * are in the channel list the more time we need.
- */
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- (125000 * interval));
- } else {
- /* full speed */
- /* 1kHz scans every USB frame */
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
- 1000000);
- }
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- tmp = rounddown(cmd->scan_begin_arg, high_speed ? 125000 : 1000000);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
-
- if (err)
- return 4;
-
- return 0;
-}
-
-/*
- * creates the ADC command for the MAX1271
- * range is the range value from comedi
- */
-static void create_adc_command(unsigned int chan,
- u8 *muxsg0, u8 *muxsg1)
-{
- if (chan < 8)
- (*muxsg0) = (*muxsg0) | (1 << chan);
- else if (chan < 16)
- (*muxsg1) = (*muxsg1) | (1 << (chan - 8));
-}
-
-static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxsigma_private *devpriv = dev->private;
- int nsent;
-
- devpriv->dux_commands[0] = cmd_type;
-
- return usb_bulk_msg(usb, usb_sndbulkpipe(usb, 1),
- devpriv->dux_commands, SIZEOFDUXBUFFER,
- &nsent, BULK_TIMEOUT);
-}
-
-static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxsigma_private *devpriv = dev->private;
- int nrec;
- int ret;
- int i;
-
- for (i = 0; i < RETRIES; i++) {
- ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, 8),
- devpriv->insn_buf, SIZEINSNBUF,
- &nrec, BULK_TIMEOUT);
- if (ret < 0)
- return ret;
-
- if (devpriv->insn_buf[0] == command)
- return 0;
- }
- /*
- * This is only reached if the data has been requested a
- * couple of times and the command was not received.
- */
- return -EFAULT;
-}
-
-static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- mutex_lock(&devpriv->mut);
- if (!devpriv->ai_cmd_running) {
- devpriv->ai_cmd_running = 1;
- ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
- devpriv->n_ai_urbs, 1);
- if (ret < 0) {
- devpriv->ai_cmd_running = 0;
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- s->async->inttrig = NULL;
- }
- mutex_unlock(&devpriv->mut);
-
- return 1;
-}
-
-static int usbduxsigma_ai_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int len = cmd->chanlist_len;
- u8 muxsg0 = 0;
- u8 muxsg1 = 0;
- u8 sysred = 0;
- int ret;
- int i;
-
- mutex_lock(&devpriv->mut);
-
- if (devpriv->high_speed) {
- /*
- * every 2 channels get a time window of 125us. Thus, if we
- * sample all 16 channels we need 1ms. If we sample only one
- * channel we need only 125us
- */
- unsigned int interval = usbduxsigma_chans_to_interval(len);
-
- devpriv->ai_interval = interval;
- devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
- } else {
- /* interval always 1ms */
- devpriv->ai_interval = 1;
- devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
- }
-
- for (i = 0; i < len; i++) {
- unsigned int chan = CR_CHAN(cmd->chanlist[i]);
-
- create_adc_command(chan, &muxsg0, &muxsg1);
- }
-
- devpriv->dux_commands[1] = devpriv->ai_interval;
- devpriv->dux_commands[2] = len; /* num channels per time step */
- devpriv->dux_commands[3] = 0x12; /* CONFIG0 */
- devpriv->dux_commands[4] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
- devpriv->dux_commands[5] = 0x00; /* CONFIG3: diff. channels off */
- devpriv->dux_commands[6] = muxsg0;
- devpriv->dux_commands[7] = muxsg1;
- devpriv->dux_commands[8] = sysred;
-
- ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
- if (ret < 0) {
- mutex_unlock(&devpriv->mut);
- return ret;
- }
-
- devpriv->ai_counter = devpriv->ai_timer;
-
- if (cmd->start_src == TRIG_NOW) {
- /* enable this acquisition operation */
- devpriv->ai_cmd_running = 1;
- ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
- devpriv->n_ai_urbs, 1);
- if (ret < 0) {
- devpriv->ai_cmd_running = 0;
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- s->async->inttrig = NULL;
- } else { /* TRIG_INT */
- s->async->inttrig = usbduxsigma_ai_inttrig;
- }
-
- mutex_unlock(&devpriv->mut);
-
- return 0;
-}
-
-static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- u8 muxsg0 = 0;
- u8 muxsg1 = 0;
- u8 sysred = 0;
- int ret;
- int i;
-
- mutex_lock(&devpriv->mut);
- if (devpriv->ai_cmd_running) {
- mutex_unlock(&devpriv->mut);
- return -EBUSY;
- }
-
- create_adc_command(chan, &muxsg0, &muxsg1);
-
- /* Mode 0 is used to get a single conversion on demand */
- devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
- devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
- devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
- devpriv->dux_commands[4] = muxsg0;
- devpriv->dux_commands[5] = muxsg1;
- devpriv->dux_commands[6] = sysred;
-
- /* adc commands */
- ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
- if (ret < 0) {
- mutex_unlock(&devpriv->mut);
- return ret;
- }
-
- for (i = 0; i < insn->n; i++) {
- u32 val;
-
- ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
- if (ret < 0) {
- mutex_unlock(&devpriv->mut);
- return ret;
- }
-
- /* 32 bits big endian from the A/D converter */
- val = be32_to_cpu(get_unaligned((__be32
- *)(devpriv->insn_buf + 1)));
- val &= 0x00ffffff; /* strip status byte */
- data[i] = comedi_offset_munge(s, val);
- }
- mutex_unlock(&devpriv->mut);
-
- return insn->n;
-}
-
-static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- int ret;
-
- mutex_lock(&devpriv->mut);
- ret = comedi_readback_insn_read(dev, s, insn, data);
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int ret;
- int i;
-
- mutex_lock(&devpriv->mut);
- if (devpriv->ao_cmd_running) {
- mutex_unlock(&devpriv->mut);
- return -EBUSY;
- }
-
- for (i = 0; i < insn->n; i++) {
- devpriv->dux_commands[1] = 1; /* num channels */
- devpriv->dux_commands[2] = data[i]; /* value */
- devpriv->dux_commands[3] = chan; /* channel number */
- ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
- if (ret < 0) {
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- s->readback[chan] = data[i];
- }
- mutex_unlock(&devpriv->mut);
-
- return insn->n;
-}
-
-static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- mutex_lock(&devpriv->mut);
- if (!devpriv->ao_cmd_running) {
- devpriv->ao_cmd_running = 1;
- ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
- devpriv->n_ao_urbs, 0);
- if (ret < 0) {
- devpriv->ao_cmd_running = 0;
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- s->async->inttrig = NULL;
- }
- mutex_unlock(&devpriv->mut);
-
- return 1;
-}
-
-static int usbduxsigma_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- unsigned int tmp;
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
-
- /*
- * For now, always use "scan" timing with all channels updated at once
- * (cmd->scan_begin_src == TRIG_TIMER, cmd->convert_src == TRIG_NOW).
- *
- * In a future version, "convert" timing with channels updated
- * indivually may be supported in high speed mode
- * (cmd->scan_begin_src == TRIG_FOLLOW, cmd->convert_src == TRIG_TIMER).
- */
- err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
- err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err) {
- mutex_unlock(&devpriv->mut);
- return 1;
- }
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= comedi_check_trigger_is_unique(cmd->start_src);
- err |= comedi_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
-
- err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 1000000);
-
- err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
- cmd->chanlist_len);
-
- if (cmd->stop_src == TRIG_COUNT)
- err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
- else /* TRIG_NONE */
- err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* Step 4: fix up any arguments */
-
- tmp = rounddown(cmd->scan_begin_arg, 1000000);
- err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
-
- if (err)
- return 4;
-
- return 0;
-}
-
-static int usbduxsigma_ao_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int ret;
-
- mutex_lock(&devpriv->mut);
-
- /*
- * For now, only "scan" timing is supported. A future version may
- * support "convert" timing in high speed mode.
- *
- * Timing of the scan: every 1ms all channels updated at once.
- */
- devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
-
- devpriv->ao_counter = devpriv->ao_timer;
-
- if (cmd->start_src == TRIG_NOW) {
- /* enable this acquisition operation */
- devpriv->ao_cmd_running = 1;
- ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
- devpriv->n_ao_urbs, 0);
- if (ret < 0) {
- devpriv->ao_cmd_running = 0;
- mutex_unlock(&devpriv->mut);
- return ret;
- }
- s->async->inttrig = NULL;
- } else { /* TRIG_INT */
- s->async->inttrig = usbduxsigma_ao_inttrig;
- }
-
- mutex_unlock(&devpriv->mut);
-
- return 0;
-}
-
-static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret;
-
- ret = comedi_dio_insn_config(dev, s, insn, data, 0);
- if (ret)
- return ret;
-
- /*
- * We don't tell the firmware here as it would take 8 frames
- * to submit the information. We do it in the (*insn_bits).
- */
- return insn->n;
-}
-
-static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- int ret;
-
- mutex_lock(&devpriv->mut);
-
- comedi_dio_update_state(s, data);
-
- /* Always update the hardware. See the (*insn_config). */
- devpriv->dux_commands[1] = s->io_bits & 0xff;
- devpriv->dux_commands[4] = s->state & 0xff;
- devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
- devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
- devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
- devpriv->dux_commands[6] = (s->state >> 16) & 0xff;
-
- ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
- if (ret < 0)
- goto done;
- ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
- if (ret < 0)
- goto done;
-
- s->state = devpriv->insn_buf[1] |
- (devpriv->insn_buf[2] << 8) |
- (devpriv->insn_buf[3] << 16);
-
- data[1] = s->state;
- ret = insn->n;
-
-done:
- mutex_unlock(&devpriv->mut);
-
- return ret;
-}
-
-static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink)
-{
- struct usbduxsigma_private *devpriv = dev->private;
-
- if (do_unlink) {
- if (devpriv->pwm_urb)
- usb_kill_urb(devpriv->pwm_urb);
- }
-
- devpriv->pwm_cmd_running = 0;
-}
-
-static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxsigma_private *devpriv = dev->private;
-
- /* unlink only if it is really running */
- usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);
-
- return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
-}
-
-static void usbduxsigma_pwm_urb_complete(struct urb *urb)
-{
- struct comedi_device *dev = urb->context;
- struct usbduxsigma_private *devpriv = dev->private;
- int ret;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- case -ECONNABORTED:
- /* happens after an unlink command */
- if (devpriv->pwm_cmd_running)
- usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
- return;
-
- default:
- /* a real error */
- if (devpriv->pwm_cmd_running) {
- dev_err(dev->class_dev, "non-zero urb status (%d)\n",
- urb->status);
- usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
- }
- return;
- }
-
- if (!devpriv->pwm_cmd_running)
- return;
-
- urb->transfer_buffer_length = devpriv->pwm_buf_sz;
- urb->dev = comedi_to_usb_dev(dev);
- urb->status = 0;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0) {
- dev_err(dev->class_dev, "urb resubmit failed (%d)\n", ret);
- if (ret == -EL2NSYNC)
- dev_err(dev->class_dev,
- "buggy USB host controller or bug in IRQ handler\n");
- usbduxsigma_pwm_stop(dev, 0); /* w/o unlink */
- }
-}
-
-static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxsigma_private *devpriv = dev->private;
- struct urb *urb = devpriv->pwm_urb;
-
- /* in case of a resubmission after an unlink... */
- usb_fill_bulk_urb(urb, usb, usb_sndbulkpipe(usb, 4),
- urb->transfer_buffer, devpriv->pwm_buf_sz,
- usbduxsigma_pwm_urb_complete, dev);
-
- return usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-static int usbduxsigma_pwm_period(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int period)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- int fx2delay;
-
- if (period < MIN_PWM_PERIOD)
- return -EAGAIN;
-
- fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
- if (fx2delay > 255)
- return -EAGAIN;
-
- devpriv->pwm_delay = fx2delay;
- devpriv->pwm_period = period;
- return 0;
-}
-
-static int usbduxsigma_pwm_start(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- int ret;
-
- if (devpriv->pwm_cmd_running)
- return 0;
-
- devpriv->dux_commands[1] = devpriv->pwm_delay;
- ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
- if (ret < 0)
- return ret;
-
- memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
-
- devpriv->pwm_cmd_running = 1;
- ret = usbduxsigma_submit_pwm_urb(dev);
- if (ret < 0) {
- devpriv->pwm_cmd_running = 0;
- return ret;
- }
-
- return 0;
-}
-
-static void usbduxsigma_pwm_pattern(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int chan,
- unsigned int value,
- unsigned int sign)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- char pwm_mask = (1 << chan); /* DIO bit for the PWM data */
- char sgn_mask = (16 << chan); /* DIO bit for the sign */
- char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
- int szbuf = devpriv->pwm_buf_sz;
- int i;
-
- for (i = 0; i < szbuf; i++) {
- char c = *buf;
-
- c &= ~pwm_mask;
- if (i < value)
- c |= pwm_mask;
- if (!sign)
- c &= ~sgn_mask;
- else
- c |= sgn_mask;
- *buf++ = c;
- }
-}
-
-static int usbduxsigma_pwm_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- /*
- * It doesn't make sense to support more than one value here
- * because it would just overwrite the PWM buffer.
- */
- if (insn->n != 1)
- return -EINVAL;
-
- /*
- * The sign is set via a special INSN only, this gives us 8 bits
- * for normal operation, sign is 0 by default.
- */
- usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0);
-
- return insn->n;
-}
-
-static int usbduxsigma_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
-
- switch (data[0]) {
- case INSN_CONFIG_ARM:
- /*
- * if not zero the PWM is limited to a certain time which is
- * not supported here
- */
- if (data[1] != 0)
- return -EINVAL;
- return usbduxsigma_pwm_start(dev, s);
- case INSN_CONFIG_DISARM:
- return usbduxsigma_pwm_cancel(dev, s);
- case INSN_CONFIG_GET_PWM_STATUS:
- data[1] = devpriv->pwm_cmd_running;
- return 0;
- case INSN_CONFIG_PWM_SET_PERIOD:
- return usbduxsigma_pwm_period(dev, s, data[1]);
- case INSN_CONFIG_PWM_GET_PERIOD:
- data[1] = devpriv->pwm_period;
- return 0;
- case INSN_CONFIG_PWM_SET_H_BRIDGE:
- /*
- * data[1] = value
- * data[2] = sign (for a relay)
- */
- usbduxsigma_pwm_pattern(dev, s, chan, data[1], (data[2] != 0));
- return 0;
- case INSN_CONFIG_PWM_GET_H_BRIDGE:
- /* values are not kept in this driver, nothing to return */
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
-{
- struct comedi_subdevice *s = dev->read_subdev;
- struct usbduxsigma_private *devpriv = dev->private;
- u8 sysred;
- u32 val;
- int ret;
-
- switch (chan) {
- default:
- case 0:
- sysred = 0; /* ADC zero */
- break;
- case 1:
- sysred = 1; /* ADC offset */
- break;
- case 2:
- sysred = 4; /* VCC */
- break;
- case 3:
- sysred = 8; /* temperature */
- break;
- case 4:
- sysred = 16; /* gain */
- break;
- case 5:
- sysred = 32; /* ref */
- break;
- }
-
- devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
- devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
- devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
- devpriv->dux_commands[4] = 0;
- devpriv->dux_commands[5] = 0;
- devpriv->dux_commands[6] = sysred;
- ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
- if (ret < 0)
- return ret;
-
- ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
- if (ret < 0)
- return ret;
-
- /* 32 bits big endian from the A/D converter */
- val = be32_to_cpu(get_unaligned((__be32 *)(devpriv->insn_buf + 1)));
- val &= 0x00ffffff; /* strip status byte */
-
- return (int)comedi_offset_munge(s, val);
-}
-
-static int usbduxsigma_firmware_upload(struct comedi_device *dev,
- const u8 *data, size_t size,
- unsigned long context)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- u8 *buf;
- u8 *tmp;
- int ret;
-
- if (!data)
- return 0;
-
- if (size > FIRMWARE_MAX_LEN) {
- dev_err(dev->class_dev, "firmware binary too large for FX2\n");
- return -ENOMEM;
- }
-
- /* we generate a local buffer for the firmware */
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- /* we need a malloc'ed buffer for usb_control_msg() */
- tmp = kmalloc(1, GFP_KERNEL);
- if (!tmp) {
- kfree(buf);
- return -ENOMEM;
- }
-
- /* stop the current firmware on the device */
- *tmp = 1; /* 7f92 to one */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUXSUB_FIRMWARE,
- VENDOR_DIR_OUT,
- USBDUXSUB_CPUCS, 0x0000,
- tmp, 1,
- BULK_TIMEOUT);
- if (ret < 0) {
- dev_err(dev->class_dev, "can not stop firmware\n");
- goto done;
- }
-
- /* upload the new firmware to the device */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUXSUB_FIRMWARE,
- VENDOR_DIR_OUT,
- 0, 0x0000,
- buf, size,
- BULK_TIMEOUT);
- if (ret < 0) {
- dev_err(dev->class_dev, "firmware upload failed\n");
- goto done;
- }
-
- /* start the new firmware on the device */
- *tmp = 0; /* 7f92 to zero */
- ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
- USBDUXSUB_FIRMWARE,
- VENDOR_DIR_OUT,
- USBDUXSUB_CPUCS, 0x0000,
- tmp, 1,
- BULK_TIMEOUT);
- if (ret < 0)
- dev_err(dev->class_dev, "can not start firmware\n");
-
-done:
- kfree(tmp);
- kfree(buf);
- return ret;
-}
-
-static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
-{
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxsigma_private *devpriv = dev->private;
- struct urb *urb;
- int i;
-
- devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
- devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
- devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
- devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(urb), GFP_KERNEL);
- devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(urb), GFP_KERNEL);
- if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf ||
- !devpriv->ai_urbs || !devpriv->ao_urbs)
- return -ENOMEM;
-
- for (i = 0; i < devpriv->n_ai_urbs; i++) {
- /* one frame: 1ms */
- urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- devpriv->ai_urbs[i] = urb;
- urb->dev = usb;
- /* will be filled later with a pointer to the comedi-device */
- /* and ONLY then the urb should be submitted */
- urb->context = NULL;
- urb->pipe = usb_rcvisocpipe(usb, 6);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
- if (!urb->transfer_buffer)
- return -ENOMEM;
- urb->complete = usbduxsigma_ai_urb_complete;
- urb->number_of_packets = 1;
- urb->transfer_buffer_length = SIZEINBUF;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEINBUF;
- }
-
- for (i = 0; i < devpriv->n_ao_urbs; i++) {
- /* one frame: 1ms */
- urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- devpriv->ao_urbs[i] = urb;
- urb->dev = usb;
- /* will be filled later with a pointer to the comedi-device */
- /* and ONLY then the urb should be submitted */
- urb->context = NULL;
- urb->pipe = usb_sndisocpipe(usb, 2);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
- if (!urb->transfer_buffer)
- return -ENOMEM;
- urb->complete = usbduxsigma_ao_urb_complete;
- urb->number_of_packets = 1;
- urb->transfer_buffer_length = SIZEOUTBUF;
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = SIZEOUTBUF;
- urb->interval = 1; /* (u)frames */
- }
-
- if (devpriv->pwm_buf_sz) {
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- devpriv->pwm_urb = urb;
-
- urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz,
- GFP_KERNEL);
- if (!urb->transfer_buffer)
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
-{
- struct usbduxsigma_private *devpriv = dev->private;
- struct urb *urb;
- int i;
-
- urb = devpriv->pwm_urb;
- if (urb) {
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- if (devpriv->ao_urbs) {
- for (i = 0; i < devpriv->n_ao_urbs; i++) {
- urb = devpriv->ao_urbs[i];
- if (urb) {
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- }
- kfree(devpriv->ao_urbs);
- }
- if (devpriv->ai_urbs) {
- for (i = 0; i < devpriv->n_ai_urbs; i++) {
- urb = devpriv->ai_urbs[i];
- if (urb) {
- kfree(urb->transfer_buffer);
- usb_free_urb(urb);
- }
- }
- kfree(devpriv->ai_urbs);
- }
- kfree(devpriv->insn_buf);
- kfree(devpriv->in_buf);
- kfree(devpriv->dux_commands);
-}
-
-static int usbduxsigma_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usbduxsigma_private *devpriv;
- struct comedi_subdevice *s;
- int offset;
- int ret;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- mutex_init(&devpriv->mut);
-
- usb_set_intfdata(intf, devpriv);
-
- devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
- if (devpriv->high_speed) {
- devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
- devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
- devpriv->pwm_buf_sz = 512;
- } else {
- devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
- devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
- }
-
- ret = usbduxsigma_alloc_usb_buffers(dev);
- if (ret)
- return ret;
-
- /* setting to alternate setting 3: enabling iso ep and bulk ep. */
- ret = usb_set_interface(usb, intf->altsetting->desc.bInterfaceNumber,
- 3);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "could not set alternate setting 3 in high speed\n");
- return ret;
- }
-
- ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
- usbduxsigma_firmware_upload, 0);
- if (ret)
- return ret;
-
- ret = comedi_alloc_subdevices(dev, (devpriv->high_speed) ? 4 : 3);
- if (ret)
- return ret;
-
- /* Analog Input subdevice */
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL;
- s->n_chan = NUMCHANNELS;
- s->len_chanlist = NUMCHANNELS;
- s->maxdata = 0x00ffffff;
- s->range_table = &usbduxsigma_ai_range;
- s->insn_read = usbduxsigma_ai_insn_read;
- s->do_cmdtest = usbduxsigma_ai_cmdtest;
- s->do_cmd = usbduxsigma_ai_cmd;
- s->cancel = usbduxsigma_ai_cancel;
-
- /* Analog Output subdevice */
- s = &dev->subdevices[1];
- dev->write_subdev = s;
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
- s->n_chan = 4;
- s->len_chanlist = s->n_chan;
- s->maxdata = 0x00ff;
- s->range_table = &range_unipolar2_5;
- s->insn_write = usbduxsigma_ao_insn_write;
- s->insn_read = usbduxsigma_ao_insn_read;
- s->do_cmdtest = usbduxsigma_ao_cmdtest;
- s->do_cmd = usbduxsigma_ao_cmd;
- s->cancel = usbduxsigma_ao_cancel;
-
- ret = comedi_alloc_subdev_readback(s);
- if (ret)
- return ret;
-
- /* Digital I/O subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = usbduxsigma_dio_insn_bits;
- s->insn_config = usbduxsigma_dio_insn_config;
-
- if (devpriv->high_speed) {
- /* Timer / pwm subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_PWM;
- s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
- s->n_chan = 8;
- s->maxdata = devpriv->pwm_buf_sz;
- s->insn_write = usbduxsigma_pwm_write;
- s->insn_config = usbduxsigma_pwm_config;
-
- usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
- }
-
- offset = usbduxsigma_getstatusinfo(dev, 0);
- if (offset < 0) {
- dev_err(dev->class_dev,
- "Communication to USBDUXSIGMA failed! Check firmware and cabling.\n");
- return offset;
- }
-
- dev_info(dev->class_dev, "ADC_zero = %x\n", offset);
-
- return 0;
-}
-
-static void usbduxsigma_detach(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usbduxsigma_private *devpriv = dev->private;
-
- usb_set_intfdata(intf, NULL);
-
- if (!devpriv)
- return;
-
- mutex_lock(&devpriv->mut);
-
- /* force unlink all urbs */
- usbduxsigma_ai_stop(dev, 1);
- usbduxsigma_ao_stop(dev, 1);
- usbduxsigma_pwm_stop(dev, 1);
-
- usbduxsigma_free_usb_buffers(dev);
-
- mutex_unlock(&devpriv->mut);
-
- mutex_destroy(&devpriv->mut);
-}
-
-static struct comedi_driver usbduxsigma_driver = {
- .driver_name = "usbduxsigma",
- .module = THIS_MODULE,
- .auto_attach = usbduxsigma_auto_attach,
- .detach = usbduxsigma_detach,
-};
-
-static int usbduxsigma_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);
-}
-
-static const struct usb_device_id usbduxsigma_usb_table[] = {
- { USB_DEVICE(0x13d8, 0x0020) },
- { USB_DEVICE(0x13d8, 0x0021) },
- { USB_DEVICE(0x13d8, 0x0022) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, usbduxsigma_usb_table);
-
-static struct usb_driver usbduxsigma_usb_driver = {
- .name = "usbduxsigma",
- .probe = usbduxsigma_usb_probe,
- .disconnect = comedi_usb_auto_unconfig,
- .id_table = usbduxsigma_usb_table,
-};
-module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
-
-MODULE_AUTHOR("Bernd Porr, mail@berndporr.me.uk");
-MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- mail@berndporr.me.uk");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(FIRMWARE);
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
deleted file mode 100644
index 9f920819cd74..000000000000
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ /dev/null
@@ -1,880 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * vmk80xx.c
- * Velleman USB Board Low-Level Driver
- *
- * Copyright (C) 2009 Manuel Gebele <forensixs@gmx.de>, Germany
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * Driver: vmk80xx
- * Description: Velleman USB Board Low-Level Driver
- * Devices: [Velleman] K8055 (K8055/VM110), K8061 (K8061/VM140),
- * VM110 (K8055/VM110), VM140 (K8061/VM140)
- * Author: Manuel Gebele <forensixs@gmx.de>
- * Updated: Sun, 10 May 2009 11:14:59 +0200
- * Status: works
- *
- * Supports:
- * - analog input
- * - analog output
- * - digital input
- * - digital output
- * - counter
- * - pwm
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/errno.h>
-#include <linux/input.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/uaccess.h>
-
-#include "../comedi_usb.h"
-
-enum {
- DEVICE_VMK8055,
- DEVICE_VMK8061
-};
-
-#define VMK8055_DI_REG 0x00
-#define VMK8055_DO_REG 0x01
-#define VMK8055_AO1_REG 0x02
-#define VMK8055_AO2_REG 0x03
-#define VMK8055_AI1_REG 0x02
-#define VMK8055_AI2_REG 0x03
-#define VMK8055_CNT1_REG 0x04
-#define VMK8055_CNT2_REG 0x06
-
-#define VMK8061_CH_REG 0x01
-#define VMK8061_DI_REG 0x01
-#define VMK8061_DO_REG 0x01
-#define VMK8061_PWM_REG1 0x01
-#define VMK8061_PWM_REG2 0x02
-#define VMK8061_CNT_REG 0x02
-#define VMK8061_AO_REG 0x02
-#define VMK8061_AI_REG1 0x02
-#define VMK8061_AI_REG2 0x03
-
-#define VMK8055_CMD_RST 0x00
-#define VMK8055_CMD_DEB1_TIME 0x01
-#define VMK8055_CMD_DEB2_TIME 0x02
-#define VMK8055_CMD_RST_CNT1 0x03
-#define VMK8055_CMD_RST_CNT2 0x04
-#define VMK8055_CMD_WRT_AD 0x05
-
-#define VMK8061_CMD_RD_AI 0x00
-#define VMK8061_CMR_RD_ALL_AI 0x01 /* !non-active! */
-#define VMK8061_CMD_SET_AO 0x02
-#define VMK8061_CMD_SET_ALL_AO 0x03 /* !non-active! */
-#define VMK8061_CMD_OUT_PWM 0x04
-#define VMK8061_CMD_RD_DI 0x05
-#define VMK8061_CMD_DO 0x06 /* !non-active! */
-#define VMK8061_CMD_CLR_DO 0x07
-#define VMK8061_CMD_SET_DO 0x08
-#define VMK8061_CMD_RD_CNT 0x09 /* TODO: completely pointless? */
-#define VMK8061_CMD_RST_CNT 0x0a /* TODO: completely pointless? */
-#define VMK8061_CMD_RD_VERSION 0x0b /* internal usage */
-#define VMK8061_CMD_RD_JMP_STAT 0x0c /* TODO: not implemented yet */
-#define VMK8061_CMD_RD_PWR_STAT 0x0d /* internal usage */
-#define VMK8061_CMD_RD_DO 0x0e
-#define VMK8061_CMD_RD_AO 0x0f
-#define VMK8061_CMD_RD_PWM 0x10
-
-#define IC3_VERSION BIT(0)
-#define IC6_VERSION BIT(1)
-
-enum vmk80xx_model {
- VMK8055_MODEL,
- VMK8061_MODEL
-};
-
-static const struct comedi_lrange vmk8061_range = {
- 2, {
- UNI_RANGE(5),
- UNI_RANGE(10)
- }
-};
-
-struct vmk80xx_board {
- const char *name;
- enum vmk80xx_model model;
- const struct comedi_lrange *range;
- int ai_nchans;
- unsigned int ai_maxdata;
- int ao_nchans;
- int di_nchans;
- unsigned int cnt_maxdata;
- int pwm_nchans;
- unsigned int pwm_maxdata;
-};
-
-static const struct vmk80xx_board vmk80xx_boardinfo[] = {
- [DEVICE_VMK8055] = {
- .name = "K8055 (VM110)",
- .model = VMK8055_MODEL,
- .range = &range_unipolar5,
- .ai_nchans = 2,
- .ai_maxdata = 0x00ff,
- .ao_nchans = 2,
- .di_nchans = 6,
- .cnt_maxdata = 0xffff,
- },
- [DEVICE_VMK8061] = {
- .name = "K8061 (VM140)",
- .model = VMK8061_MODEL,
- .range = &vmk8061_range,
- .ai_nchans = 8,
- .ai_maxdata = 0x03ff,
- .ao_nchans = 8,
- .di_nchans = 8,
- .cnt_maxdata = 0, /* unknown, device is not writeable */
- .pwm_nchans = 1,
- .pwm_maxdata = 0x03ff,
- },
-};
-
-struct vmk80xx_private {
- struct usb_endpoint_descriptor *ep_rx;
- struct usb_endpoint_descriptor *ep_tx;
- struct semaphore limit_sem;
- unsigned char *usb_rx_buf;
- unsigned char *usb_tx_buf;
- enum vmk80xx_model model;
-};
-
-static void vmk80xx_do_bulk_msg(struct comedi_device *dev)
-{
- struct vmk80xx_private *devpriv = dev->private;
- struct usb_device *usb = comedi_to_usb_dev(dev);
- __u8 tx_addr;
- __u8 rx_addr;
- unsigned int tx_pipe;
- unsigned int rx_pipe;
- size_t size;
-
- tx_addr = devpriv->ep_tx->bEndpointAddress;
- rx_addr = devpriv->ep_rx->bEndpointAddress;
- tx_pipe = usb_sndbulkpipe(usb, tx_addr);
- rx_pipe = usb_rcvbulkpipe(usb, rx_addr);
-
- /*
- * The max packet size attributes of the K8061
- * input/output endpoints are identical
- */
- size = usb_endpoint_maxp(devpriv->ep_tx);
-
- usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf,
- size, NULL, devpriv->ep_tx->bInterval);
- usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10);
-}
-
-static int vmk80xx_read_packet(struct comedi_device *dev)
-{
- struct vmk80xx_private *devpriv = dev->private;
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usb_endpoint_descriptor *ep;
- unsigned int pipe;
-
- if (devpriv->model == VMK8061_MODEL) {
- vmk80xx_do_bulk_msg(dev);
- return 0;
- }
-
- ep = devpriv->ep_rx;
- pipe = usb_rcvintpipe(usb, ep->bEndpointAddress);
- return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf,
- usb_endpoint_maxp(ep), NULL,
- HZ * 10);
-}
-
-static int vmk80xx_write_packet(struct comedi_device *dev, int cmd)
-{
- struct vmk80xx_private *devpriv = dev->private;
- struct usb_device *usb = comedi_to_usb_dev(dev);
- struct usb_endpoint_descriptor *ep;
- unsigned int pipe;
-
- devpriv->usb_tx_buf[0] = cmd;
-
- if (devpriv->model == VMK8061_MODEL) {
- vmk80xx_do_bulk_msg(dev);
- return 0;
- }
-
- ep = devpriv->ep_tx;
- pipe = usb_sndintpipe(usb, ep->bEndpointAddress);
- return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf,
- usb_endpoint_maxp(ep), NULL,
- HZ * 10);
-}
-
-static int vmk80xx_reset_device(struct comedi_device *dev)
-{
- struct vmk80xx_private *devpriv = dev->private;
- size_t size;
- int retval;
-
- size = usb_endpoint_maxp(devpriv->ep_tx);
- memset(devpriv->usb_tx_buf, 0, size);
- retval = vmk80xx_write_packet(dev, VMK8055_CMD_RST);
- if (retval)
- return retval;
- /* set outputs to known state as we cannot read them */
- return vmk80xx_write_packet(dev, VMK8055_CMD_WRT_AD);
-}
-
-static int vmk80xx_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- int chan;
- int reg[2];
- int n;
-
- down(&devpriv->limit_sem);
- chan = CR_CHAN(insn->chanspec);
-
- switch (devpriv->model) {
- case VMK8055_MODEL:
- if (!chan)
- reg[0] = VMK8055_AI1_REG;
- else
- reg[0] = VMK8055_AI2_REG;
- break;
- case VMK8061_MODEL:
- default:
- reg[0] = VMK8061_AI_REG1;
- reg[1] = VMK8061_AI_REG2;
- devpriv->usb_tx_buf[0] = VMK8061_CMD_RD_AI;
- devpriv->usb_tx_buf[VMK8061_CH_REG] = chan;
- break;
- }
-
- for (n = 0; n < insn->n; n++) {
- if (vmk80xx_read_packet(dev))
- break;
-
- if (devpriv->model == VMK8055_MODEL) {
- data[n] = devpriv->usb_rx_buf[reg[0]];
- continue;
- }
-
- /* VMK8061_MODEL */
- data[n] = devpriv->usb_rx_buf[reg[0]] + 256 *
- devpriv->usb_rx_buf[reg[1]];
- }
-
- up(&devpriv->limit_sem);
-
- return n;
-}
-
-static int vmk80xx_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- int chan;
- int cmd;
- int reg;
- int n;
-
- down(&devpriv->limit_sem);
- chan = CR_CHAN(insn->chanspec);
-
- switch (devpriv->model) {
- case VMK8055_MODEL:
- cmd = VMK8055_CMD_WRT_AD;
- if (!chan)
- reg = VMK8055_AO1_REG;
- else
- reg = VMK8055_AO2_REG;
- break;
- default: /* NOTE: avoid compiler warnings */
- cmd = VMK8061_CMD_SET_AO;
- reg = VMK8061_AO_REG;
- devpriv->usb_tx_buf[VMK8061_CH_REG] = chan;
- break;
- }
-
- for (n = 0; n < insn->n; n++) {
- devpriv->usb_tx_buf[reg] = data[n];
-
- if (vmk80xx_write_packet(dev, cmd))
- break;
- }
-
- up(&devpriv->limit_sem);
-
- return n;
-}
-
-static int vmk80xx_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- int chan;
- int reg;
- int n;
-
- down(&devpriv->limit_sem);
- chan = CR_CHAN(insn->chanspec);
-
- reg = VMK8061_AO_REG - 1;
-
- devpriv->usb_tx_buf[0] = VMK8061_CMD_RD_AO;
-
- for (n = 0; n < insn->n; n++) {
- if (vmk80xx_read_packet(dev))
- break;
-
- data[n] = devpriv->usb_rx_buf[reg + chan];
- }
-
- up(&devpriv->limit_sem);
-
- return n;
-}
-
-static int vmk80xx_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- unsigned char *rx_buf;
- int reg;
- int retval;
-
- down(&devpriv->limit_sem);
-
- rx_buf = devpriv->usb_rx_buf;
-
- if (devpriv->model == VMK8061_MODEL) {
- reg = VMK8061_DI_REG;
- devpriv->usb_tx_buf[0] = VMK8061_CMD_RD_DI;
- } else {
- reg = VMK8055_DI_REG;
- }
-
- retval = vmk80xx_read_packet(dev);
-
- if (!retval) {
- if (devpriv->model == VMK8055_MODEL)
- data[1] = (((rx_buf[reg] >> 4) & 0x03) |
- ((rx_buf[reg] << 2) & 0x04) |
- ((rx_buf[reg] >> 3) & 0x18));
- else
- data[1] = rx_buf[reg];
-
- retval = 2;
- }
-
- up(&devpriv->limit_sem);
-
- return retval;
-}
-
-static int vmk80xx_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- unsigned char *rx_buf = devpriv->usb_rx_buf;
- unsigned char *tx_buf = devpriv->usb_tx_buf;
- int reg, cmd;
- int ret = 0;
-
- if (devpriv->model == VMK8061_MODEL) {
- reg = VMK8061_DO_REG;
- cmd = VMK8061_CMD_DO;
- } else { /* VMK8055_MODEL */
- reg = VMK8055_DO_REG;
- cmd = VMK8055_CMD_WRT_AD;
- }
-
- down(&devpriv->limit_sem);
-
- if (comedi_dio_update_state(s, data)) {
- tx_buf[reg] = s->state;
- ret = vmk80xx_write_packet(dev, cmd);
- if (ret)
- goto out;
- }
-
- if (devpriv->model == VMK8061_MODEL) {
- tx_buf[0] = VMK8061_CMD_RD_DO;
- ret = vmk80xx_read_packet(dev);
- if (ret)
- goto out;
- data[1] = rx_buf[reg];
- } else {
- data[1] = s->state;
- }
-
-out:
- up(&devpriv->limit_sem);
-
- return ret ? ret : insn->n;
-}
-
-static int vmk80xx_cnt_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- int chan;
- int reg[2];
- int n;
-
- down(&devpriv->limit_sem);
- chan = CR_CHAN(insn->chanspec);
-
- switch (devpriv->model) {
- case VMK8055_MODEL:
- if (!chan)
- reg[0] = VMK8055_CNT1_REG;
- else
- reg[0] = VMK8055_CNT2_REG;
- break;
- case VMK8061_MODEL:
- default:
- reg[0] = VMK8061_CNT_REG;
- reg[1] = VMK8061_CNT_REG;
- devpriv->usb_tx_buf[0] = VMK8061_CMD_RD_CNT;
- break;
- }
-
- for (n = 0; n < insn->n; n++) {
- if (vmk80xx_read_packet(dev))
- break;
-
- if (devpriv->model == VMK8055_MODEL)
- data[n] = devpriv->usb_rx_buf[reg[0]];
- else /* VMK8061_MODEL */
- data[n] = devpriv->usb_rx_buf[reg[0] * (chan + 1) + 1]
- + 256 * devpriv->usb_rx_buf[reg[1] * 2 + 2];
- }
-
- up(&devpriv->limit_sem);
-
- return n;
-}
-
-static int vmk80xx_cnt_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- int cmd;
- int reg;
- int ret;
-
- down(&devpriv->limit_sem);
- switch (data[0]) {
- case INSN_CONFIG_RESET:
- if (devpriv->model == VMK8055_MODEL) {
- if (!chan) {
- cmd = VMK8055_CMD_RST_CNT1;
- reg = VMK8055_CNT1_REG;
- } else {
- cmd = VMK8055_CMD_RST_CNT2;
- reg = VMK8055_CNT2_REG;
- }
- devpriv->usb_tx_buf[reg] = 0x00;
- } else {
- cmd = VMK8061_CMD_RST_CNT;
- }
- ret = vmk80xx_write_packet(dev, cmd);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- up(&devpriv->limit_sem);
-
- return ret ? ret : insn->n;
-}
-
-static int vmk80xx_cnt_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- unsigned long debtime;
- unsigned long val;
- int chan;
- int cmd;
- int n;
-
- down(&devpriv->limit_sem);
- chan = CR_CHAN(insn->chanspec);
-
- if (!chan)
- cmd = VMK8055_CMD_DEB1_TIME;
- else
- cmd = VMK8055_CMD_DEB2_TIME;
-
- for (n = 0; n < insn->n; n++) {
- debtime = data[n];
- if (debtime == 0)
- debtime = 1;
-
- /* TODO: Prevent overflows */
- if (debtime > 7450)
- debtime = 7450;
-
- val = int_sqrt(debtime * 1000 / 115);
- if (((val + 1) * val) < debtime * 1000 / 115)
- val += 1;
-
- devpriv->usb_tx_buf[6 + chan] = val;
-
- if (vmk80xx_write_packet(dev, cmd))
- break;
- }
-
- up(&devpriv->limit_sem);
-
- return n;
-}
-
-static int vmk80xx_pwm_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- unsigned char *tx_buf;
- unsigned char *rx_buf;
- int reg[2];
- int n;
-
- down(&devpriv->limit_sem);
-
- tx_buf = devpriv->usb_tx_buf;
- rx_buf = devpriv->usb_rx_buf;
-
- reg[0] = VMK8061_PWM_REG1;
- reg[1] = VMK8061_PWM_REG2;
-
- tx_buf[0] = VMK8061_CMD_RD_PWM;
-
- for (n = 0; n < insn->n; n++) {
- if (vmk80xx_read_packet(dev))
- break;
-
- data[n] = rx_buf[reg[0]] + 4 * rx_buf[reg[1]];
- }
-
- up(&devpriv->limit_sem);
-
- return n;
-}
-
-static int vmk80xx_pwm_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct vmk80xx_private *devpriv = dev->private;
- unsigned char *tx_buf;
- int reg[2];
- int cmd;
- int n;
-
- down(&devpriv->limit_sem);
-
- tx_buf = devpriv->usb_tx_buf;
-
- reg[0] = VMK8061_PWM_REG1;
- reg[1] = VMK8061_PWM_REG2;
-
- cmd = VMK8061_CMD_OUT_PWM;
-
- /*
- * The followin piece of code was translated from the inline
- * assembler code in the DLL source code.
- *
- * asm
- * mov eax, k ; k is the value (data[n])
- * and al, 03h ; al are the lower 8 bits of eax
- * mov lo, al ; lo is the low part (tx_buf[reg[0]])
- * mov eax, k
- * shr eax, 2 ; right shift eax register by 2
- * mov hi, al ; hi is the high part (tx_buf[reg[1]])
- * end;
- */
- for (n = 0; n < insn->n; n++) {
- tx_buf[reg[0]] = (unsigned char)(data[n] & 0x03);
- tx_buf[reg[1]] = (unsigned char)(data[n] >> 2) & 0xff;
-
- if (vmk80xx_write_packet(dev, cmd))
- break;
- }
-
- up(&devpriv->limit_sem);
-
- return n;
-}
-
-static int vmk80xx_find_usb_endpoints(struct comedi_device *dev)
-{
- struct vmk80xx_private *devpriv = dev->private;
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct usb_host_interface *iface_desc = intf->cur_altsetting;
- struct usb_endpoint_descriptor *ep_desc;
- int i;
-
- if (iface_desc->desc.bNumEndpoints != 2)
- return -ENODEV;
-
- for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
- ep_desc = &iface_desc->endpoint[i].desc;
-
- if (usb_endpoint_is_int_in(ep_desc) ||
- usb_endpoint_is_bulk_in(ep_desc)) {
- if (!devpriv->ep_rx)
- devpriv->ep_rx = ep_desc;
- continue;
- }
-
- if (usb_endpoint_is_int_out(ep_desc) ||
- usb_endpoint_is_bulk_out(ep_desc)) {
- if (!devpriv->ep_tx)
- devpriv->ep_tx = ep_desc;
- continue;
- }
- }
-
- if (!devpriv->ep_rx || !devpriv->ep_tx)
- return -ENODEV;
-
- if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx))
- return -EINVAL;
-
- return 0;
-}
-
-static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev)
-{
- struct vmk80xx_private *devpriv = dev->private;
- size_t size;
-
- size = usb_endpoint_maxp(devpriv->ep_rx);
- devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL);
- if (!devpriv->usb_rx_buf)
- return -ENOMEM;
-
- size = usb_endpoint_maxp(devpriv->ep_tx);
- devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
- if (!devpriv->usb_tx_buf)
- return -ENOMEM;
-
- return 0;
-}
-
-static int vmk80xx_init_subdevices(struct comedi_device *dev)
-{
- const struct vmk80xx_board *board = dev->board_ptr;
- struct vmk80xx_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- int n_subd;
- int ret;
-
- down(&devpriv->limit_sem);
-
- if (devpriv->model == VMK8055_MODEL)
- n_subd = 5;
- else
- n_subd = 6;
- ret = comedi_alloc_subdevices(dev, n_subd);
- if (ret) {
- up(&devpriv->limit_sem);
- return ret;
- }
-
- /* Analog input subdevice */
- s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = board->ai_nchans;
- s->maxdata = board->ai_maxdata;
- s->range_table = board->range;
- s->insn_read = vmk80xx_ai_insn_read;
-
- /* Analog output subdevice */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
- s->n_chan = board->ao_nchans;
- s->maxdata = 0x00ff;
- s->range_table = board->range;
- s->insn_write = vmk80xx_ao_insn_write;
- if (devpriv->model == VMK8061_MODEL) {
- s->subdev_flags |= SDF_READABLE;
- s->insn_read = vmk80xx_ao_insn_read;
- }
-
- /* Digital input subdevice */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = board->di_nchans;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = vmk80xx_di_insn_bits;
-
- /* Digital output subdevice */
- s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = vmk80xx_do_insn_bits;
-
- /* Counter subdevice */
- s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 2;
- s->maxdata = board->cnt_maxdata;
- s->insn_read = vmk80xx_cnt_insn_read;
- s->insn_config = vmk80xx_cnt_insn_config;
- if (devpriv->model == VMK8055_MODEL) {
- s->subdev_flags |= SDF_WRITABLE;
- s->insn_write = vmk80xx_cnt_insn_write;
- }
-
- /* PWM subdevice */
- if (devpriv->model == VMK8061_MODEL) {
- s = &dev->subdevices[5];
- s->type = COMEDI_SUBD_PWM;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = board->pwm_nchans;
- s->maxdata = board->pwm_maxdata;
- s->insn_read = vmk80xx_pwm_insn_read;
- s->insn_write = vmk80xx_pwm_insn_write;
- }
-
- up(&devpriv->limit_sem);
-
- return 0;
-}
-
-static int vmk80xx_auto_attach(struct comedi_device *dev,
- unsigned long context)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- const struct vmk80xx_board *board = NULL;
- struct vmk80xx_private *devpriv;
- int ret;
-
- if (context < ARRAY_SIZE(vmk80xx_boardinfo))
- board = &vmk80xx_boardinfo[context];
- if (!board)
- return -ENODEV;
- dev->board_ptr = board;
- dev->board_name = board->name;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- devpriv->model = board->model;
-
- sema_init(&devpriv->limit_sem, 8);
-
- ret = vmk80xx_find_usb_endpoints(dev);
- if (ret)
- return ret;
-
- ret = vmk80xx_alloc_usb_buffers(dev);
- if (ret)
- return ret;
-
- usb_set_intfdata(intf, devpriv);
-
- if (devpriv->model == VMK8055_MODEL)
- vmk80xx_reset_device(dev);
-
- return vmk80xx_init_subdevices(dev);
-}
-
-static void vmk80xx_detach(struct comedi_device *dev)
-{
- struct usb_interface *intf = comedi_to_usb_interface(dev);
- struct vmk80xx_private *devpriv = dev->private;
-
- if (!devpriv)
- return;
-
- down(&devpriv->limit_sem);
-
- usb_set_intfdata(intf, NULL);
-
- kfree(devpriv->usb_rx_buf);
- kfree(devpriv->usb_tx_buf);
-
- up(&devpriv->limit_sem);
-}
-
-static struct comedi_driver vmk80xx_driver = {
- .module = THIS_MODULE,
- .driver_name = "vmk80xx",
- .auto_attach = vmk80xx_auto_attach,
- .detach = vmk80xx_detach,
-};
-
-static int vmk80xx_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- return comedi_usb_auto_config(intf, &vmk80xx_driver, id->driver_info);
-}
-
-static const struct usb_device_id vmk80xx_usb_id_table[] = {
- { USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055 },
- { USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055 },
- { USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055 },
- { USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055 },
- { USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061 },
- { USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061 },
- { USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061 },
- { USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061 },
- { USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061 },
- { USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061 },
- { USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061 },
- { USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061 },
- { }
-};
-MODULE_DEVICE_TABLE(usb, vmk80xx_usb_id_table);
-
-static struct usb_driver vmk80xx_usb_driver = {
- .name = "vmk80xx",
- .id_table = vmk80xx_usb_id_table,
- .probe = vmk80xx_usb_probe,
- .disconnect = comedi_usb_auto_unconfig,
-};
-module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver);
-
-MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
-MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/z8536.h b/drivers/staging/comedi/drivers/z8536.h
deleted file mode 100644
index 3ef5f9e79b89..000000000000
--- a/drivers/staging/comedi/drivers/z8536.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Z8536 CIO Internal registers
- */
-
-#ifndef _Z8536_H
-#define _Z8536_H
-
-/* Master Interrupt Control register */
-#define Z8536_INT_CTRL_REG 0x00
-#define Z8536_INT_CTRL_MIE BIT(7) /* Master Interrupt Enable */
-#define Z8536_INT_CTRL_DLC BIT(6) /* Disable Lower Chain */
-#define Z8536_INT_CTRL_NV BIT(5) /* No Vector */
-#define Z8536_INT_CTRL_PA_VIS BIT(4) /* Port A Vect Inc Status */
-#define Z8536_INT_CTRL_PB_VIS BIT(3) /* Port B Vect Inc Status */
-#define Z8536_INT_CTRL_VT_VIS BIT(2) /* C/T Vect Inc Status */
-#define Z8536_INT_CTRL_RJA BIT(1) /* Right Justified Addresses */
-#define Z8536_INT_CTRL_RESET BIT(0) /* Reset */
-
-/* Master Configuration Control register */
-#define Z8536_CFG_CTRL_REG 0x01
-#define Z8536_CFG_CTRL_PBE BIT(7) /* Port B Enable */
-#define Z8536_CFG_CTRL_CT1E BIT(6) /* C/T 1 Enable */
-#define Z8536_CFG_CTRL_CT2E BIT(5) /* C/T 2 Enable */
-#define Z8536_CFG_CTRL_PCE_CT3E BIT(4) /* Port C & C/T 3 Enable */
-#define Z8536_CFG_CTRL_PLC BIT(3) /* Port A/B Link Control */
-#define Z8536_CFG_CTRL_PAE BIT(2) /* Port A Enable */
-#define Z8536_CFG_CTRL_LC(x) (((x) & 0x3) << 0) /* Link Control */
-#define Z8536_CFG_CTRL_LC_INDEP Z8536_CFG_CTRL_LC(0)/* Independent */
-#define Z8536_CFG_CTRL_LC_GATE Z8536_CFG_CTRL_LC(1)/* 1 Gates 2 */
-#define Z8536_CFG_CTRL_LC_TRIG Z8536_CFG_CTRL_LC(2)/* 1 Triggers 2 */
-#define Z8536_CFG_CTRL_LC_CLK Z8536_CFG_CTRL_LC(3)/* 1 Clocks 2 */
-#define Z8536_CFG_CTRL_LC_MASK Z8536_CFG_CTRL_LC(3)
-
-/* Interrupt Vector registers */
-#define Z8536_PA_INT_VECT_REG 0x02
-#define Z8536_PB_INT_VECT_REG 0x03
-#define Z8536_CT_INT_VECT_REG 0x04
-#define Z8536_CURR_INT_VECT_REG 0x1f
-
-/* Port A/B & Counter/Timer 1/2/3 Command and Status registers */
-#define Z8536_PA_CMDSTAT_REG 0x08
-#define Z8536_PB_CMDSTAT_REG 0x09
-#define Z8536_CT1_CMDSTAT_REG 0x0a
-#define Z8536_CT2_CMDSTAT_REG 0x0b
-#define Z8536_CT3_CMDSTAT_REG 0x0c
-#define Z8536_CT_CMDSTAT_REG(x) (0x0a + (x))
-#define Z8536_CMD(x) (((x) & 0x7) << 5)
-#define Z8536_CMD_NULL Z8536_CMD(0) /* Null Code */
-#define Z8536_CMD_CLR_IP_IUS Z8536_CMD(1) /* Clear IP & IUS */
-#define Z8536_CMD_SET_IUS Z8536_CMD(2) /* Set IUS */
-#define Z8536_CMD_CLR_IUS Z8536_CMD(3) /* Clear IUS */
-#define Z8536_CMD_SET_IP Z8536_CMD(4) /* Set IP */
-#define Z8536_CMD_CLR_IP Z8536_CMD(5) /* Clear IP */
-#define Z8536_CMD_SET_IE Z8536_CMD(6) /* Set IE */
-#define Z8536_CMD_CLR_IE Z8536_CMD(7) /* Clear IE */
-#define Z8536_CMD_MASK Z8536_CMD(7)
-
-#define Z8536_STAT_IUS BIT(7) /* Interrupt Under Service */
-#define Z8536_STAT_IE BIT(6) /* Interrupt Enable */
-#define Z8536_STAT_IP BIT(5) /* Interrupt Pending */
-#define Z8536_STAT_ERR BIT(4) /* Interrupt Error */
-#define Z8536_STAT_IE_IP (Z8536_STAT_IE | Z8536_STAT_IP)
-
-#define Z8536_PAB_STAT_ORE BIT(3) /* Output Register Empty */
-#define Z8536_PAB_STAT_IRF BIT(2) /* Input Register Full */
-#define Z8536_PAB_STAT_PMF BIT(1) /* Pattern Match Flag */
-#define Z8536_PAB_CMDSTAT_IOE BIT(0) /* Interrupt On Error */
-
-#define Z8536_CT_CMD_RCC BIT(3) /* Read Counter Control */
-#define Z8536_CT_CMDSTAT_GCB BIT(2) /* Gate Command Bit */
-#define Z8536_CT_CMD_TCB BIT(1) /* Trigger Command Bit */
-#define Z8536_CT_STAT_CIP BIT(0) /* Count In Progress */
-
-/* Port Data registers */
-#define Z8536_PA_DATA_REG 0x0d
-#define Z8536_PB_DATA_REG 0x0e
-#define Z8536_PC_DATA_REG 0x0f
-
-/* Counter/Timer 1/2/3 Current Count registers */
-#define Z8536_CT1_VAL_MSB_REG 0x10
-#define Z8536_CT1_VAL_LSB_REG 0x11
-#define Z8536_CT2_VAL_MSB_REG 0x12
-#define Z8536_CT2_VAL_LSB_REG 0x13
-#define Z8536_CT3_VAL_MSB_REG 0x14
-#define Z8536_CT3_VAL_LSB_REG 0x15
-#define Z8536_CT_VAL_MSB_REG(x) (0x10 + ((x) * 2))
-#define Z8536_CT_VAL_LSB_REG(x) (0x11 + ((x) * 2))
-
-/* Counter/Timer 1/2/3 Time Constant registers */
-#define Z8536_CT1_RELOAD_MSB_REG 0x16
-#define Z8536_CT1_RELOAD_LSB_REG 0x17
-#define Z8536_CT2_RELOAD_MSB_REG 0x18
-#define Z8536_CT2_RELOAD_LSB_REG 0x19
-#define Z8536_CT3_RELOAD_MSB_REG 0x1a
-#define Z8536_CT3_RELOAD_LSB_REG 0x1b
-#define Z8536_CT_RELOAD_MSB_REG(x) (0x16 + ((x) * 2))
-#define Z8536_CT_RELOAD_LSB_REG(x) (0x17 + ((x) * 2))
-
-/* Counter/Timer 1/2/3 Mode Specification registers */
-#define Z8536_CT1_MODE_REG 0x1c
-#define Z8536_CT2_MODE_REG 0x1d
-#define Z8536_CT3_MODE_REG 0x1e
-#define Z8536_CT_MODE_REG(x) (0x1c + (x))
-#define Z8536_CT_MODE_CSC BIT(7) /* Continuous/Single Cycle */
-#define Z8536_CT_MODE_EOE BIT(6) /* External Output Enable */
-#define Z8536_CT_MODE_ECE BIT(5) /* External Count Enable */
-#define Z8536_CT_MODE_ETE BIT(4) /* External Trigger Enable */
-#define Z8536_CT_MODE_EGE BIT(3) /* External Gate Enable */
-#define Z8536_CT_MODE_REB BIT(2) /* Retrigger Enable Bit */
-#define Z8536_CT_MODE_DCS(x) (((x) & 0x3) << 0) /* Duty Cycle */
-#define Z8536_CT_MODE_DCS_PULSE Z8536_CT_MODE_DCS(0) /* Pulse */
-#define Z8536_CT_MODE_DCS_ONESHOT Z8536_CT_MODE_DCS(1) /* One-Shot */
-#define Z8536_CT_MODE_DCS_SQRWAVE Z8536_CT_MODE_DCS(2) /* Square Wave */
-#define Z8536_CT_MODE_DCS_DO_NOT_USE Z8536_CT_MODE_DCS(3) /* Do Not Use */
-#define Z8536_CT_MODE_DCS_MASK Z8536_CT_MODE_DCS(3)
-
-/* Port A/B Mode Specification registers */
-#define Z8536_PA_MODE_REG 0x20
-#define Z8536_PB_MODE_REG 0x28
-#define Z8536_PAB_MODE_PTS(x) (((x) & 0x3) << 6) /* Port type */
-#define Z8536_PAB_MODE_PTS_BIT Z8536_PAB_MODE_PTS(0 << 6)/* Bit */
-#define Z8536_PAB_MODE_PTS_INPUT Z8536_PAB_MODE_PTS(1 << 6)/* Input */
-#define Z8536_PAB_MODE_PTS_OUTPUT Z8536_PAB_MODE_PTS(2 << 6)/* Output */
-#define Z8536_PAB_MODE_PTS_BIDIR Z8536_PAB_MODE_PTS(3 << 6)/* Bidir */
-#define Z8536_PAB_MODE_PTS_MASK Z8536_PAB_MODE_PTS(3 << 6)
-#define Z8536_PAB_MODE_ITB BIT(5) /* Interrupt on Two Bytes */
-#define Z8536_PAB_MODE_SB BIT(4) /* Single Buffered mode */
-#define Z8536_PAB_MODE_IMO BIT(3) /* Interrupt on Match Only */
-#define Z8536_PAB_MODE_PMS(x) (((x) & 0x3) << 1) /* Pattern Mode */
-#define Z8536_PAB_MODE_PMS_DISABLE Z8536_PAB_MODE_PMS(0)/* Disabled */
-#define Z8536_PAB_MODE_PMS_AND Z8536_PAB_MODE_PMS(1)/* "AND" */
-#define Z8536_PAB_MODE_PMS_OR Z8536_PAB_MODE_PMS(2)/* "OR" */
-#define Z8536_PAB_MODE_PMS_OR_PEV Z8536_PAB_MODE_PMS(3)/* "OR-Priority" */
-#define Z8536_PAB_MODE_PMS_MASK Z8536_PAB_MODE_PMS(3)
-#define Z8536_PAB_MODE_LPM BIT(0) /* Latch on Pattern Match */
-#define Z8536_PAB_MODE_DTE BIT(0) /* Deskew Timer Enabled */
-
-/* Port A/B Handshake Specification registers */
-#define Z8536_PA_HANDSHAKE_REG 0x21
-#define Z8536_PB_HANDSHAKE_REG 0x29
-#define Z8536_PAB_HANDSHAKE_HST(x) (((x) & 0x3) << 6) /* Handshake Type */
-#define Z8536_PAB_HANDSHAKE_HST_INTER Z8536_PAB_HANDSHAKE_HST(0)/*Interlock*/
-#define Z8536_PAB_HANDSHAKE_HST_STROBED Z8536_PAB_HANDSHAKE_HST(1)/* Strobed */
-#define Z8536_PAB_HANDSHAKE_HST_PULSED Z8536_PAB_HANDSHAKE_HST(2)/* Pulsed */
-#define Z8536_PAB_HANDSHAKE_HST_3WIRE Z8536_PAB_HANDSHAKE_HST(3)/* 3-Wire */
-#define Z8536_PAB_HANDSHAKE_HST_MASK Z8536_PAB_HANDSHAKE_HST(3)
-#define Z8536_PAB_HANDSHAKE_RWS(x) (((x) & 0x7) << 3) /* Req/Wait */
-#define Z8536_PAB_HANDSHAKE_RWS_DISABLE Z8536_PAB_HANDSHAKE_RWS(0)/* Disabled */
-#define Z8536_PAB_HANDSHAKE_RWS_OUTWAIT Z8536_PAB_HANDSHAKE_RWS(1)/* Out Wait */
-#define Z8536_PAB_HANDSHAKE_RWS_INWAIT Z8536_PAB_HANDSHAKE_RWS(3)/* In Wait */
-#define Z8536_PAB_HANDSHAKE_RWS_SPREQ Z8536_PAB_HANDSHAKE_RWS(4)/* Special */
-#define Z8536_PAB_HANDSHAKE_RWS_OUTREQ Z8536_PAB_HANDSHAKE_RWS(5)/* Out Req */
-#define Z8536_PAB_HANDSHAKE_RWS_INREQ Z8536_PAB_HANDSHAKE_RWS(7)/* In Req */
-#define Z8536_PAB_HANDSHAKE_RWS_MASK Z8536_PAB_HANDSHAKE_RWS(7)
-#define Z8536_PAB_HANDSHAKE_DESKEW(x) ((x) << 0)/* Deskew Time */
-#define Z8536_PAB_HANDSHAKE_DESKEW_MASK (3 << 0)/* Deskew Time mask */
-
-/*
- * Port A/B/C Data Path Polarity registers
- *
- * 0 = Non-Inverting
- * 1 = Inverting
- */
-#define Z8536_PA_DPP_REG 0x22
-#define Z8536_PB_DPP_REG 0x2a
-#define Z8536_PC_DPP_REG 0x05
-
-/*
- * Port A/B/C Data Direction registers
- *
- * 0 = Output bit
- * 1 = Input bit
- */
-#define Z8536_PA_DD_REG 0x23
-#define Z8536_PB_DD_REG 0x2b
-#define Z8536_PC_DD_REG 0x06
-
-/*
- * Port A/B/C Special I/O Control registers
- *
- * 0 = Normal Input or Output
- * 1 = Output with open drain or Input with 1's catcher
- */
-#define Z8536_PA_SIO_REG 0x24
-#define Z8536_PB_SIO_REG 0x2c
-#define Z8536_PC_SIO_REG 0x07
-
-/*
- * Port A/B Pattern Polarity/Transition/Mask registers
- *
- * PM PT PP Pattern Specification
- * -- -- -- -------------------------------------
- * 0 0 x Bit masked off
- * 0 1 x Any transition
- * 1 0 0 Zero (low-level)
- * 1 0 1 One (high-level)
- * 1 1 0 One-to-zero transition (falling-edge)
- * 1 1 1 Zero-to-one transition (rising-edge)
- */
-#define Z8536_PA_PP_REG 0x25
-#define Z8536_PB_PP_REG 0x2d
-
-#define Z8536_PA_PT_REG 0x26
-#define Z8536_PB_PT_REG 0x2e
-
-#define Z8536_PA_PM_REG 0x27
-#define Z8536_PB_PM_REG 0x2f
-
-#endif /* _Z8536_H */
diff --git a/drivers/staging/comedi/kcomedilib/Makefile b/drivers/staging/comedi/kcomedilib/Makefile
deleted file mode 100644
index 8031142a105f..000000000000
--- a/drivers/staging/comedi/kcomedilib/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG
-
-obj-$(CONFIG_COMEDI_KCOMEDILIB) += kcomedilib.o
-
-kcomedilib-objs := kcomedilib_main.o
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
deleted file mode 100644
index df9bba1b69ed..000000000000
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ /dev/null
@@ -1,255 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * kcomedilib/kcomedilib.c
- * a comedlib interface for kernel modules
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-
-#include "../comedi.h"
-#include "../comedilib.h"
-#include "../comedidev.h"
-
-MODULE_AUTHOR("David Schleef <ds@schleef.org>");
-MODULE_DESCRIPTION("Comedi kernel library");
-MODULE_LICENSE("GPL");
-
-struct comedi_device *comedi_open(const char *filename)
-{
- struct comedi_device *dev, *retval = NULL;
- unsigned int minor;
-
- if (strncmp(filename, "/dev/comedi", 11) != 0)
- return NULL;
-
- if (kstrtouint(filename + 11, 0, &minor))
- return NULL;
-
- if (minor >= COMEDI_NUM_BOARD_MINORS)
- return NULL;
-
- dev = comedi_dev_get_from_minor(minor);
- if (!dev)
- return NULL;
-
- down_read(&dev->attach_lock);
- if (dev->attached)
- retval = dev;
- else
- retval = NULL;
- up_read(&dev->attach_lock);
-
- if (!retval)
- comedi_dev_put(dev);
-
- return retval;
-}
-EXPORT_SYMBOL_GPL(comedi_open);
-
-int comedi_close(struct comedi_device *dev)
-{
- comedi_dev_put(dev);
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_close);
-
-static int comedi_do_insn(struct comedi_device *dev,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct comedi_subdevice *s;
- int ret;
-
- mutex_lock(&dev->mutex);
-
- if (!dev->attached) {
- ret = -EINVAL;
- goto error;
- }
-
- /* a subdevice instruction */
- if (insn->subdev >= dev->n_subdevices) {
- ret = -EINVAL;
- goto error;
- }
- s = &dev->subdevices[insn->subdev];
-
- if (s->type == COMEDI_SUBD_UNUSED) {
- dev_err(dev->class_dev,
- "%d not usable subdevice\n", insn->subdev);
- ret = -EIO;
- goto error;
- }
-
- /* XXX check lock */
-
- ret = comedi_check_chanlist(s, 1, &insn->chanspec);
- if (ret < 0) {
- dev_err(dev->class_dev, "bad chanspec\n");
- ret = -EINVAL;
- goto error;
- }
-
- if (s->busy) {
- ret = -EBUSY;
- goto error;
- }
- s->busy = dev;
-
- switch (insn->insn) {
- case INSN_BITS:
- ret = s->insn_bits(dev, s, insn, data);
- break;
- case INSN_CONFIG:
- /* XXX should check instruction length */
- ret = s->insn_config(dev, s, insn, data);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- s->busy = NULL;
-error:
-
- mutex_unlock(&dev->mutex);
- return ret;
-}
-
-int comedi_dio_get_config(struct comedi_device *dev, unsigned int subdev,
- unsigned int chan, unsigned int *io)
-{
- struct comedi_insn insn;
- unsigned int data[2];
- int ret;
-
- memset(&insn, 0, sizeof(insn));
- insn.insn = INSN_CONFIG;
- insn.n = 2;
- insn.subdev = subdev;
- insn.chanspec = CR_PACK(chan, 0, 0);
- data[0] = INSN_CONFIG_DIO_QUERY;
- data[1] = 0;
- ret = comedi_do_insn(dev, &insn, data);
- if (ret >= 0)
- *io = data[1];
- return ret;
-}
-EXPORT_SYMBOL_GPL(comedi_dio_get_config);
-
-int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
- unsigned int chan, unsigned int io)
-{
- struct comedi_insn insn;
-
- memset(&insn, 0, sizeof(insn));
- insn.insn = INSN_CONFIG;
- insn.n = 1;
- insn.subdev = subdev;
- insn.chanspec = CR_PACK(chan, 0, 0);
-
- return comedi_do_insn(dev, &insn, &io);
-}
-EXPORT_SYMBOL_GPL(comedi_dio_config);
-
-int comedi_dio_bitfield2(struct comedi_device *dev, unsigned int subdev,
- unsigned int mask, unsigned int *bits,
- unsigned int base_channel)
-{
- struct comedi_insn insn;
- unsigned int data[2];
- unsigned int n_chan;
- unsigned int shift;
- int ret;
-
- base_channel = CR_CHAN(base_channel);
- n_chan = comedi_get_n_channels(dev, subdev);
- if (base_channel >= n_chan)
- return -EINVAL;
-
- memset(&insn, 0, sizeof(insn));
- insn.insn = INSN_BITS;
- insn.chanspec = base_channel;
- insn.n = 2;
- insn.subdev = subdev;
-
- data[0] = mask;
- data[1] = *bits;
-
- /*
- * Most drivers ignore the base channel in insn->chanspec.
- * Fix this here if the subdevice has <= 32 channels.
- */
- if (n_chan <= 32) {
- shift = base_channel;
- if (shift) {
- insn.chanspec = 0;
- data[0] <<= shift;
- data[1] <<= shift;
- }
- } else {
- shift = 0;
- }
-
- ret = comedi_do_insn(dev, &insn, data);
- *bits = data[1] >> shift;
- return ret;
-}
-EXPORT_SYMBOL_GPL(comedi_dio_bitfield2);
-
-int comedi_find_subdevice_by_type(struct comedi_device *dev, int type,
- unsigned int subd)
-{
- struct comedi_subdevice *s;
- int ret = -ENODEV;
-
- down_read(&dev->attach_lock);
- if (dev->attached)
- for (; subd < dev->n_subdevices; subd++) {
- s = &dev->subdevices[subd];
- if (s->type == type) {
- ret = subd;
- break;
- }
- }
- up_read(&dev->attach_lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(comedi_find_subdevice_by_type);
-
-int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice)
-{
- int n;
-
- down_read(&dev->attach_lock);
- if (!dev->attached || subdevice >= dev->n_subdevices)
- n = 0;
- else
- n = dev->subdevices[subdevice].n_chan;
- up_read(&dev->attach_lock);
-
- return n;
-}
-EXPORT_SYMBOL_GPL(comedi_get_n_channels);
-
-static int __init kcomedilib_module_init(void)
-{
- return 0;
-}
-
-static void __exit kcomedilib_module_exit(void)
-{
-}
-
-module_init(kcomedilib_module_init);
-module_exit(kcomedilib_module_exit);
diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c
deleted file mode 100644
index 8bc8e42beb90..000000000000
--- a/drivers/staging/comedi/proc.c
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * /proc interface for comedi
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
- */
-
-/*
- * This is some serious bloatware.
- *
- * Taken from Dave A.'s PCL-711 driver, 'cuz I thought it
- * was cool.
- */
-
-#include "comedidev.h"
-#include "comedi_internal.h"
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-static int comedi_read(struct seq_file *m, void *v)
-{
- int i;
- int devices_q = 0;
- struct comedi_driver *driv;
-
- seq_printf(m, "comedi version " COMEDI_RELEASE "\nformat string: %s\n",
- "\"%2d: %-20s %-20s %4d\", i, driver_name, board_name, n_subdevices");
-
- for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
- struct comedi_device *dev = comedi_dev_get_from_minor(i);
-
- if (!dev)
- continue;
-
- down_read(&dev->attach_lock);
- if (dev->attached) {
- devices_q = 1;
- seq_printf(m, "%2d: %-20s %-20s %4d\n",
- i, dev->driver->driver_name,
- dev->board_name, dev->n_subdevices);
- }
- up_read(&dev->attach_lock);
- comedi_dev_put(dev);
- }
- if (!devices_q)
- seq_puts(m, "no devices\n");
-
- mutex_lock(&comedi_drivers_list_lock);
- for (driv = comedi_drivers; driv; driv = driv->next) {
- seq_printf(m, "%s:\n", driv->driver_name);
- for (i = 0; i < driv->num_names; i++)
- seq_printf(m, " %s\n",
- *(char **)((char *)driv->board_name +
- i * driv->offset));
-
- if (!driv->num_names)
- seq_printf(m, " %s\n", driv->driver_name);
- }
- mutex_unlock(&comedi_drivers_list_lock);
-
- return 0;
-}
-
-void __init comedi_proc_init(void)
-{
- if (!proc_create_single("comedi", 0444, NULL, comedi_read))
- pr_warn("comedi: unable to create proc entry\n");
-}
-
-void comedi_proc_cleanup(void)
-{
- remove_proc_entry("comedi", NULL);
-}
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
deleted file mode 100644
index a4e6fe0fb729..000000000000
--- a/drivers/staging/comedi/range.c
+++ /dev/null
@@ -1,131 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * comedi/range.c
- * comedi routines for voltage ranges
- *
- * COMEDI - Linux Control and Measurement Device Interface
- * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
- */
-
-#include <linux/uaccess.h>
-#include "comedidev.h"
-#include "comedi_internal.h"
-
-const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
-EXPORT_SYMBOL_GPL(range_bipolar10);
-const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
-EXPORT_SYMBOL_GPL(range_bipolar5);
-const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
-EXPORT_SYMBOL_GPL(range_bipolar2_5);
-const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
-EXPORT_SYMBOL_GPL(range_unipolar10);
-const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
-EXPORT_SYMBOL_GPL(range_unipolar5);
-const struct comedi_lrange range_unipolar2_5 = { 1, {UNI_RANGE(2.5)} };
-EXPORT_SYMBOL_GPL(range_unipolar2_5);
-const struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
-EXPORT_SYMBOL_GPL(range_0_20mA);
-const struct comedi_lrange range_4_20mA = { 1, {RANGE_mA(4, 20)} };
-EXPORT_SYMBOL_GPL(range_4_20mA);
-const struct comedi_lrange range_0_32mA = { 1, {RANGE_mA(0, 32)} };
-EXPORT_SYMBOL_GPL(range_0_32mA);
-const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } };
-EXPORT_SYMBOL_GPL(range_unknown);
-
-/*
- * COMEDI_RANGEINFO ioctl
- * range information
- *
- * arg:
- * pointer to comedi_rangeinfo structure
- *
- * reads:
- * comedi_rangeinfo structure
- *
- * writes:
- * array of comedi_krange structures to rangeinfo->range_ptr pointer
- */
-int do_rangeinfo_ioctl(struct comedi_device *dev,
- struct comedi_rangeinfo *it)
-{
- int subd, chan;
- const struct comedi_lrange *lr;
- struct comedi_subdevice *s;
-
- subd = (it->range_type >> 24) & 0xf;
- chan = (it->range_type >> 16) & 0xff;
-
- if (!dev->attached)
- return -EINVAL;
- if (subd >= dev->n_subdevices)
- return -EINVAL;
- s = &dev->subdevices[subd];
- if (s->range_table) {
- lr = s->range_table;
- } else if (s->range_table_list) {
- if (chan >= s->n_chan)
- return -EINVAL;
- lr = s->range_table_list[chan];
- } else {
- return -EINVAL;
- }
-
- if (RANGE_LENGTH(it->range_type) != lr->length) {
- dev_dbg(dev->class_dev,
- "wrong length %d should be %d (0x%08x)\n",
- RANGE_LENGTH(it->range_type),
- lr->length, it->range_type);
- return -EINVAL;
- }
-
- if (copy_to_user(it->range_ptr, lr->range,
- sizeof(struct comedi_krange) * lr->length))
- return -EFAULT;
-
- return 0;
-}
-
-/**
- * comedi_check_chanlist() - Validate each element in a chanlist.
- * @s: comedi_subdevice struct
- * @n: number of elements in the chanlist
- * @chanlist: the chanlist to validate
- *
- * Each element consists of a channel number, a range index, an analog
- * reference type and some flags, all packed into an unsigned int.
- *
- * This checks that the channel number and range index are supported by
- * the comedi subdevice. It does not check whether the analog reference
- * type and the flags are supported. Drivers that care should check those
- * themselves.
- *
- * Return: %0 if all @chanlist elements are valid (success),
- * %-EINVAL if one or more elements are invalid.
- */
-int comedi_check_chanlist(struct comedi_subdevice *s, int n,
- unsigned int *chanlist)
-{
- struct comedi_device *dev = s->device;
- unsigned int chanspec;
- int chan, range_len, i;
-
- for (i = 0; i < n; i++) {
- chanspec = chanlist[i];
- chan = CR_CHAN(chanspec);
- if (s->range_table)
- range_len = s->range_table->length;
- else if (s->range_table_list && chan < s->n_chan)
- range_len = s->range_table_list[chan]->length;
- else
- range_len = 0;
- if (chan >= s->n_chan ||
- CR_RANGE(chanspec) >= range_len) {
- dev_warn(dev->class_dev,
- "bad chanlist[%d]=0x%08x chan=%d range length=%d\n",
- i, chanspec, chan, range_len);
- return -EINVAL;
- }
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(comedi_check_chanlist);