diff options
Diffstat (limited to 'drivers/staging/comedi')
178 files changed, 13939 insertions, 20956 deletions
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 2093403..7de2a10 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -568,7 +568,6 @@ config COMEDI_8255_PCI config COMEDI_ADDI_APCI_035 tristate "ADDI-DATA APCI_035 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_035 cards @@ -577,7 +576,6 @@ config COMEDI_ADDI_APCI_035 config COMEDI_ADDI_APCI_1032 tristate "ADDI-DATA APCI_1032 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_1032 cards @@ -586,7 +584,6 @@ config COMEDI_ADDI_APCI_1032 config COMEDI_ADDI_APCI_1500 tristate "ADDI-DATA APCI_1500 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_1500 cards @@ -594,17 +591,17 @@ config COMEDI_ADDI_APCI_1500 called addi_apci_1500. config COMEDI_ADDI_APCI_1516 - tristate "ADDI-DATA APCI_1516 support" - depends on VIRT_TO_BUS + tristate "ADDI-DATA APCI-1016/1516/2016 support" ---help--- - Enable support for ADDI-DATA APCI_1516 cards + 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" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_1564 cards @@ -613,25 +610,14 @@ config COMEDI_ADDI_APCI_1564 config COMEDI_ADDI_APCI_16XX tristate "ADDI-DATA APCI_16xx support" - depends on VIRT_TO_BUS ---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_2016 - tristate "ADDI-DATA APCI_2016 support" - depends on VIRT_TO_BUS - ---help--- - Enable support for ADDI-DATA APCI_2016 cards - - To compile this driver as a module, choose M here: the module will be - called addi_apci_2016. - config COMEDI_ADDI_APCI_2032 tristate "ADDI-DATA APCI_2032 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_2032 cards @@ -640,36 +626,24 @@ config COMEDI_ADDI_APCI_2032 config COMEDI_ADDI_APCI_2200 tristate "ADDI-DATA APCI_2200 support" - depends on VIRT_TO_BUS ---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_3001 - tristate "ADDI-DATA APCI_3001 support" - depends on VIRT_TO_BUS - select COMEDI_FC - ---help--- - Enable support for ADDI-DATA APCI_3001 cards - - To compile this driver as a module, choose M here: the module will be - called addi_apci_3001. - config COMEDI_ADDI_APCI_3120 - tristate "ADDI-DATA APCI_3520 support" + tristate "ADDI-DATA APCI_3120/3001 support" depends on VIRT_TO_BUS select COMEDI_FC ---help--- - Enable support for ADDI-DATA APCI_3520 cards + 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" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_3501 cards @@ -678,7 +652,6 @@ config COMEDI_ADDI_APCI_3501 config COMEDI_ADDI_APCI_3XXX tristate "ADDI-DATA APCI_3xxx support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_3xxx cards @@ -761,10 +734,11 @@ config COMEDI_ADV_PCI_DIO called adv_pci_dio. config COMEDI_AMPLC_DIO200_PCI - tristate "Amplicon PCI215 and PCI272 DIO board support" + tristate "Amplicon PCI215/PCI272/PCIe215/PCIe236/PCIe296 DIO support" select COMEDI_AMPLC_DIO200 ---help--- - Enable support for Amplicon PCI215 and PCI272 DIO boards. + 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. @@ -1263,7 +1237,6 @@ config COMEDI_FC config COMEDI_AMPLC_DIO200 tristate - select COMEDI_8255 config COMEDI_AMPLC_PC236 tristate diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 133f013..c8a8ca1 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -283,6 +283,44 @@ enum configuration_ids { INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 }; +/* + * Settings for INSN_CONFIG_DIGITAL_TRIG: + * 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 + * + * operation parameter 1 parameter 2 parameter 3 + * --------------------------------- ----------- ----------- ----------- + * COMEDI_DIGITAL_TRIG_DISABLE + * COMEDI_DIGITAL_TRIG_ENABLE_EDGES left-shift rising-edges falling-edges + * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS left-shift high-levels low-levels + * + * COMEDI_DIGITAL_TRIG_DISABLE returns the trigger to its default, inactive, + * unconfigured state. + * + * COMEDI_DIGITAL_TRIG_ENABLE_EDGES sets the rising and/or falling edge inputs + * that each can fire the trigger. + * + * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS sets a combination of high and/or low + * level inputs that can fire the trigger. + * + * "left-shift" is useful if the trigger has more than 32 inputs to specify the + * first input for this configuration. + * + * 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_io_direction { COMEDI_INPUT = 0, COMEDI_OUTPUT = 1, @@ -888,7 +926,20 @@ enum amplc_dio_clock_source { subdevice, preceding counter subdevice is the last counter subdevice) */ - AMPLC_DIO_CLK_EXT /* per chip external input pin */ + 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 @@ -907,7 +958,17 @@ enum amplc_dio_gate_source { AMPLC_DIO_GAT_RESERVED4, AMPLC_DIO_GAT_RESERVED5, AMPLC_DIO_GAT_RESERVED6, - AMPLC_DIO_GAT_RESERVED7 + AMPLC_DIO_GAT_RESERVED7, + /* the following are "enhanced" gate sources for PCIe models */ + AMPLC_DIO_GAT_NGATN = 6, /* negated per channel gate input */ + AMPLC_DIO_GAT_OUTNM2, /* non-negated output of counter + channel minus 2 */ + 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" */ }; #endif /* _COMEDI_H */ diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c index 0a5057f..4b7cbfa 100644 --- a/drivers/staging/comedi/comedi_compat32.c +++ b/drivers/staging/comedi/comedi_compat32.c @@ -24,7 +24,6 @@ */ -#define __NO_VERSION__ #include <linux/uaccess.h> #include <linux/compat.h> #include <linux/fs.h> diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index c2a32cf..b7bba17 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -23,7 +23,6 @@ #undef DEBUG -#define __NO_VERSION__ #include "comedi_compat32.h" #include <linux/module.h> @@ -880,6 +879,10 @@ static int check_insn_config_length(struct comedi_insn *insn, if (insn->n == 5) return 0; break; + case INSN_CONFIG_DIGITAL_TRIG: + if (insn->n == 6) + return 0; + break; /* by default we allow the insn since we don't have checks for * all possible cases yet */ default: diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index cb67a5c..692e1e6 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -41,6 +41,7 @@ #include <linux/io.h> #include <linux/timer.h> #include <linux/pci.h> +#include <linux/usb.h> #include "comedi.h" @@ -54,9 +55,21 @@ COMEDI_MINORVERSION, COMEDI_MICROVERSION) #define COMEDI_RELEASE VERSION -#define PCI_VENDOR_ID_ADLINK 0x144a +/* + * 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_AMCC 0x10e8 +#define PCI_VENDOR_ID_DT 0x1116 +#define PCI_VENDOR_ID_IOTECH 0x1616 #define PCI_VENDOR_ID_CONTEC 0x1221 +#define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */ +#define PCI_VENDOR_ID_ADVANTECH 0x13fe +#define PCI_VENDOR_ID_MEILHAUS 0x1402 +#define PCI_VENDOR_ID_RTD 0x1435 +#define PCI_VENDOR_ID_ADLINK 0x144a +#define PCI_VENDOR_ID_AMPLICON 0x14dc #define COMEDI_NUM_MINORS 0x100 #define COMEDI_NUM_BOARD_MINORS 0x30 @@ -181,8 +194,6 @@ struct comedi_async { unsigned int x); }; -struct usb_interface; - struct comedi_driver { struct comedi_driver *next; @@ -190,8 +201,7 @@ struct comedi_driver { struct module *module; int (*attach) (struct comedi_device *, struct comedi_devconfig *); void (*detach) (struct comedi_device *); - int (*attach_pci) (struct comedi_device *, struct pci_dev *); - int (*attach_usb) (struct comedi_device *, struct usb_interface *); + int (*auto_attach) (struct comedi_device *, unsigned long); /* number of elements in board_name and board_id arrays */ unsigned int num_names; @@ -235,7 +245,7 @@ struct comedi_device { void (*close) (struct comedi_device *dev); }; -static inline const void *comedi_board(struct comedi_device *dev) +static inline const void *comedi_board(const struct comedi_device *dev) { return dev->board_ptr; } @@ -415,14 +425,6 @@ struct comedi_lrange { /* some silly little inline functions */ -static inline int alloc_private(struct comedi_device *dev, int size) -{ - dev->private = kzalloc(size, GFP_KERNEL); - if (!dev->private) - return -ENOMEM; - return 0; -} - static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd) { if (subd->subdev_flags & SDF_LSAMPL) @@ -436,9 +438,10 @@ into comedi's buffer */ static inline void comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev) { + if (dev->hw_dev == hw_dev) + return; if (dev->hw_dev) put_device(dev->hw_dev); - dev->hw_dev = hw_dev; if (dev->hw_dev) { dev->hw_dev = get_device(dev->hw_dev); @@ -451,6 +454,12 @@ static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev) return dev->hw_dev ? to_pci_dev(dev->hw_dev) : NULL; } +static inline struct usb_interface * +comedi_to_usb_interface(struct comedi_device *dev) +{ + return dev->hw_dev ? to_usb_interface(dev->hw_dev) : NULL; +} + int comedi_buf_put(struct comedi_async *async, short x); int comedi_buf_get(struct comedi_async *async, short *x); @@ -505,11 +514,30 @@ static inline void *comedi_aux_data(int options[], int n) int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s); void comedi_free_subdevice_minor(struct comedi_subdevice *s); -int comedi_pci_auto_config(struct pci_dev *pcidev, - struct comedi_driver *driver); -void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -int comedi_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver); -void comedi_usb_auto_unconfig(struct usb_interface *intf); +int comedi_auto_config(struct device *hardware_device, + struct comedi_driver *driver, unsigned long context); +void comedi_auto_unconfig(struct device *hardware_device); + +static inline int comedi_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) +{ + return comedi_auto_config(&pcidev->dev, driver, 0); +} + +static inline void comedi_pci_auto_unconfig(struct pci_dev *pcidev) +{ + comedi_auto_unconfig(&pcidev->dev); +} + +static inline int comedi_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config(&intf->dev, driver, 0); +} + +static inline void comedi_usb_auto_unconfig(struct usb_interface *intf) +{ + comedi_auto_unconfig(&intf->dev); +} #endif /* _COMEDIDEV_H */ diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1db6bfd..50cf498 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -21,9 +21,6 @@ */ -#define _GNU_SOURCE - -#define __NO_VERSION__ #include <linux/device.h> #include <linux/module.h> #include <linux/pci.h> @@ -833,11 +830,8 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } -static int -comedi_auto_config_helper(struct device *hardware_device, - struct comedi_driver *driver, - int (*attach_wrapper) (struct comedi_device *, - void *), void *context) +int comedi_auto_config(struct device *hardware_device, + struct comedi_driver *driver, unsigned long context) { int minor; struct comedi_device_file_info *dev_file_info; @@ -847,6 +841,13 @@ comedi_auto_config_helper(struct device *hardware_device, if (!comedi_autoconfig) return 0; + if (!driver->auto_attach) { + dev_warn(hardware_device, + "BUG! comedi driver '%s' has no auto_attach handler\n", + driver->driver_name); + return -EINVAL; + } + minor = comedi_alloc_board_minor(hardware_device); if (minor < 0) return minor; @@ -860,9 +861,9 @@ comedi_auto_config_helper(struct device *hardware_device, else if (!try_module_get(driver->module)) ret = -EIO; else { - /* set comedi_dev->driver here for attach wrapper */ + comedi_set_hw_dev(comedi_dev, hardware_device); comedi_dev->driver = driver; - ret = (*attach_wrapper)(comedi_dev, context); + ret = driver->auto_attach(comedi_dev, context); if (ret < 0) { module_put(driver->module); __comedi_device_detach(comedi_dev); @@ -876,49 +877,9 @@ comedi_auto_config_helper(struct device *hardware_device, comedi_free_board_minor(minor); return ret; } +EXPORT_SYMBOL_GPL(comedi_auto_config); -static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) -{ - struct comedi_devconfig *it = context; - struct comedi_driver *driv = dev->driver; - - if (driv->num_names) { - /* look for generic board entry matching driver name, which - * has already been copied to it->board_name */ - dev->board_ptr = comedi_recognize(driv, it->board_name); - if (dev->board_ptr == NULL) { - dev_warn(dev->class_dev, - "auto config failed to find board entry '%s' for driver '%s'\n", - it->board_name, driv->driver_name); - comedi_report_boards(driv); - return -EINVAL; - } - } - if (!driv->attach) { - dev_warn(dev->class_dev, - "BUG! driver '%s' using old-style auto config but has no attach handler\n", - driv->driver_name); - return -EINVAL; - } - return driv->attach(dev, it); -} - -static int comedi_auto_config(struct device *hardware_device, - struct comedi_driver *driver, const int *options, - unsigned num_options) -{ - struct comedi_devconfig it; - - memset(&it, 0, sizeof(it)); - strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN); - it.board_name[COMEDI_NAMELEN - 1] = '\0'; - BUG_ON(num_options > COMEDI_NDEVCONFOPTS); - memcpy(it.options, options, num_options * sizeof(int)); - return comedi_auto_config_helper(hardware_device, driver, - comedi_auto_config_wrapper, &it); -} - -static void comedi_auto_unconfig(struct device *hardware_device) +void comedi_auto_unconfig(struct device *hardware_device) { int minor; @@ -930,6 +891,7 @@ static void comedi_auto_unconfig(struct device *hardware_device) BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); comedi_free_board_minor(minor); } +EXPORT_SYMBOL_GPL(comedi_auto_unconfig); /** * comedi_pci_enable() - Enable the PCI device and request the regions. @@ -965,48 +927,6 @@ void comedi_pci_disable(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(comedi_pci_disable); -static int comedi_old_pci_auto_config(struct pci_dev *pcidev, - struct comedi_driver *driver) -{ - int options[2]; - - /* pci bus */ - options[0] = pcidev->bus->number; - /* pci slot */ - options[1] = PCI_SLOT(pcidev->devfn); - - return comedi_auto_config(&pcidev->dev, driver, - options, ARRAY_SIZE(options)); -} - -static int comedi_pci_attach_wrapper(struct comedi_device *dev, void *pcidev) -{ - return dev->driver->attach_pci(dev, pcidev); -} - -static int comedi_new_pci_auto_config(struct pci_dev *pcidev, - struct comedi_driver *driver) -{ - return comedi_auto_config_helper(&pcidev->dev, driver, - comedi_pci_attach_wrapper, pcidev); -} - -int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) -{ - - if (driver->attach_pci) - return comedi_new_pci_auto_config(pcidev, driver); - else - return comedi_old_pci_auto_config(pcidev, driver); -} -EXPORT_SYMBOL_GPL(comedi_pci_auto_config); - -void comedi_pci_auto_unconfig(struct pci_dev *pcidev) -{ - comedi_auto_unconfig(&pcidev->dev); -} -EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); - int comedi_pci_driver_register(struct comedi_driver *comedi_driver, struct pci_driver *pci_driver) { @@ -1040,42 +960,6 @@ EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); #if IS_ENABLED(CONFIG_USB) -static int comedi_old_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver) -{ - return comedi_auto_config(&intf->dev, driver, NULL, 0); -} - -static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf) -{ - return dev->driver->attach_usb(dev, intf); -} - -static int comedi_new_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver) -{ - return comedi_auto_config_helper(&intf->dev, driver, - comedi_usb_attach_wrapper, intf); -} - -int comedi_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver) -{ - BUG_ON(intf == NULL); - if (driver->attach_usb) - return comedi_new_usb_auto_config(intf, driver); - else - return comedi_old_usb_auto_config(intf, driver); -} -EXPORT_SYMBOL_GPL(comedi_usb_auto_config); - -void comedi_usb_auto_unconfig(struct usb_interface *intf) -{ - BUG_ON(intf == NULL); - comedi_auto_unconfig(&intf->dev); -} -EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); - int comedi_usb_driver_register(struct comedi_driver *comedi_driver, struct usb_driver *usb_driver) { diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index a256622..c7aa41a 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -249,28 +249,13 @@ static int subdev_8255_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3 */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index d00aff6..e0a7952 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -65,9 +65,6 @@ Configuration Options: not applicable, uses PCI auto config #define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248 #define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296 -/* ComputerBoards is now known as Measurement Computing */ -#define PCI_VENDOR_ID_CB 0x1307 - #define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b #define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014 #define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017 @@ -216,9 +213,10 @@ static const void *pci_8255_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci_8255_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int pci_8255_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci_8255_boardinfo *board; struct pci_8255_private *devpriv; struct comedi_subdevice *s; @@ -227,18 +225,16 @@ static int pci_8255_attach_pci(struct comedi_device *dev, int ret; int i; - comedi_set_hw_dev(dev, &pcidev->dev); - board = pci_8255_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; dev->board_ptr = board; dev->board_name = board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -308,17 +304,17 @@ static void pci_8255_detach(struct comedi_device *dev) static struct comedi_driver pci_8255_driver = { .driver_name = "8255_pci", .module = THIS_MODULE, - .attach_pci = pci_8255_attach_pci, + .auto_attach = pci_8255_auto_attach, .detach = pci_8255_detach, }; -static int __devinit pci_8255_pci_probe(struct pci_dev *dev, +static int pci_8255_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &pci_8255_driver); } -static void __devexit pci_8255_pci_remove(struct pci_dev *dev) +static void pci_8255_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -346,7 +342,7 @@ static struct pci_driver pci_8255_pci_driver = { .name = "8255_pci", .id_table = pci_8255_pci_table, .probe = pci_8255_pci_probe, - .remove = __devexit_p(pci_8255_pci_remove), + .remove = pci_8255_pci_remove, }; module_comedi_pci_driver(pci_8255_driver, pci_8255_pci_driver); diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index a2787c0..0de4d2e 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -62,10 +62,8 @@ 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_2016) += addi_apci_2016.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_3001) += addi_apci_3001.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 diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c index b59f2d4..d070208 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c @@ -18,7 +18,19 @@ | Description : APCI-1710 82X54 timer module | */ -#include "APCI1710_82x54.h" +#define APCI1710_PCI_BUS_CLOCK 0 +#define APCI1710_FRONT_CONNECTOR_INPUT 1 +#define APCI1710_TIMER_READVALUE 0 +#define APCI1710_TIMER_GETOUTPUTLEVEL 1 +#define APCI1710_TIMER_GETPROGRESSSTATUS 2 +#define APCI1710_TIMER_WRITEVALUE 3 + +#define APCI1710_TIMER_READINTERRUPT 1 +#define APCI1710_TIMER_READALLTIMER 2 + +#ifndef APCI1710_10MHZ +#define APCI1710_10MHZ 10 +#endif /* +----------------------------------------------------------------------------+ @@ -218,11 +230,12 @@ int i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s, | -9: Selection from hardware gate level is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr; unsigned char b_TimerNbr; @@ -447,11 +460,12 @@ i_ReturnValue=insn->n; | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_DummyRead; unsigned char b_ModulNbr; @@ -589,10 +603,12 @@ int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_sub | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr, b_ReadType; unsigned int *pul_TimerValueArray; @@ -668,70 +684,6 @@ int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_su /* +----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, -struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read write functions for Timer | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned char b_BitsType; - int i_ReturnValue = 0; - b_BitsType = data[0]; - - printk("\n82X54"); - - switch (b_BitsType) { - case APCI1710_TIMER_READVALUE: - i_ReturnValue = i_APCI1710_ReadTimerValue(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned int *) &data[0]); - break; - - case APCI1710_TIMER_GETOUTPUTLEVEL: - i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned char *) &data[0]); - break; - - case APCI1710_TIMER_GETPROGRESSSTATUS: - i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned char *)&data[0]); - break; - - case APCI1710_TIMER_WRITEVALUE: - i_ReturnValue = i_APCI1710_WriteTimerValue(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned int)data[1]); - - break; - - default: - printk("Bits Config Parameter Wrong\n"); - i_ReturnValue = -1; - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; -} - -/* -+----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_ReadTimerValue | | (unsigned char_ b_BoardHandle, | | unsigned char_ b_ModulNbr, | @@ -759,11 +711,12 @@ int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int *pul_TimerValue) +static int i_APCI1710_ReadTimerValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned int *pul_TimerValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /* Test the module number */ @@ -847,11 +800,12 @@ int i_APCI1710_ReadTimerValue(struct comedi_device *dev, | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_OutputLevel) +static int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned char *pb_OutputLevel) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_TimerStatus; @@ -926,11 +880,12 @@ int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_TimerStatus) +static int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned char *pb_TimerStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_TimerStatus; @@ -1005,11 +960,12 @@ int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_WriteTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int ul_WriteValue) +static int i_APCI1710_WriteTimerValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned int ul_WriteValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /* Test the module number */ @@ -1045,3 +1001,68 @@ int i_APCI1710_WriteTimerValue(struct comedi_device *dev, return i_ReturnValue; } + +/* ++----------------------------------------------------------------------------+ +| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, +struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | ++----------------------------------------------------------------------------+ +| Task : Read write functions for Timer | ++----------------------------------------------------------------------------+ +| Input Parameters : ++----------------------------------------------------------------------------+ +| Output Parameters : - | ++----------------------------------------------------------------------------+ +| Return Value : ++----------------------------------------------------------------------------+ +*/ +static int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned char b_BitsType; + int i_ReturnValue = 0; + b_BitsType = data[0]; + + printk("\n82X54"); + + switch (b_BitsType) { + case APCI1710_TIMER_READVALUE: + i_ReturnValue = i_APCI1710_ReadTimerValue(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned int *) &data[0]); + break; + + case APCI1710_TIMER_GETOUTPUTLEVEL: + i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned char *) &data[0]); + break; + + case APCI1710_TIMER_GETPROGRESSSTATUS: + i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned char *)&data[0]); + break; + + case APCI1710_TIMER_WRITEVALUE: + i_ReturnValue = i_APCI1710_WriteTimerValue(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned int)data[1]); + + break; + + default: + printk("Bits Config Parameter Wrong\n"); + i_ReturnValue = -1; + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; +} diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h deleted file mode 100644 index 81346db..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_PCI_BUS_CLOCK 0 -#define APCI1710_FRONT_CONNECTOR_INPUT 1 -#define APCI1710_TIMER_READVALUE 0 -#define APCI1710_TIMER_GETOUTPUTLEVEL 1 -#define APCI1710_TIMER_GETPROGRESSSTATUS 2 -#define APCI1710_TIMER_WRITEVALUE 3 - -#define APCI1710_TIMER_READINTERRUPT 1 -#define APCI1710_TIMER_READALLTIMER 2 - -/* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ -#ifndef APCI1710_10MHZ -#define APCI1710_10MHZ 10 -#endif -/* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ - -/* - * 82X54 TIMER INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * 82X54 READ FUNCTION - */ -int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * 82X54 READ & WRITE FUNCTION - */ -int i_APCI1710_ReadTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int *pul_TimerValue); - -int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_OutputLevel); - -int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_TimerStatus); - -/* - * 82X54 WRITE FUNCTION - */ -int i_APCI1710_WriteTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int ul_WriteValue); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c index 482a412..5bd7fe6 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c @@ -52,12 +52,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "APCI1710_Chrono.h" +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 + +#define APCI1710_SINGLE 0 +#define APCI1710_CONTINUOUS 1 + +#define APCI1710_CHRONO_PROGRESS_STATUS 0 +#define APCI1710_CHRONO_READVALUE 1 +#define APCI1710_CHRONO_CONVERTVALUE 2 +#define APCI1710_CHRONO_READINTERRUPT 3 + +#define APCI1710_CHRONO_SET_CHANNELON 0 +#define APCI1710_CHRONO_SET_CHANNELOFF 1 +#define APCI1710_CHRONO_READ_CHANNEL 2 +#define APCI1710_CHRONO_READ_PORT 3 /* +----------------------------------------------------------------------------+ @@ -130,10 +140,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour | this CHRONOS version | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_TimerValue = 0; unsigned int ul_TimingInterval = 0; @@ -839,10 +851,12 @@ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -8: data[0] wrong input | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action; b_ModulNbr = CR_AREF(insn->chanspec); @@ -1077,87 +1091,6 @@ int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, /* +----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read functions for Timer | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned char b_ReadType; - int i_ReturnValue = insn->n; - - b_ReadType = CR_CHAN(insn->chanspec); - - switch (b_ReadType) { - case APCI1710_CHRONO_PROGRESS_STATUS: - i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); - break; - - case APCI1710_CHRONO_READVALUE: - i_ReturnValue = i_APCI1710_ReadChronoValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned int) insn->unused[0], - (unsigned char *) &data[0], (unsigned int *) &data[1]); - break; - - case APCI1710_CHRONO_CONVERTVALUE: - i_ReturnValue = i_APCI1710_ConvertChronoValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned int) insn->unused[0], - (unsigned int *) &data[0], - (unsigned char *) &data[1], - (unsigned char *) &data[2], - (unsigned int *) &data[3], - (unsigned int *) &data[4], (unsigned int *) &data[5]); - break; - - case APCI1710_CHRONO_READINTERRUPT: - printk("In Chrono Read Interrupt\n"); - - data[0] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].b_OldModuleMask; - data[1] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldInterruptMask; - data[2] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; - - /**************************/ - /* Increment the read FIFO */ - /***************************/ - - devpriv-> - s_InterruptParameters. - ui_Read = (devpriv-> - s_InterruptParameters. - ui_Read + 1) % APCI1710_SAVE_INTERRUPT; - break; - - default: - printk("ReadType Parameter wrong\n"); - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; - -} - -/* -+----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_GetChronoProgressStatus | | (unsigned char_ b_BoardHandle, | | unsigned char_ b_ModulNbr, | @@ -1193,10 +1126,11 @@ int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice | "i_APCI1710_InitChrono" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus) +static int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_ChronoStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; @@ -1354,11 +1288,13 @@ int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, | directly the chronometer measured timing. | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, unsigned int *pul_ChronoValue) +static int i_APCI1710_ReadChronoValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ui_TimeOut, + unsigned char *pb_ChronoStatus, + unsigned int *pul_ChronoValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_TimeOut = 0; @@ -1617,15 +1553,17 @@ int i_APCI1710_ReadChronoValue(struct comedi_device *dev, | "i_APCI1710_InitChrono" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ul_ChronoValue, - unsigned int *pul_Hour, - unsigned char *pb_Minute, - unsigned char *pb_Second, - unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, unsigned int *pui_NanoSecond) +static int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ul_ChronoValue, + unsigned int *pul_Hour, + unsigned char *pb_Minute, + unsigned char *pb_Second, + unsigned int *pui_MilliSecond, + unsigned int *pui_MicroSecond, + unsigned int *pui_NanoSecond) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; double d_Hour; double d_Minute; @@ -1756,6 +1694,89 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, /* +----------------------------------------------------------------------------+ +| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s, +struct comedi_insn *insn,unsigned int *data) | ++----------------------------------------------------------------------------+ +| Task : Read functions for Timer | ++----------------------------------------------------------------------------+ +| Input Parameters : ++----------------------------------------------------------------------------+ +| Output Parameters : - | ++----------------------------------------------------------------------------+ +| Return Value : ++----------------------------------------------------------------------------+ +*/ +static int i_APCI1710_InsnReadChrono(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned char b_ReadType; + int i_ReturnValue = insn->n; + + b_ReadType = CR_CHAN(insn->chanspec); + + switch (b_ReadType) { + case APCI1710_CHRONO_PROGRESS_STATUS: + i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_CHRONO_READVALUE: + i_ReturnValue = i_APCI1710_ReadChronoValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned int) insn->unused[0], + (unsigned char *) &data[0], (unsigned int *) &data[1]); + break; + + case APCI1710_CHRONO_CONVERTVALUE: + i_ReturnValue = i_APCI1710_ConvertChronoValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned int) insn->unused[0], + (unsigned int *) &data[0], + (unsigned char *) &data[1], + (unsigned char *) &data[2], + (unsigned int *) &data[3], + (unsigned int *) &data[4], (unsigned int *) &data[5]); + break; + + case APCI1710_CHRONO_READINTERRUPT: + printk("In Chrono Read Interrupt\n"); + + data[0] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].b_OldModuleMask; + data[1] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldInterruptMask; + data[2] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; + + /**************************/ + /* Increment the read FIFO */ + /***************************/ + + devpriv-> + s_InterruptParameters. + ui_Read = (devpriv-> + s_InterruptParameters. + ui_Read + 1) % APCI1710_SAVE_INTERRUPT; + break; + + default: + printk("ReadType Parameter wrong\n"); + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; + +} + +/* ++----------------------------------------------------------------------------+ | Function Name : int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | +----------------------------------------------------------------------------+ @@ -1874,10 +1895,12 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, | "i_APCI1710_InitChrono" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType; unsigned int dw_Status; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h deleted file mode 100644 index 29bad1d..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_SINGLE 0 -#define APCI1710_CONTINUOUS 1 - -#define APCI1710_CHRONO_PROGRESS_STATUS 0 -#define APCI1710_CHRONO_READVALUE 1 -#define APCI1710_CHRONO_CONVERTVALUE 2 -#define APCI1710_CHRONO_READINTERRUPT 3 - -#define APCI1710_CHRONO_SET_CHANNELON 0 -#define APCI1710_CHRONO_SET_CHANNELOFF 1 -#define APCI1710_CHRONO_READ_CHANNEL 2 -#define APCI1710_CHRONO_READ_PORT 3 - -/* - * CHRONOMETER INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -/* - * CHRONOMETER READ FUNCTION - */ -int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus); - -int i_APCI1710_ReadChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, - unsigned int *pul_ChronoValue); - -int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ul_ChronoValue, - unsigned int *pul_Hour, - unsigned char *pb_Minute, - unsigned char *pb_Second, - unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, - unsigned int *pui_NanoSecond); - -/* - * CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION - */ -int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c index 07108f9..6b38ce7 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c @@ -52,12 +52,16 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "APCI1710_Dig_io.h" +/* Digital Output ON or OFF */ +#define APCI1710_ON 1 +#define APCI1710_OFF 0 + +/* Digital I/O */ +#define APCI1710_INPUT 0 +#define APCI1710_OUTPUT 1 + +#define APCI1710_DIGIO_MEMORYONOFF 0x10 +#define APCI1710_DIGIO_INIT 0x11 /* +----------------------------------------------------------------------------+ @@ -99,9 +103,12 @@ Activates and deactivates the digital output memory. +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode; unsigned char b_MemoryOnOff, b_ConfigType; int i_ReturnValue = 0; @@ -293,9 +300,12 @@ int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subd * unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel, * unsigned char *_ pb_ChannelStatus) */ -int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr, b_InputChannel; @@ -481,9 +491,12 @@ int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, * _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle, * unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel) */ -int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_WriteValue = 0; unsigned char b_ModulNbr, b_OutputChannel; @@ -731,9 +744,12 @@ int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, * b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_ * b_PortValue) */ -int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_WriteValue = 0; unsigned int dw_StatusReg; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h deleted file mode 100644 index cc3973d..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_ON 1 /* Digital Output ON or OFF */ -#define APCI1710_OFF 0 - -#define APCI1710_INPUT 0 /* Digital I/O */ -#define APCI1710_OUTPUT 1 - -#define APCI1710_DIGIO_MEMORYONOFF 0x10 -#define APCI1710_DIGIO_INIT 0x11 - -/* - * DIGITAL I/O INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * INPUT OUTPUT FUNCTIONS - */ -int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c index 14b13ea..70a7f95 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c @@ -51,93 +51,121 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ - -#include "APCI1710_INCCPT.h" - -/* -+----------------------------------------------------------------------------+ -| int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) - -+----------------------------------------------------------------------------+ -| Task : Configuration function for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : | -+----------------------------------------------------------------------------+ -| Output Parameters : *data -+----------------------------------------------------------------------------+ -| Return Value : | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_ConfigType; - int i_ReturnValue = 0; - ui_ConfigType = CR_CHAN(insn->chanspec); - - printk("\nINC_CPT"); - - devpriv->tsk_Current = current; /* Save the current process task structure */ - switch (ui_ConfigType) { - case APCI1710_INCCPT_INITCOUNTER: - i_ReturnValue = i_APCI1710_InitCounter(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], - (unsigned char) data[2], (unsigned char) data[3], (unsigned char) data[4]); - break; - - case APCI1710_INCCPT_COUNTERAUTOTEST: - i_ReturnValue = i_APCI1710_CounterAutoTest(dev, - (unsigned char *) &data[0]); - break; - - case APCI1710_INCCPT_INITINDEX: - i_ReturnValue = i_APCI1710_InitIndex(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], (unsigned char) data[2], (unsigned char) data[3]); - break; - - case APCI1710_INCCPT_INITREFERENCE: - i_ReturnValue = i_APCI1710_InitReference(dev, - CR_AREF(insn->chanspec), (unsigned char) data[0]); - break; - - case APCI1710_INCCPT_INITEXTERNALSTROBE: - i_ReturnValue = i_APCI1710_InitExternalStrobe(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], (unsigned char) data[1]); - break; - - case APCI1710_INCCPT_INITCOMPARELOGIC: - i_ReturnValue = i_APCI1710_InitCompareLogic(dev, - CR_AREF(insn->chanspec), (unsigned int) data[0]); - break; - - case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], (unsigned int) data[2], (unsigned int *) &data[0]); - break; - - default: - printk("Insn Config : Config Parameter Wrong\n"); - - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; -} +#define APCI1710_16BIT_COUNTER 0x10 +#define APCI1710_32BIT_COUNTER 0x0 +#define APCI1710_QUADRUPLE_MODE 0x0 +#define APCI1710_DOUBLE_MODE 0x3 +#define APCI1710_SIMPLE_MODE 0xF +#define APCI1710_DIRECT_MODE 0x80 +#define APCI1710_HYSTERESIS_ON 0x60 +#define APCI1710_HYSTERESIS_OFF 0x0 +#define APCI1710_INCREMENT 0x60 +#define APCI1710_DECREMENT 0x0 +#define APCI1710_LATCH_COUNTER 0x1 +#define APCI1710_CLEAR_COUNTER 0x0 +#define APCI1710_LOW 0x0 +#define APCI1710_HIGH 0x1 + +/*********************/ +/* Version 0600-0229 */ +/*********************/ +#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0 +#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1 +#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2 +#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3 +#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4 +#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5 +#define APCI1710_SOURCE_0 0x0 +#define APCI1710_SOURCE_1 0x1 + +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 + +#define APCI1710_ENABLE_LATCH_INT 0x80 +#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT) + +#define APCI1710_INDEX_LATCH_COUNTER 0x10 +#define APCI1710_INDEX_AUTO_MODE 0x8 +#define APCI1710_ENABLE_INDEX 0x4 +#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX) +#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8 +#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR) +#define APCI1710_SET_LOW_INDEX_LEVEL 0x4 +#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL) +#define APCI1710_INVERT_INDEX_RFERENCE 0x2 +#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE) + +#define APCI1710_ENABLE_INDEX_INT 0x1 +#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT) + +#define APCI1710_ENABLE_FREQUENCY 0x4 +#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY) + +#define APCI1710_ENABLE_FREQUENCY_INT 0x8 +#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT) + +#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40 +#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY) + +#define APCI1710_ENABLE_40MHZ_FILTER 0x80 +#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER) + +#define APCI1710_ENABLE_COMPARE_INT 0x2 +#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT) + +#define APCI1710_ENABLE_INDEX_ACTION 0x20 +#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION) +#define APCI1710_REFERENCE_HIGH 0x40 +#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH) + +#define APCI1710_TOR_GATE_LOW 0x40 +#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW) + +/* INSN CONFIG */ +#define APCI1710_INCCPT_INITCOUNTER 100 +#define APCI1710_INCCPT_COUNTERAUTOTEST 101 +#define APCI1710_INCCPT_INITINDEX 102 +#define APCI1710_INCCPT_INITREFERENCE 103 +#define APCI1710_INCCPT_INITEXTERNALSTROBE 104 +#define APCI1710_INCCPT_INITCOMPARELOGIC 105 +#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106 + +/* INSN READ */ +#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200 +#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201 +#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202 +#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203 +#define APCI1710_INCCPT_GETINDEXSTATUS 204 +#define APCI1710_INCCPT_GETREFERENCESTATUS 205 +#define APCI1710_INCCPT_GETUASSTATUS 206 +#define APCI1710_INCCPT_GETCBSTATUS 207 +#define APCI1710_INCCPT_GET16BITCBSTATUS 208 +#define APCI1710_INCCPT_GETUDSTATUS 209 +#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210 +#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211 +#define APCI1710_INCCPT_READINTERRUPT 212 + +/* INSN BITS */ +#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300 +#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301 +#define APCI1710_INCCPT_SETINPUTFILTER 302 +#define APCI1710_INCCPT_LATCHCOUNTER 303 +#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304 +#define APCI1710_INCCPT_SETDIGITALCHLON 305 +#define APCI1710_INCCPT_SETDIGITALCHLOFF 306 + +/* INSN WRITE */ +#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400 +#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401 +#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402 +#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403 +#define APCI1710_INCCPT_ENABLEINDEX 404 +#define APCI1710_INCCPT_DISABLEINDEX 405 +#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406 +#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407 +#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408 +#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409 /* +----------------------------------------------------------------------------+ @@ -298,14 +326,15 @@ int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevi | wrong. | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_CounterRange, - unsigned char b_FirstCounterModus, - unsigned char b_FirstCounterOption, - unsigned char b_SecondCounterModus, unsigned char b_SecondCounterOption) +static int i_APCI1710_InitCounter(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_CounterRange, + unsigned char b_FirstCounterModus, + unsigned char b_FirstCounterOption, + unsigned char b_SecondCounterModus, + unsigned char b_SecondCounterOption) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /*******************************/ @@ -544,9 +573,10 @@ int i_APCI1710_InitCounter(struct comedi_device *dev, | -2: No counter module found | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char *pb_TestStatus) +static int i_APCI1710_CounterAutoTest(struct comedi_device *dev, + unsigned char *pb_TestStatus) { + struct addi_private *devpriv = dev->private; unsigned char b_ModulCpt = 0; int i_ReturnValue = 0; unsigned int dw_LathchValue; @@ -707,12 +737,14 @@ int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char *pb_Test | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitIndex(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_ReferenceAction, - unsigned char b_IndexOperation, unsigned char b_AutoMode, unsigned char b_InterruptEnable) +static int i_APCI1710_InitIndex(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_ReferenceAction, + unsigned char b_IndexOperation, + unsigned char b_AutoMode, + unsigned char b_InterruptEnable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1151,10 +1183,11 @@ int i_APCI1710_InitIndex(struct comedi_device *dev, | -4: Reference level parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitReference(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ReferenceLevel) +static int i_APCI1710_InitReference(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_ReferenceLevel) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1276,10 +1309,12 @@ int i_APCI1710_InitReference(struct comedi_device *dev, | -5: External strobe level parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ExternalStrobe, unsigned char b_ExternalStrobeLevel) +static int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_ExternalStrobe, + unsigned char b_ExternalStrobeLevel) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1390,10 +1425,11 @@ int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitCompareLogic(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ui_CompareValue) +static int i_APCI1710_InitCompareLogic(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ui_CompareValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1486,13 +1522,14 @@ int i_APCI1710_InitCompareLogic(struct comedi_device *dev, | -7: 40MHz quartz not on board | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PCIInputClock, - unsigned char b_TimingUnity, - unsigned int ul_TimingInterval, unsigned int *pul_RealTimingInterval) +static int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PCIInputClock, + unsigned char b_TimingUnity, + unsigned int ul_TimingInterval, + unsigned int *pul_RealTimingInterval) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_TimerValue = 0; double d_RealTimingInterval; @@ -1995,72 +2032,70 @@ int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, return i_ReturnValue; } -/*########################################################################### */ - - /* INSN BITS */ -/*########################################################################### */ - /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Set & Clear Functions for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Configuration function for INC_CPT + */ +static int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_BitsType; + struct addi_private *devpriv = dev->private; + unsigned int ui_ConfigType; int i_ReturnValue = 0; - ui_BitsType = CR_CHAN(insn->chanspec); - devpriv->tsk_Current = current; /* Save the current process task structure */ - switch (ui_BitsType) { - case APCI1710_INCCPT_CLEARCOUNTERVALUE: - i_ReturnValue = i_APCI1710_ClearCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec)); + ui_ConfigType = CR_CHAN(insn->chanspec); + + printk("\nINC_CPT"); + + devpriv->tsk_Current = current; /* Save the current process task structure */ + switch (ui_ConfigType) { + case APCI1710_INCCPT_INITCOUNTER: + i_ReturnValue = i_APCI1710_InitCounter(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], + (unsigned char) data[2], (unsigned char) data[3], (unsigned char) data[4]); break; - case APCI1710_INCCPT_CLEARALLCOUNTERVALUE: - i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev); + case APCI1710_INCCPT_COUNTERAUTOTEST: + i_ReturnValue = i_APCI1710_CounterAutoTest(dev, + (unsigned char *) &data[0]); break; - case APCI1710_INCCPT_SETINPUTFILTER: - i_ReturnValue = i_APCI1710_SetInputFilter(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], (unsigned char) data[1]); + case APCI1710_INCCPT_INITINDEX: + i_ReturnValue = i_APCI1710_InitIndex(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], (unsigned char) data[2], (unsigned char) data[3]); break; - case APCI1710_INCCPT_LATCHCOUNTER: - i_ReturnValue = i_APCI1710_LatchCounter(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + case APCI1710_INCCPT_INITREFERENCE: + i_ReturnValue = i_APCI1710_InitReference(dev, + CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE: - i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + case APCI1710_INCCPT_INITEXTERNALSTROBE: + i_ReturnValue = i_APCI1710_InitExternalStrobe(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], (unsigned char) data[1]); break; - case APCI1710_INCCPT_SETDIGITALCHLON: - i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_INITCOMPARELOGIC: + i_ReturnValue = i_APCI1710_InitCompareLogic(dev, + CR_AREF(insn->chanspec), (unsigned int) data[0]); break; - case APCI1710_INCCPT_SETDIGITALCHLOFF: - i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], (unsigned int) data[2], (unsigned int *) &data[0]); break; default: - printk("Bits Config Parameter Wrong\n"); + printk("Insn Config : Config Parameter Wrong\n"); + } if (i_ReturnValue >= 0) @@ -2090,9 +2125,10 @@ int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_ClearCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2150,9 +2186,9 @@ int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_Modu | -2: No counter module found | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) +static int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; unsigned char b_ModulCpt = 0; int i_ReturnValue = 0; @@ -2296,10 +2332,12 @@ int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) | -6: 40MHz quartz not on board | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetInputFilter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_PCIInputClock, unsigned char b_Filter) +static int i_APCI1710_SetInputFilter(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PCIInputClock, + unsigned char b_Filter) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status = 0; @@ -2560,10 +2598,11 @@ int i_APCI1710_SetInputFilter(struct comedi_device *dev, | -4: The selected latch register parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_LatchCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg) +static int i_APCI1710_LatchCounter(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_LatchReg) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2657,10 +2696,11 @@ int i_APCI1710_LatchCounter(struct comedi_device *dev, | -4: The source selection is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SourceSelection) +static int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_SourceSelection) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2794,9 +2834,10 @@ int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2874,9 +2915,10 @@ int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulN | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2932,88 +2974,59 @@ int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_Modul return i_ReturnValue; } -/*########################################################################### */ - - /* INSN WRITE */ -/*########################################################################### */ - /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Enable Disable functions for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ -int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Set & Clear Functions for INC_CPT + */ +static int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_WriteType; + struct addi_private *devpriv = dev->private; + unsigned int ui_BitsType; int i_ReturnValue = 0; - ui_WriteType = CR_CHAN(insn->chanspec); + ui_BitsType = CR_CHAN(insn->chanspec); devpriv->tsk_Current = current; /* Save the current process task structure */ - switch (ui_WriteType) { - case APCI1710_INCCPT_ENABLELATCHINTERRUPT: - i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev, + switch (ui_BitsType) { + case APCI1710_INCCPT_CLEARCOUNTERVALUE: + i_ReturnValue = i_APCI1710_ClearCounterValue(dev, (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_DISABLELATCHINTERRUPT: - i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_CLEARALLCOUNTERVALUE: + i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev); break; - case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev, + case APCI1710_INCCPT_SETINPUTFILTER: + i_ReturnValue = i_APCI1710_SetInputFilter(dev, (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], (unsigned int) data[1]); - break; - - case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned int) data[0]); - - break; - - case APCI1710_INCCPT_ENABLEINDEX: - i_APCI1710_EnableIndex(dev, (unsigned char) CR_AREF(insn->chanspec)); + (unsigned char) data[0], (unsigned char) data[1]); break; - case APCI1710_INCCPT_DISABLEINDEX: - i_ReturnValue = i_APCI1710_DisableIndex(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_LATCHCOUNTER: + i_ReturnValue = i_APCI1710_LatchCounter(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_ENABLECOMPARELOGIC: - i_ReturnValue = i_APCI1710_EnableCompareLogic(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE: + i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_DISABLECOMPARELOGIC: - i_ReturnValue = i_APCI1710_DisableCompareLogic(dev, + case APCI1710_INCCPT_SETDIGITALCHLON: + i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev, (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); - break; - - case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev, + case APCI1710_INCCPT_SETDIGITALCHLOFF: + i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev, (unsigned char) CR_AREF(insn->chanspec)); break; default: - printk("Write Config Parameter Wrong\n"); + printk("Bits Config Parameter Wrong\n"); } if (i_ReturnValue >= 0) @@ -3046,9 +3059,10 @@ int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevic | "i_APCI1710_SetBoardIntRoutine" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3132,9 +3146,10 @@ int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_M | "i_APCI1710_SetBoardIntRoutine" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3230,10 +3245,12 @@ int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ | -4: The selected 16-Bit counter parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int ui_WriteValue) +static int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_SelectedCounter, + unsigned int ui_WriteValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3315,10 +3332,11 @@ int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ul_WriteValue) +static int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ul_WriteValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3382,9 +3400,10 @@ int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitIndex" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_EnableIndex(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_InterruptLatchReg; @@ -3480,9 +3499,10 @@ int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) | "i_APCI1710_InitIndex" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableIndex(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3579,9 +3599,10 @@ int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3679,9 +3700,10 @@ int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_Mod | See function "i_APCI1710_InitCompareLogic" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3788,10 +3810,11 @@ int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_Mo | -6: Interrupt function not initialised. | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_InterruptEnable) +static int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_InterruptEnable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3935,9 +3958,10 @@ int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, | See function "i_APCI1710_InitFrequencyMeasurement" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -4029,134 +4053,80 @@ int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, unsigned c return i_ReturnValue; } -/*########################################################################### */ - - /* INSN READ */ - -/*########################################################################### */ - /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read and Get functions for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ -int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Enable Disable functions for INC_CPT + */ +static int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_ReadType; + struct addi_private *devpriv = dev->private; + unsigned int ui_WriteType; int i_ReturnValue = 0; - ui_ReadType = CR_CHAN(insn->chanspec); - + ui_WriteType = CR_CHAN(insn->chanspec); devpriv->tsk_Current = current; /* Save the current process task structure */ - switch (ui_ReadType) { - case APCI1710_INCCPT_READLATCHREGISTERSTATUS: - i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) CR_RANGE(insn->chanspec), (unsigned char *) &data[0]); - break; - case APCI1710_INCCPT_READLATCHREGISTERVALUE: - i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); - printk("Latch Register Value %d\n", data[0]); + switch (ui_WriteType) { + case APCI1710_INCCPT_ENABLELATCHINTERRUPT: + i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_READ16BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); + case APCI1710_INCCPT_DISABLELATCHINTERRUPT: + i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_READ32BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned int *) &data[0]); + case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) data[0], (unsigned int) data[1]); break; - case APCI1710_INCCPT_GETINDEXSTATUS: - i_ReturnValue = i_APCI1710_GetIndexStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); - break; + case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned int) data[0]); - case APCI1710_INCCPT_GETREFERENCESTATUS: - i_ReturnValue = i_APCI1710_GetReferenceStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); break; - case APCI1710_INCCPT_GETUASSTATUS: - i_ReturnValue = i_APCI1710_GetUASStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); - break; - - case APCI1710_INCCPT_GETCBSTATUS: - i_ReturnValue = i_APCI1710_GetCBStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + case APCI1710_INCCPT_ENABLEINDEX: + i_APCI1710_EnableIndex(dev, (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_GET16BITCBSTATUS: - i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char *) &data[0], (unsigned char *) &data[1]); + case APCI1710_INCCPT_DISABLEINDEX: + i_ReturnValue = i_APCI1710_DisableIndex(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_GETUDSTATUS: - i_ReturnValue = i_APCI1710_GetUDStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); - + case APCI1710_INCCPT_ENABLECOMPARELOGIC: + i_ReturnValue = i_APCI1710_EnableCompareLogic(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS: - i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + case APCI1710_INCCPT_DISABLECOMPARELOGIC: + i_ReturnValue = i_APCI1710_DisableCompareLogic(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_READFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char *) &data[0], - (unsigned char *) &data[1], (unsigned int *) &data[2]); + case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_READINTERRUPT: - data[0] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].b_OldModuleMask; - data[1] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldInterruptMask; - data[2] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; - - /**************************/ - /* Increment the read FIFO */ - /***************************/ - - devpriv-> - s_InterruptParameters. - ui_Read = (devpriv->s_InterruptParameters. - ui_Read + 1) % APCI1710_SAVE_INTERRUPT; - + case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; default: - printk("ReadType Parameter wrong\n"); + printk("Write Config Parameter Wrong\n"); } if (i_ReturnValue >= 0) i_ReturnValue = insn->n; return i_ReturnValue; - } /* @@ -4192,10 +4162,12 @@ int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice | -4: The selected latch register parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned char *pb_LatchStatus) +static int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_LatchReg, + unsigned char *pb_LatchStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_LatchReg; @@ -4279,10 +4251,12 @@ int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, | -4: The selected latch register parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned int *pul_LatchValue) +static int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_LatchReg, + unsigned int *pul_LatchValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -4363,10 +4337,12 @@ int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, | -4: The selected 16-Bit counter parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int *pui_CounterValue) +static int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_SelectedCounter, + unsigned int *pui_CounterValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_LathchValue = 0; @@ -4458,10 +4434,11 @@ int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int *pul_CounterValue) +static int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int *pul_CounterValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -4534,10 +4511,11 @@ int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitIndex" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetIndexStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_IndexStatus) +static int i_APCI1710_GetIndexStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_IndexStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4618,10 +4596,11 @@ int i_APCI1710_GetIndexStatus(struct comedi_device *dev, | "i_APCI1710_InitReference" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ReferenceStatus) +static int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_ReferenceStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4702,10 +4681,11 @@ int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetUASStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UASStatus) +static int i_APCI1710_GetUASStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_UASStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4770,10 +4750,11 @@ int i_APCI1710_GetUASStatus(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatus) +static int i_APCI1710_GetCBStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_CBStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4852,10 +4833,12 @@ int i_APCI1710_GetCBStatus(struct comedi_device *dev, | -5: Firmware revision error | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatusCounter0, unsigned char *pb_CBStatusCounter1) +static int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_CBStatusCounter0, + unsigned char *pb_CBStatusCounter1) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4965,10 +4948,11 @@ int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetUDStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus) +static int i_APCI1710_GetUDStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_UDStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -5039,10 +5023,11 @@ int i_APCI1710_GetUDStatus(struct comedi_device *dev, | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus) +static int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_UDStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -5144,11 +5129,13 @@ int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, | See function "i_APCI1710_InitFrequencyMeasurement" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char *pb_Status, unsigned char *pb_UDStatus, unsigned int *pul_ReadValue) +static int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_Status, + unsigned char *pb_UDStatus, + unsigned int *pul_ReadValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ui_16BitValue; unsigned int dw_StatusReg; @@ -5361,3 +5348,118 @@ int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, return i_ReturnValue; } +/* + * Read and Get functions for INC_CPT + */ +static int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_ReadType; + int i_ReturnValue = 0; + + ui_ReadType = CR_CHAN(insn->chanspec); + + devpriv->tsk_Current = current; /* Save the current process task structure */ + switch (ui_ReadType) { + case APCI1710_INCCPT_READLATCHREGISTERSTATUS: + i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) CR_RANGE(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_READLATCHREGISTERVALUE: + i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); + printk("Latch Register Value %d\n", data[0]); + break; + + case APCI1710_INCCPT_READ16BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); + break; + + case APCI1710_INCCPT_READ32BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned int *) &data[0]); + break; + + case APCI1710_INCCPT_GETINDEXSTATUS: + i_ReturnValue = i_APCI1710_GetIndexStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GETREFERENCESTATUS: + i_ReturnValue = i_APCI1710_GetReferenceStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GETUASSTATUS: + i_ReturnValue = i_APCI1710_GetUASStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GETCBSTATUS: + i_ReturnValue = i_APCI1710_GetCBStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GET16BITCBSTATUS: + i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char *) &data[0], (unsigned char *) &data[1]); + break; + + case APCI1710_INCCPT_GETUDSTATUS: + i_ReturnValue = i_APCI1710_GetUDStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + + break; + + case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS: + i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_READFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char *) &data[0], + (unsigned char *) &data[1], (unsigned int *) &data[2]); + break; + + case APCI1710_INCCPT_READINTERRUPT: + data[0] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].b_OldModuleMask; + data[1] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldInterruptMask; + data[2] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; + + /**************************/ + /* Increment the read FIFO */ + /***************************/ + + devpriv-> + s_InterruptParameters. + ui_Read = (devpriv->s_InterruptParameters. + ui_Read + 1) % APCI1710_SAVE_INTERRUPT; + + break; + + default: + printk("ReadType Parameter wrong\n"); + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; + +} diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h deleted file mode 100644 index 358298b..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_16BIT_COUNTER 0x10 -#define APCI1710_32BIT_COUNTER 0x0 -#define APCI1710_QUADRUPLE_MODE 0x0 -#define APCI1710_DOUBLE_MODE 0x3 -#define APCI1710_SIMPLE_MODE 0xF -#define APCI1710_DIRECT_MODE 0x80 -#define APCI1710_HYSTERESIS_ON 0x60 -#define APCI1710_HYSTERESIS_OFF 0x0 -#define APCI1710_INCREMENT 0x60 -#define APCI1710_DECREMENT 0x0 -#define APCI1710_LATCH_COUNTER 0x1 -#define APCI1710_CLEAR_COUNTER 0x0 -#define APCI1710_LOW 0x0 -#define APCI1710_HIGH 0x1 - -/*********************/ -/* Version 0600-0229 */ -/*********************/ -#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0 -#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1 -#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2 -#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3 -#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4 -#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5 -#define APCI1710_SOURCE_0 0x0 -#define APCI1710_SOURCE_1 0x1 - -#define APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_ENABLE_LATCH_INT 0x80 -#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT) - -#define APCI1710_INDEX_LATCH_COUNTER 0x10 -#define APCI1710_INDEX_AUTO_MODE 0x8 -#define APCI1710_ENABLE_INDEX 0x4 -#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX) -#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8 -#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR) -#define APCI1710_SET_LOW_INDEX_LEVEL 0x4 -#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL) -#define APCI1710_INVERT_INDEX_RFERENCE 0x2 -#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE) - -#define APCI1710_ENABLE_INDEX_INT 0x1 -#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT) - -#define APCI1710_ENABLE_FREQUENCY 0x4 -#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY) - -#define APCI1710_ENABLE_FREQUENCY_INT 0x8 -#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT) - -#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40 -#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY) - -#define APCI1710_ENABLE_40MHZ_FILTER 0x80 -#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER) - -#define APCI1710_ENABLE_COMPARE_INT 0x2 -#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT) - -#define APCI1710_ENABLE_INDEX_ACTION 0x20 -#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION) -#define APCI1710_REFERENCE_HIGH 0x40 -#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH) - -#define APCI1710_TOR_GATE_LOW 0x40 -#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW) - -/* INSN CONFIG */ -#define APCI1710_INCCPT_INITCOUNTER 100 -#define APCI1710_INCCPT_COUNTERAUTOTEST 101 -#define APCI1710_INCCPT_INITINDEX 102 -#define APCI1710_INCCPT_INITREFERENCE 103 -#define APCI1710_INCCPT_INITEXTERNALSTROBE 104 -#define APCI1710_INCCPT_INITCOMPARELOGIC 105 -#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106 - -/* INSN READ */ -#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200 -#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201 -#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202 -#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203 -#define APCI1710_INCCPT_GETINDEXSTATUS 204 -#define APCI1710_INCCPT_GETREFERENCESTATUS 205 -#define APCI1710_INCCPT_GETUASSTATUS 206 -#define APCI1710_INCCPT_GETCBSTATUS 207 -#define APCI1710_INCCPT_GET16BITCBSTATUS 208 -#define APCI1710_INCCPT_GETUDSTATUS 209 -#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210 -#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211 -#define APCI1710_INCCPT_READINTERRUPT 212 - -/* INSN BITS */ -#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300 -#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301 -#define APCI1710_INCCPT_SETINPUTFILTER 302 -#define APCI1710_INCCPT_LATCHCOUNTER 303 -#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304 -#define APCI1710_INCCPT_SETDIGITALCHLON 305 -#define APCI1710_INCCPT_SETDIGITALCHLOFF 306 - -/* INSN WRITE */ -#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400 -#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401 -#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402 -#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403 -#define APCI1710_INCCPT_ENABLEINDEX 404 -#define APCI1710_INCCPT_DISABLEINDEX 405 -#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406 -#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407 -#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408 -#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409 - -/************ Main Functions *************/ -int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int * data); - -int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice * s, - struct comedi_insn *insn, unsigned int * data); - -int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice * s, - struct comedi_insn *insn, unsigned int * data); - -int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice * s, - struct comedi_insn *insn, unsigned int * data); - -/*********** Supplementary Functions********/ - -/* INSN CONFIG */ -int i_APCI1710_InitCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_CounterRange, - unsigned char b_FirstCounterModus, - unsigned char b_FirstCounterOption, - unsigned char b_SecondCounterModus, - unsigned char b_SecondCounterOption); - -int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char * pb_TestStatus); - -int i_APCI1710_InitIndex(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_ReferenceAction, - unsigned char b_IndexOperation, unsigned char b_AutoMode, - unsigned char b_InterruptEnable); - -int i_APCI1710_InitReference(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ReferenceLevel); - -int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ExternalStrobe, - unsigned char b_ExternalStrobeLevel); - -int i_APCI1710_InitCompareLogic(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ui_CompareValue); - -int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PCIInputClock, - unsigned char b_TimingUnity, - unsigned int ul_TimingInterval, - unsigned int *pul_RealTimingInterval); - -/* INSN BITS */ -int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev); - -int i_APCI1710_SetInputFilter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_PCIInputClock, - unsigned char b_Filter); - -int i_APCI1710_LatchCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg); - -int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_SourceSelection); - -int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_ModulNbr); - -/* INSN WRITE */ -int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, - unsigned int ui_WriteValue); - -int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ul_WriteValue); - -int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_InterruptEnable); - -int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr); - -/* INSN READ */ -int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, - unsigned char *pb_LatchStatus); - -int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, - unsigned int *pul_LatchValue); - -int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, - unsigned int *pui_CounterValue); - -int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int *pul_CounterValue); - -int i_APCI1710_GetIndexStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_IndexStatus); - -int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ReferenceStatus); - -int i_APCI1710_GetUASStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UASStatus); - -int i_APCI1710_GetCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatus); - -int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatusCounter0, - unsigned char *pb_CBStatusCounter1); - -int i_APCI1710_GetUDStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus); - -int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus); - -int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char *pb_Status, unsigned char *pb_UDStatus, - unsigned int *pul_ReadValue); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c index 3f9cfa2..be0c6ad 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c @@ -49,13 +49,11 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_SINGLE 0 +#define APCI1710_CONTINUOUS 1 -#include "APCI1710_Inp_cpt.h" +#define APCI1710_PULSEENCODER_READ 0 +#define APCI1710_PULSEENCODER_WRITE 1 /* +----------------------------------------------------------------------------+ @@ -123,12 +121,14 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_IntRegister; - unsigned char b_ModulNbr; unsigned char b_PulseEncoderNbr; unsigned char b_InputLevelSelection; @@ -414,9 +414,12 @@ int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr; unsigned char b_PulseEncoderNbr; @@ -708,9 +711,12 @@ int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, unsigned char *_ pb_Status) */ -int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusRegister; unsigned char b_ModulNbr; @@ -834,9 +840,12 @@ int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, return i_ReturnValue; } -int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; data[0] = devpriv->s_InterruptParameters. s_FIFOInterruptParameters[devpriv-> diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h deleted file mode 100644 index 31fbb0b..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_SINGLE 0 -#define APCI1710_CONTINUOUS 1 - -#define APCI1710_PULSEENCODER_READ 0 -#define APCI1710_PULSEENCODER_WRITE 1 - -int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -/* - * READ PULSE ENCODER FUNCTIONS - */ -int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -/* - * WRITE PULSE ENCODER FUNCTIONS - */ -int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c index 8883e66..a211e78 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c @@ -47,72 +47,16 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ - -#include "APCI1710_Pwm.h" - -/* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev, -struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Pwm Init and Get Pwm Initialisation | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 -int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned char b_ConfigType; - int i_ReturnValue = 0; - b_ConfigType = CR_CHAN(insn->chanspec); +#define APCI1710_PWM_INIT 0 +#define APCI1710_PWM_GETINITDATA 1 - switch (b_ConfigType) { - case APCI1710_PWM_INIT: - i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ - (unsigned char) data[0], /* b_PWM */ - (unsigned char) data[1], /* b_ClockSelection */ - (unsigned char) data[2], /* b_TimingUnit */ - (unsigned int) data[3], /* ul_LowTiming */ - (unsigned int) data[4], /* ul_HighTiming */ - (unsigned int *) &data[0], /* pul_RealLowTiming */ - (unsigned int *) &data[1] /* pul_RealHighTiming */ - ); - break; - - case APCI1710_PWM_GETINITDATA: - i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ - (unsigned char) data[0], /* b_PWM */ - (unsigned char *) &data[0], /* pb_TimingUnit */ - (unsigned int *) &data[1], /* pul_LowTiming */ - (unsigned int *) &data[2], /* pul_HighTiming */ - (unsigned char *) &data[3], /* pb_StartLevel */ - (unsigned char *) &data[4], /* pb_StopMode */ - (unsigned char *) &data[5], /* pb_StopLevel */ - (unsigned char *) &data[6], /* pb_ExternGate */ - (unsigned char *) &data[7], /* pb_InterruptEnable */ - (unsigned char *) &data[8] /* pb_Enable */ - ); - break; - - default: - printk(" Config Parameter Wrong\n"); - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; -} +#define APCI1710_PWM_DISABLE 0 +#define APCI1710_PWM_ENABLE 1 +#define APCI1710_PWM_NEWTIMING 2 /* +----------------------------------------------------------------------------+ @@ -178,16 +122,17 @@ int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice | this board | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitPWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_ClockSelection, - unsigned char b_TimingUnit, - unsigned int ul_LowTiming, - unsigned int ul_HighTiming, - unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming) +static int i_APCI1710_InitPWM(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char b_ClockSelection, + unsigned char b_TimingUnit, + unsigned int ul_LowTiming, + unsigned int ul_HighTiming, + unsigned int *pul_RealLowTiming, + unsigned int *pul_RealHighTiming) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_LowTimerValue = 0; unsigned int ul_HighTimerValue = 0; @@ -1533,18 +1478,20 @@ int i_APCI1710_InitPWM(struct comedi_device *dev, | "i_APCI1710_InitPWM" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char *pb_TimingUnit, - unsigned int *pul_LowTiming, - unsigned int *pul_HighTiming, - unsigned char *pb_StartLevel, - unsigned char *pb_StopMode, - unsigned char *pb_StopLevel, - unsigned char *pb_ExternGate, unsigned char *pb_InterruptEnable, unsigned char *pb_Enable) +static int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char *pb_TimingUnit, + unsigned int *pul_LowTiming, + unsigned int *pul_HighTiming, + unsigned char *pb_StartLevel, + unsigned char *pb_StopMode, + unsigned char *pb_StopLevel, + unsigned char *pb_ExternGate, + unsigned char *pb_InterruptEnable, + unsigned char *pb_Enable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_Command; @@ -1669,51 +1616,47 @@ int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, } /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnWritePWM(struct comedi_device *dev, -struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Pwm Enable Disable and Set New Timing | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Pwm Init and Get Pwm Initialisation + */ +static int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned char b_WriteType; + unsigned char b_ConfigType; int i_ReturnValue = 0; - b_WriteType = CR_CHAN(insn->chanspec); - - switch (b_WriteType) { - case APCI1710_PWM_ENABLE: - i_ReturnValue = i_APCI1710_EnablePWM(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], - (unsigned char) data[2], - (unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]); - break; + b_ConfigType = CR_CHAN(insn->chanspec); - case APCI1710_PWM_DISABLE: - i_ReturnValue = i_APCI1710_DisablePWM(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + switch (b_ConfigType) { + case APCI1710_PWM_INIT: + i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ + (unsigned char) data[0], /* b_PWM */ + (unsigned char) data[1], /* b_ClockSelection */ + (unsigned char) data[2], /* b_TimingUnit */ + (unsigned int) data[3], /* ul_LowTiming */ + (unsigned int) data[4], /* ul_HighTiming */ + (unsigned int *) &data[0], /* pul_RealLowTiming */ + (unsigned int *) &data[1] /* pul_RealHighTiming */ + ); break; - case APCI1710_PWM_NEWTIMING: - i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]); + case APCI1710_PWM_GETINITDATA: + i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ + (unsigned char) data[0], /* b_PWM */ + (unsigned char *) &data[0], /* pb_TimingUnit */ + (unsigned int *) &data[1], /* pul_LowTiming */ + (unsigned int *) &data[2], /* pul_HighTiming */ + (unsigned char *) &data[3], /* pb_StartLevel */ + (unsigned char *) &data[4], /* pb_StopMode */ + (unsigned char *) &data[5], /* pb_StopLevel */ + (unsigned char *) &data[6], /* pb_ExternGate */ + (unsigned char *) &data[7], /* pb_InterruptEnable */ + (unsigned char *) &data[8] /* pb_Enable */ + ); break; default: - printk("Write Config Parameter Wrong\n"); + printk(" Config Parameter Wrong\n"); } if (i_ReturnValue >= 0) @@ -1805,14 +1748,16 @@ int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice * | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnablePWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_StartLevel, - unsigned char b_StopMode, - unsigned char b_StopLevel, unsigned char b_ExternGate, unsigned char b_InterruptEnable) +static int i_APCI1710_EnablePWM(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char b_StartLevel, + unsigned char b_StopMode, + unsigned char b_StopLevel, + unsigned char b_ExternGate, + unsigned char b_InterruptEnable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_Command; @@ -2061,9 +2006,11 @@ int i_APCI1710_EnablePWM(struct comedi_device *dev, | "i_APCI1710_EnablePWM" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM) +static int i_APCI1710_DisablePWM(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; @@ -2188,11 +2135,14 @@ int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, u | -8: High base timing selection is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, unsigned char b_TimingUnit, unsigned int ul_LowTiming, unsigned int ul_HighTiming) +static int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char b_TimingUnit, + unsigned int ul_LowTiming, + unsigned int ul_HighTiming) { + struct addi_private *devpriv = dev->private; unsigned char b_ClockSelection; int i_ReturnValue = 0; unsigned int ul_LowTimerValue = 0; @@ -3415,6 +3365,49 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, } /* + * Pwm Enable Disable and Set New Timing + */ +static int i_APCI1710_InsnWritePWM(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned char b_WriteType; + int i_ReturnValue = 0; + b_WriteType = CR_CHAN(insn->chanspec); + + switch (b_WriteType) { + case APCI1710_PWM_ENABLE: + i_ReturnValue = i_APCI1710_EnablePWM(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], + (unsigned char) data[2], + (unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]); + break; + + case APCI1710_PWM_DISABLE: + i_ReturnValue = i_APCI1710_DisablePWM(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + break; + + case APCI1710_PWM_NEWTIMING: + i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]); + break; + + default: + printk("Write Config Parameter Wrong\n"); + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; +} + +/* +----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_GetPWMStatus | | (unsigned char_ b_BoardHandle, | @@ -3459,13 +3452,14 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, | -6: PWM not enabled see function "i_APCI1710_EnablePWM"| +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; - unsigned char b_ModulNbr; unsigned char b_PWM; unsigned char *pb_PWMOutputStatus; @@ -3561,9 +3555,13 @@ int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_sub return i_ReturnValue; } -int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + data[0] = devpriv->s_InterruptParameters. s_FIFOInterruptParameters[devpriv-> s_InterruptParameters.ui_Read].b_OldModuleMask; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h deleted file mode 100644 index d8ad0b9..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_PWM_INIT 0 -#define APCI1710_PWM_GETINITDATA 1 - -#define APCI1710_PWM_DISABLE 0 -#define APCI1710_PWM_ENABLE 1 -#define APCI1710_PWM_NEWTIMING 2 - -int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InitPWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_ClockSelection, - unsigned char b_TimingUnit, - unsigned int ul_LowTiming, - unsigned int ul_HighTiming, - unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming); - -int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char *pb_TimingUnit, - unsigned int *pul_LowTiming, - unsigned int *pul_HighTiming, - unsigned char *pb_StartLevel, - unsigned char *pb_StopMode, - unsigned char *pb_StopLevel, - unsigned char *pb_ExternGate, - unsigned char *pb_InterruptEnable, unsigned char *pb_Enable); - -int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_EnablePWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_StartLevel, - unsigned char b_StopMode, - unsigned char b_StopLevel, unsigned char b_ExternGate, - unsigned char b_InterruptEnable); - -int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, unsigned char b_TimingUnit, - unsigned int ul_LowTiming, unsigned int ul_HighTiming); - -int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM); - -int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c index c13b002..1e05732 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c @@ -40,13 +40,20 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 -#include "APCI1710_Ssi.h" +#define APCI1710_BINARY_MODE 0x1 +#define APCI1710_GRAY_MODE 0x0 + +#define APCI1710_SSI_READ1VALUE 1 +#define APCI1710_SSI_READALLVALUE 2 + +#define APCI1710_SSI_SET_CHANNELON 0 +#define APCI1710_SSI_SET_CHANNELOFF 1 +#define APCI1710_SSI_READ_1CHANNEL 2 +#define APCI1710_SSI_READ_ALLCHANNEL 3 /* +----------------------------------------------------------------------------+ @@ -119,9 +126,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ui_TimerValue; unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength, @@ -386,9 +396,12 @@ pul_Position = (unsigned int *) &data[0]; +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_Cpt; unsigned char b_Length; @@ -719,9 +732,12 @@ int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevi +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr; @@ -729,6 +745,7 @@ int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_sub unsigned char *pb_ChannelStatus; unsigned char *pb_InputStatus; unsigned char b_IOType; + i_ReturnValue = insn->n; b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); b_IOType = (unsigned char) data[0]; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h deleted file mode 100644 index ef4d887..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_BINARY_MODE 0x1 -#define APCI1710_GRAY_MODE 0x0 - -#define APCI1710_SSI_READ1VALUE 1 -#define APCI1710_SSI_READALLVALUE 2 - -#define APCI1710_SSI_SET_CHANNELON 0 -#define APCI1710_SSI_SET_CHANNELOFF 1 -#define APCI1710_SSI_READ_1CHANNEL 2 -#define APCI1710_SSI_READ_ALLCHANNEL 3 - -/* - * SSI INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c index 0e6affd..3bc9826 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c @@ -52,13 +52,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 -#include "APCI1710_Tor.h" +#define APCI1710_GATE_INPUT 10 + +#define APCI1710_TOR_SIMPLE_MODE 2 +#define APCI1710_TOR_DOUBLE_MODE 3 +#define APCI1710_TOR_QUADRUPLE_MODE 4 + +#define APCI1710_SINGLE 0 +#define APCI1710_CONTINUOUS 1 + +#define APCI1710_TOR_GETPROGRESSSTATUS 0 +#define APCI1710_TOR_GETCOUNTERVALUE 1 +#define APCI1710_TOR_READINTERRUPT 2 /* +----------------------------------------------------------------------------+ @@ -130,9 +139,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_TimerValue = 0; unsigned int dw_Command; @@ -987,9 +999,12 @@ int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_DummyRead; @@ -1460,9 +1475,12 @@ int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned char b_ModulNbr; @@ -1700,13 +1718,15 @@ int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_TimeOut = 0; - unsigned char b_ModulNbr; unsigned char b_TorCounter; unsigned char b_ReadType; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h deleted file mode 100644 index 537d475..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_GATE_INPUT 10 - -#define APCI1710_TOR_SIMPLE_MODE 2 -#define APCI1710_TOR_DOUBLE_MODE 3 -#define APCI1710_TOR_QUADRUPLE_MODE 4 - -#define APCI1710_SINGLE 0 -#define APCI1710_CONTINUOUS 1 - -#define APCI1710_TOR_GETPROGRESSSTATUS 0 -#define APCI1710_TOR_GETCOUNTERVALUE 1 -#define APCI1710_TOR_READINTERRUPT 2 - -/* - * TOR_COUNTER INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -/* - * TOR_COUNTER READ FUNCTION - */ -int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c index 9e177f4..c8238b8 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c @@ -52,13 +52,11 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_TTL_INIT 0 +#define APCI1710_TTL_INITDIRECTION 1 -#include "APCI1710_Ttl.h" +#define APCI1710_TTL_READCHANNEL 0 +#define APCI1710_TTL_READPORT 1 /* +----------------------------------------------------------------------------+ @@ -100,9 +98,12 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr; unsigned char b_InitType; @@ -406,9 +407,12 @@ APCI1710_TTL_READCHANNEL +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr; @@ -655,9 +659,12 @@ int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr; @@ -825,9 +832,12 @@ int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; unsigned char b_ModulNbr; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h deleted file mode 100644 index adcab82..0000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define APCI1710_TTL_INIT 0 -#define APCI1710_TTL_INITDIRECTION 1 - -#define APCI1710_TTL_READCHANNEL 0 -#define APCI1710_TTL_READPORT 1 - -/* - * TTL INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * TTL INPUT FUNCTION - */ -int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * TTL OUTPUT FUNCTIONS - */ -int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h deleted file mode 100644 index 95f7dc6..0000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ /dev/null @@ -1,469 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/* Header file for AMCC s 5933 */ - -#ifndef _AMCC_S5933_H_ -#define _AMCC_S5933_H_ - -#include "../../comedidev.h" - -/* written on base0 */ -#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 - -/* added for step 6 dma written on base2 */ -#define AMWEN_ENABLE 0x02 - -#define A2P_FIFO_WRITE_ENABLE 0x01 - -/* for transfer count enable bit */ -#define AGCSTS_TC_ENABLE 0x10000000 - -/* - * ADDON RELATED ADDITIONS - */ -/* Constant */ -#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00 -#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200 -#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L -#define APCI3120_AMWEN_ENABLE 0x02 -#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 -#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L -#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L -#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L -#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 -#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 -#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 - -/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ -#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C -#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2) -#define APCI3120_ADD_ON_MWAR_LOW 0x24 -#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2) -#define APCI3120_ADD_ON_MWTC_LOW 0x058 -#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2) - -/* AMCC */ -#define APCI3120_AMCC_OP_MCSR 0x3C -#define APCI3120_AMCC_OP_REG_INTCSR 0x38 - -/* - * 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 -/* int source */ -#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) -/* FIFO ctrl */ -#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) -#define AMCC_OP_REG_MCSR 0x3c -/* Data in byte 2 */ -#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) -/* Command in byte 3 */ -#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) - -#define AMCC_FIFO_DEPTH_DWORD 8 -#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32)) - -/* - * 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_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 - -/* 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 - -/****************************************************************************/ - -struct pcilst_struct { - struct pcilst_struct *next; - int used; - struct pci_dev *pcidev; - unsigned short vendor; - unsigned short device; - unsigned char pci_bus; - unsigned char pci_slot; - unsigned char pci_func; - resource_size_t io_addr[5]; - unsigned int irq; -}; - -/* ptr to root list of all amcc devices */ -static struct pcilst_struct *amcc_devices; - -static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 }; - -/****************************************************************************/ - -void v_pci_card_list_init(unsigned short pci_vendor, char display); -void v_pci_card_list_cleanup(unsigned short pci_vendor); -struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, - unsigned short - device_id); -int i_find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card); -struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - int i_Master); - -int pci_card_alloc(struct pcilst_struct *amcc, int master); -int i_pci_card_free(struct pcilst_struct *amcc); -void v_pci_card_list_display(void); -int i_pci_card_data(struct pcilst_struct *amcc, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, resource_size_t * io_addr, - unsigned int *irq); - -/****************************************************************************/ - -/* build list of amcc cards in this system */ -void v_pci_card_list_init(unsigned short pci_vendor, char display) -{ - struct pci_dev *pcidev = NULL; - struct pcilst_struct *amcc, *last; - int i; - int i_Count = 0; - amcc_devices = NULL; - last = NULL; - - for_each_pci_dev(pcidev) { - for (i_Count = 0; i_Count < 2; i_Count++) { - pci_vendor = i_ADDIDATADeviceID[i_Count]; - if (pcidev->vendor == pci_vendor) { - amcc = kzalloc(sizeof(*amcc), GFP_KERNEL); - if (amcc == NULL) - continue; - - amcc->pcidev = pcidev; - if (last) - last->next = amcc; - else - amcc_devices = amcc; - last = amcc; - - amcc->vendor = pcidev->vendor; - amcc->device = pcidev->device; - amcc->pci_bus = pcidev->bus->number; - amcc->pci_slot = PCI_SLOT(pcidev->devfn); - amcc->pci_func = PCI_FUNC(pcidev->devfn); - /* Note: resources may be invalid if PCI device - * not enabled, but they are corrected in - * pci_card_alloc. */ - for (i = 0; i < 5; i++) - amcc->io_addr[i] = - pci_resource_start(pcidev, i); - amcc->irq = pcidev->irq; - - } - } - } - - if (display) - v_pci_card_list_display(); -} - -/****************************************************************************/ -/* free up list of amcc cards in this system */ -void v_pci_card_list_cleanup(unsigned short pci_vendor) -{ - struct pcilst_struct *amcc, *next; - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - kfree(amcc); - } - - amcc_devices = NULL; -} - -/****************************************************************************/ -/* find first unused card with this device_id */ -struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, - unsigned short device_id) -{ - struct pcilst_struct *amcc, *next; - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - if ((!amcc->used) && (amcc->device == device_id) - && (amcc->vendor == vendor_id)) - return amcc; - - } - - return NULL; -} - -/****************************************************************************/ -/* find card on requested position */ -int i_find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card) -{ - struct pcilst_struct *amcc, *next; - - *card = NULL; - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - if ((amcc->vendor == vendor_id) && (amcc->device == device_id) - && (amcc->pci_bus == pci_bus) - && (amcc->pci_slot == pci_slot)) { - if (!(amcc->used)) { - *card = amcc; - return 0; /* ok, card is found */ - } else { - printk(" - \nCard on requested position is used b:s %d:%d!\n", - pci_bus, pci_slot); - return 2; /* card exist but is used */ - } - } - } - - /* no card found */ - return 1; -} - -/****************************************************************************/ -/* mark card as used */ -int pci_card_alloc(struct pcilst_struct *amcc, int master) -{ - int i; - - if (!amcc) - return -1; - - if (amcc->used) - return 1; - if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933")) - return -1; - /* Resources will be accurate now. */ - for (i = 0; i < 5; i++) - amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i); - if (master) - pci_set_master(amcc->pcidev); - amcc->used = 1; - - return 0; -} - -/****************************************************************************/ -/* mark card as free */ -int i_pci_card_free(struct pcilst_struct *amcc) -{ - if (!amcc) - return -1; - - if (!amcc->used) - return 1; - amcc->used = 0; - comedi_pci_disable(amcc->pcidev); - return 0; -} - -/****************************************************************************/ -/* display list of found cards */ -void v_pci_card_list_display(void) -{ - struct pcilst_struct *amcc, *next; - - printk(KERN_DEBUG "List of pci cards\n"); - printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n"); - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - printk - ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n", - amcc->pci_bus, amcc->pci_slot, amcc->pci_func, - amcc->vendor, amcc->device, - (unsigned long long)amcc->io_addr[0], - (unsigned long long)amcc->io_addr[2], amcc->irq, - amcc->used); - - } -} - -/****************************************************************************/ -/* return all card information for driver */ -int i_pci_card_data(struct pcilst_struct *amcc, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, resource_size_t * io_addr, - unsigned int *irq) -{ - int i; - - if (!amcc) - return -1; - *pci_bus = amcc->pci_bus; - *pci_slot = amcc->pci_slot; - *pci_func = amcc->pci_func; - for (i = 0; i < 5; i++) - io_addr[i] = amcc->io_addr[i]; - *irq = amcc->irq; - return 0; -} - -/****************************************************************************/ -/* select and alloc card */ -struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - int i_Master) -{ - struct pcilst_struct *card; - - if ((pci_bus < 1) & (pci_slot < 1)) { - /* use autodetection */ - card = ptr_find_free_pci_card_by_device(vendor_id, device_id); - if (card == NULL) { - printk(" - Unused card not found in system!\n"); - return NULL; - } - } else { - switch (i_find_free_pci_card_by_position(vendor_id, device_id, - pci_bus, pci_slot, - &card)) { - case 1: - printk(" - Card not found on requested position b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - case 2: - printk(" - Card on requested position is used b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - } - } - - if (pci_card_alloc(card, i_Master) != 0) { - printk(" - Can't allocate card!\n"); - return NULL; - - } - - return card; -} -#endif diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 99a96bd..90cc432 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -36,1518 +36,107 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ | Description : ADDI COMMON Main Module | +-----------------------------------------------------------------------+ - | CONFIG OPTIONS | - | option[0] - PCI bus number - if bus number and slot number are 0, | - | then driver search for first unused card | - | option[1] - PCI slot number | - | | - | option[2] = 0 - DMA ENABLE | - | = 1 - DMA DISABLE | - +----------+-----------+------------------------------------------------+ */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/timex.h> -#include <linux/timer.h> -#include <linux/pci.h> -#include <linux/gfp.h> -#include <linux/io.h> -#include "../../comedidev.h" -#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) -#include <asm/i387.h> -#endif -#include "../comedi_fc.h" - -#include "addi_common.h" -#include "addi_amcc_s5933.h" - -#ifndef ADDIDATA_DRIVER_NAME -#define ADDIDATA_DRIVER_NAME "addi_common" -#endif - -/* Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>"); */ -/* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */ -/* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */ - -#define devpriv ((struct addi_private *)dev->private) -#define this_board ((const struct addi_board *)dev->board_ptr) - -#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) -/* BYTE b_SaveFPUReg [94]; */ - -void fpu_begin(void) -{ - /* asm ("fstenv b_SaveFPUReg"); */ - kernel_fpu_begin(); -} - -void fpu_end(void) -{ - /* asm ("frstor b_SaveFPUReg"); */ - kernel_fpu_end(); -} -#endif - -#include "addi_eeprom.c" -#if (defined (CONFIG_APCI_3120) || defined (CONFIG_APCI_3001)) -#include "hwdrv_apci3120.c" -#endif -#ifdef CONFIG_APCI_1032 -#include "hwdrv_apci1032.c" -#endif -#ifdef CONFIG_APCI_1516 -#include "hwdrv_apci1516.c" -#endif -#ifdef CONFIG_APCI_2016 -#include "hwdrv_apci2016.c" -#endif -#ifdef CONFIG_APCI_2032 -#include "hwdrv_apci2032.c" -#endif -#ifdef CONFIG_APCI_2200 -#include "hwdrv_apci2200.c" -#endif -#ifdef CONFIG_APCI_1564 -#include "hwdrv_apci1564.c" -#endif -#ifdef CONFIG_APCI_1500 -#include "hwdrv_apci1500.c" -#endif -#ifdef CONFIG_APCI_3501 -#include "hwdrv_apci3501.c" -#endif -#ifdef CONFIG_APCI_035 -#include "hwdrv_apci035.c" -#endif -#if (defined (CONFIG_APCI_3200) || defined (CONFIG_APCI_3300)) -#include "hwdrv_apci3200.c" -#endif -#ifdef CONFIG_APCI_1710 -#include "hwdrv_APCI1710.c" -#endif -#ifdef CONFIG_APCI_16XX -#include "hwdrv_apci16xx.c" -#endif -#ifdef CONFIG_APCI_3XXX -#include "hwdrv_apci3xxx.c" -#endif - #ifndef COMEDI_SUBD_TTLIO #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { -#ifdef CONFIG_APCI_3120 - {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x818D)}, -#endif -#ifdef CONFIG_APCI_1032 - {PCI_DEVICE(APCI1032_BOARD_VENDOR_ID, 0x1003)}, -#endif -#ifdef CONFIG_APCI_1516 - {PCI_DEVICE(APCI1516_BOARD_VENDOR_ID, 0x1001)}, -#endif -#ifdef CONFIG_APCI_2016 - {PCI_DEVICE(APCI2016_BOARD_VENDOR_ID, 0x1002)}, -#endif -#ifdef CONFIG_APCI_2032 - {PCI_DEVICE(APCI2032_BOARD_VENDOR_ID, 0x1004)}, -#endif -#ifdef CONFIG_APCI_2200 - {PCI_DEVICE(APCI2200_BOARD_VENDOR_ID, 0x1005)}, -#endif -#ifdef CONFIG_APCI_1564 - {PCI_DEVICE(APCI1564_BOARD_VENDOR_ID, 0x1006)}, -#endif -#ifdef CONFIG_APCI_1500 - {PCI_DEVICE(APCI1500_BOARD_VENDOR_ID, 0x80fc)}, -#endif -#ifdef CONFIG_APCI_3001 - {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x828D)}, -#endif -#ifdef CONFIG_APCI_3501 - {PCI_DEVICE(APCI3501_BOARD_VENDOR_ID, 0x3001)}, -#endif -#ifdef CONFIG_APCI_035 - {PCI_DEVICE(APCI035_BOARD_VENDOR_ID, 0x0300)}, -#endif -#ifdef CONFIG_APCI_3200 - {PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3000)}, -#endif -#ifdef CONFIG_APCI_3300 - {PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3007)}, -#endif -#ifdef CONFIG_APCI_1710 - {PCI_DEVICE(APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID)}, -#endif -#ifdef CONFIG_APCI_16XX - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100A)}, -#endif -#ifdef CONFIG_APCI_3XXX - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300F)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300E)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301A)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301B)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301C)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301D)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301E)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301F)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024)}, -#endif - {0} -}; - -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); - -static const struct addi_board boardtypes[] = { -#ifdef CONFIG_APCI_3120 - { - .pc_DriverName = "apci3120", - .i_VendorId = APCI3120_BOARD_VENDOR_ID, - .i_DeviceId = 0x818D, - .i_IorangeBase0 = AMCC_OP_REG_SIZE, - .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, - .i_IorangeBase2 = 8, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 8, - .i_AiMaxdata = 0xffff, - .i_AoMaxdata = 0x3fff, - .pr_AiRangelist = &range_apci3120_ai, - .pr_AoRangelist = &range_apci3120_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, - .i_Dma = 1, - .i_Timer = 1, - .b_AvailableConvertUnit = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3120_Interrupt, - .reset = i_APCI3120_Reset, - .ai_config = i_APCI3120_InsnConfigAnalogInput, - .ai_read = i_APCI3120_InsnReadAnalogInput, - .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, - .ai_cmd = i_APCI3120_CommandAnalogInput, - .ai_cancel = i_APCI3120_StopCyclicAcquisition, - .ao_write = i_APCI3120_InsnWriteAnalogOutput, - .di_read = i_APCI3120_InsnReadDigitalInput, - .di_bits = i_APCI3120_InsnBitsDigitalInput, - .do_config = i_APCI3120_InsnConfigDigitalOutput, - .do_write = i_APCI3120_InsnWriteDigitalOutput, - .do_bits = i_APCI3120_InsnBitsDigitalOutput, - .timer_config = i_APCI3120_InsnConfigTimer, - .timer_write = i_APCI3120_InsnWriteTimer, - .timer_read = i_APCI3120_InsnReadTimer, - }, -#endif -#ifdef CONFIG_APCI_1032 - { - .pc_DriverName = "apci1032", - .i_VendorId = APCI1032_BOARD_VENDOR_ID, - .i_DeviceId = 0x1003, - .i_IorangeBase0 = 4, - .i_IorangeBase1 = APCI1032_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDiChannel = 32, - .interrupt = v_APCI1032_Interrupt, - .reset = i_APCI1032_Reset, - .di_config = i_APCI1032_ConfigDigitalInput, - .di_read = i_APCI1032_Read1DigitalInput, - .di_bits = i_APCI1032_ReadMoreDigitalInput, - }, -#endif -#ifdef CONFIG_APCI_1516 - { - .pc_DriverName = "apci1516", - .i_VendorId = APCI1516_BOARD_VENDOR_ID, - .i_DeviceId = 0x1001, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrDiChannel = 8, - .i_NbrDoChannel = 8, - .i_Timer = 1, - .reset = i_APCI1516_Reset, - .di_read = i_APCI1516_Read1DigitalInput, - .di_bits = i_APCI1516_ReadMoreDigitalInput, - .do_config = i_APCI1516_ConfigDigitalOutput, - .do_write = i_APCI1516_WriteDigitalOutput, - .do_bits = i_APCI1516_ReadDigitalOutput, - .timer_config = i_APCI1516_ConfigWatchdog, - .timer_write = i_APCI1516_StartStopWriteWatchdog, - .timer_read = i_APCI1516_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_2016 - { - .pc_DriverName = "apci2016", - .i_VendorId = APCI2016_BOARD_VENDOR_ID, - .i_DeviceId = 0x1002, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI2016_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrDoChannel = 16, - .i_Timer = 1, - .reset = i_APCI2016_Reset, - .do_config = i_APCI2016_ConfigDigitalOutput, - .do_write = i_APCI2016_WriteDigitalOutput, - .do_bits = i_APCI2016_BitsDigitalOutput, - .timer_config = i_APCI2016_ConfigWatchdog, - .timer_write = i_APCI2016_StartStopWriteWatchdog, - .timer_read = i_APCI2016_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_2032 - { - .pc_DriverName = "apci2032", - .i_VendorId = APCI2032_BOARD_VENDOR_ID, - .i_DeviceId = 0x1004, - .i_IorangeBase0 = 4, - .i_IorangeBase1 = APCI2032_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDoChannel = 32, - .i_DoMaxdata = 0xffffffff, - .i_Timer = 1, - .interrupt = v_APCI2032_Interrupt, - .reset = i_APCI2032_Reset, - .do_config = i_APCI2032_ConfigDigitalOutput, - .do_write = i_APCI2032_WriteDigitalOutput, - .do_bits = i_APCI2032_ReadDigitalOutput, - .do_read = i_APCI2032_ReadInterruptStatus, - .timer_config = i_APCI2032_ConfigWatchdog, - .timer_write = i_APCI2032_StartStopWriteWatchdog, - .timer_read = i_APCI2032_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_2200 - { - .pc_DriverName = "apci2200", - .i_VendorId = APCI2200_BOARD_VENDOR_ID, - .i_DeviceId = 0x1005, - .i_IorangeBase0 = 4, - .i_IorangeBase1 = APCI2200_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDiChannel = 8, - .i_NbrDoChannel = 16, - .i_Timer = 1, - .reset = i_APCI2200_Reset, - .di_read = i_APCI2200_Read1DigitalInput, - .di_bits = i_APCI2200_ReadMoreDigitalInput, - .do_config = i_APCI2200_ConfigDigitalOutput, - .do_write = i_APCI2200_WriteDigitalOutput, - .do_bits = i_APCI2200_ReadDigitalOutput, - .timer_config = i_APCI2200_ConfigWatchdog, - .timer_write = i_APCI2200_StartStopWriteWatchdog, - .timer_read = i_APCI2200_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_1564 - { - .pc_DriverName = "apci1564", - .i_VendorId = APCI1564_BOARD_VENDOR_ID, - .i_DeviceId = 0x1006, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1564_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDiChannel = 32, - .i_NbrDoChannel = 32, - .i_DoMaxdata = 0xffffffff, - .i_Timer = 1, - .interrupt = v_APCI1564_Interrupt, - .reset = i_APCI1564_Reset, - .di_config = i_APCI1564_ConfigDigitalInput, - .di_read = i_APCI1564_Read1DigitalInput, - .di_bits = i_APCI1564_ReadMoreDigitalInput, - .do_config = i_APCI1564_ConfigDigitalOutput, - .do_write = i_APCI1564_WriteDigitalOutput, - .do_bits = i_APCI1564_ReadDigitalOutput, - .do_read = i_APCI1564_ReadInterruptStatus, - .timer_config = i_APCI1564_ConfigTimerCounterWatchdog, - .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog, - .timer_read = i_APCI1564_ReadTimerCounterWatchdog, - }, -#endif -#ifdef CONFIG_APCI_1500 - { - .pc_DriverName = "apci1500", - .i_VendorId = APCI1500_BOARD_VENDOR_ID, - .i_DeviceId = 0x80fc, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, - .i_IorangeBase2 = 4, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrDiChannel = 16, - .i_NbrDoChannel = 16, - .i_DoMaxdata = 0xffff, - .i_Timer = 1, - .interrupt = v_APCI1500_Interrupt, - .reset = i_APCI1500_Reset, - .di_config = i_APCI1500_ConfigDigitalInputEvent, - .di_read = i_APCI1500_Initialisation, - .di_write = i_APCI1500_StartStopInputEvent, - .di_bits = i_APCI1500_ReadMoreDigitalInput, - .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt, - .do_write = i_APCI1500_WriteDigitalOutput, - .do_bits = i_APCI1500_ConfigureInterrupt, - .timer_config = i_APCI1500_ConfigCounterTimerWatchdog, - .timer_write = i_APCI1500_StartStopTriggerTimerCounterWatchdog, - .timer_read = i_APCI1500_ReadInterruptMask, - .timer_bits = i_APCI1500_ReadCounterTimerWatchdog, - }, -#endif -#ifdef CONFIG_APCI_3001 - { - .pc_DriverName = "apci3001", - .i_VendorId = APCI3120_BOARD_VENDOR_ID, - .i_DeviceId = 0x828D, - .i_IorangeBase0 = AMCC_OP_REG_SIZE, - .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, - .i_IorangeBase2 = 8, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xfff, - .pr_AiRangelist = &range_apci3120_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, - .i_Dma = 1, - .i_Timer = 1, - .b_AvailableConvertUnit = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3120_Interrupt, - .reset = i_APCI3120_Reset, - .ai_config = i_APCI3120_InsnConfigAnalogInput, - .ai_read = i_APCI3120_InsnReadAnalogInput, - .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, - .ai_cmd = i_APCI3120_CommandAnalogInput, - .ai_cancel = i_APCI3120_StopCyclicAcquisition, - .di_read = i_APCI3120_InsnReadDigitalInput, - .di_bits = i_APCI3120_InsnBitsDigitalInput, - .do_config = i_APCI3120_InsnConfigDigitalOutput, - .do_write = i_APCI3120_InsnWriteDigitalOutput, - .do_bits = i_APCI3120_InsnBitsDigitalOutput, - .timer_config = i_APCI3120_InsnConfigTimer, - .timer_write = i_APCI3120_InsnWriteTimer, - .timer_read = i_APCI3120_InsnReadTimer, - }, -#endif -#ifdef CONFIG_APCI_3501 - { - .pc_DriverName = "apci3501", - .i_VendorId = APCI3501_BOARD_VENDOR_ID, - .i_DeviceId = 0x3001, - .i_IorangeBase0 = 64, - .i_IorangeBase1 = APCI3501_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5933, - .i_AoMaxdata = 16383, - .pr_AoRangelist = &range_apci3501_ao, - .i_NbrDiChannel = 2, - .i_NbrDoChannel = 2, - .i_DoMaxdata = 0x3, - .i_Timer = 1, - .interrupt = v_APCI3501_Interrupt, - .reset = i_APCI3501_Reset, - .ao_config = i_APCI3501_ConfigAnalogOutput, - .ao_write = i_APCI3501_WriteAnalogOutput, - .di_bits = i_APCI3501_ReadDigitalInput, - .do_config = i_APCI3501_ConfigDigitalOutput, - .do_write = i_APCI3501_WriteDigitalOutput, - .do_bits = i_APCI3501_ReadDigitalOutput, - .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, - .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog, - .timer_read = i_APCI3501_ReadTimerCounterWatchdog, - }, -#endif -#ifdef CONFIG_APCI_035 - { - .pc_DriverName = "apci035", - .i_VendorId = APCI035_BOARD_VENDOR_ID, - .i_DeviceId = 0x0300, - .i_IorangeBase0 = 127, - .i_IorangeBase1 = APCI035_ADDRESS_RANGE, - .i_PCIEeprom = 1, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xff, - .pr_AiRangelist = &range_apci035_ai, - .i_Timer = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI035_Interrupt, - .reset = i_APCI035_Reset, - .ai_config = i_APCI035_ConfigAnalogInput, - .ai_read = i_APCI035_ReadAnalogInput, - .timer_config = i_APCI035_ConfigTimerWatchdog, - .timer_write = i_APCI035_StartStopWriteTimerWatchdog, - .timer_read = i_APCI035_ReadTimerWatchdog, - }, -#endif -#ifdef CONFIG_APCI_3200 - { - .pc_DriverName = "apci3200", - .i_VendorId = APCI3200_BOARD_VENDOR_ID, - .i_DeviceId = 0x3000, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 4, - .i_IorangeBase3 = 4, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3200_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3200_Interrupt, - .reset = i_APCI3200_Reset, - .ai_config = i_APCI3200_ConfigAnalogInput, - .ai_read = i_APCI3200_ReadAnalogInput, - .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, - .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, - .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, - .ai_cmd = i_APCI3200_CommandAnalogInput, - .ai_cancel = i_APCI3200_StopCyclicAcquisition, - .di_bits = i_APCI3200_ReadDigitalInput, - .do_config = i_APCI3200_ConfigDigitalOutput, - .do_write = i_APCI3200_WriteDigitalOutput, - .do_bits = i_APCI3200_ReadDigitalOutput, - }, -#endif -#ifdef CONFIG_APCI_3300 - /* Begin JK .20.10.2004 = APCI-3300 integration */ - { - .pc_DriverName = "apci3300", - .i_VendorId = APCI3200_BOARD_VENDOR_ID, - .i_DeviceId = 0x3007, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 4, - .i_IorangeBase3 = 4, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 8, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3300_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3200_Interrupt, - .reset = i_APCI3200_Reset, - .ai_config = i_APCI3200_ConfigAnalogInput, - .ai_read = i_APCI3200_ReadAnalogInput, - .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, - .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, - .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, - .ai_cmd = i_APCI3200_CommandAnalogInput, - .ai_cancel = i_APCI3200_StopCyclicAcquisition, - .di_bits = i_APCI3200_ReadDigitalInput, - .do_config = i_APCI3200_ConfigDigitalOutput, - .do_write = i_APCI3200_WriteDigitalOutput, - .do_bits = i_APCI3200_ReadDigitalOutput, - }, -#endif -#ifdef CONFIG_APCI_1710 - { - .pc_DriverName = "apci1710", - .i_VendorId = APCI1710_BOARD_VENDOR_ID, - .i_DeviceId = APCI1710_BOARD_DEVICE_ID, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 8, - .i_IorangeBase2 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .interrupt = v_APCI1710_Interrupt, - .reset = i_APCI1710_Reset, - }, -#endif -#ifdef CONFIG_APCI_16XX - { - .pc_DriverName = "apci1648", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1009, - .i_IorangeBase0 = 128, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrTTLChannel = 48, - .reset = i_APCI16XX_Reset, - .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, - .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, - .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, - }, { - .pc_DriverName = "apci1696", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x100A, - .i_IorangeBase0 = 128, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrTTLChannel = 96, - .reset = i_APCI16XX_Reset, - .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, - .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, - .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, - }, -#endif -#ifdef CONFIG_APCI_3XXX - { - .pc_DriverName = "apci3000-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3010, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3000-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300F, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3000-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300E, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3006-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3013, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3006-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3014, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3006-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3015, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3010-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3016, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3010-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3017, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3010-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3018, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3016-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3019, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3016-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301A, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3016-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301B, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3100-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301C, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3100-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301D, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3106-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301E, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3106-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301F, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3110-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3020, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3110-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3021, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3116-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3022, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3116-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3023, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3003", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300B, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 7, - .ui_MinAcquisitiontimeNs = 2500, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3002-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3002, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 16, - .i_AiChannelList = 16, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3002-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3003, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 8, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3002-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3004, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3500", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3024, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAoChannel = 4, - .i_AoMaxdata = 4095, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, -#endif -}; +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; -static struct comedi_driver driver_addi = { - .driver_name = ADDIDATA_DRIVER_NAME, - .module = THIS_MODULE, - .attach = i_ADDI_Attach, - .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), -}; + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 2 * w_Address); + data[0] = w_Data; -static int __devinit driver_addi_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &driver_addi); + return insn->n; } -static void __devexit driver_addi_pci_remove(struct pci_dev *dev) +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { - comedi_pci_auto_unconfig(dev); -} + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); -static struct pci_driver driver_addi_pci_driver = { - .id_table = addi_apci_tbl, - .probe = &driver_addi_pci_probe, - .remove = __devexit_p(&driver_addi_pci_remove) -}; + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} -static int __init driver_addi_init_module(void) +static int i_ADDI_Reset(struct comedi_device *dev) { - int retval; - - retval = comedi_driver_register(&driver_addi); - if (retval < 0) - return retval; + const struct addi_board *this_board = comedi_board(dev); - driver_addi_pci_driver.name = (char *)driver_addi.driver_name; - return pci_register_driver(&driver_addi_pci_driver); + this_board->reset(dev); + return 0; } -static void __exit driver_addi_cleanup_module(void) +static const void *addi_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - pci_unregister_driver(&driver_addi_pci_driver); - comedi_driver_unregister(&driver_addi); + const void *p = dev->driver->board_name; + const struct addi_board *this_board; + int i; + + for (i = 0; i < dev->driver->num_names; i++) { + this_board = p; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + p += dev->driver->offset; + } + return NULL; } -module_init(driver_addi_init_module); -module_exit(driver_addi_cleanup_module); - -/* -+----------------------------------------------------------------------------+ -| Function name :static int i_ADDI_Attach(struct comedi_device *dev, | -| struct comedi_devconfig *it) | -| | -+----------------------------------------------------------------------------+ -| Task :Detects the card. | -| Configure the driver for a particular board. | -| This function does all the initializations and memory | -| allocation of data structures for the driver. | -+----------------------------------------------------------------------------+ -| Input Parameters :struct comedi_device *dev | -| struct comedi_devconfig *it | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int addi_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct addi_board *this_board; + struct addi_private *devpriv; struct comedi_subdevice *s; - int ret, pages, i, n_subdevices; + int ret, n_subdevices; unsigned int dw_Dummy; - resource_size_t io_addr[5]; - unsigned int irq; - resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved; - struct pcilst_struct *card = NULL; - unsigned char pci_bus, pci_slot, pci_func; - int i_Dma = 0; - - ret = alloc_private(dev, sizeof(struct addi_private)); - if (ret < 0) - return -ENOMEM; - - if (!pci_list_builded) { - v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */ - pci_list_builded = 1; - } - /* printk("comedi%d: "ADDIDATA_DRIVER_NAME": board=%s",dev->minor,this_board->pc_DriverName); */ - - if ((this_board->i_Dma) && (it->options[2] == 0)) { - i_Dma = 1; - } - - card = ptr_select_and_alloc_pci_card(this_board->i_VendorId, - this_board->i_DeviceId, - it->options[0], - it->options[1], i_Dma); - - if (card == NULL) - return -EIO; - - devpriv->allocated = 1; - - if ((i_pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0], - &irq)) < 0) { - i_pci_card_free(card); - printk(" - Can't get AMCC data!\n"); - return -EIO; - } - - iobase_a = io_addr[0]; - iobase_main = io_addr[1]; - iobase_addon = io_addr[2]; - iobase_reserved = io_addr[3]; - printk("\nBus %d: Slot %d: Funct%d\nBase0: 0x%8llx\nBase1: 0x%8llx\nBase2: 0x%8llx\nBase3: 0x%8llx\n", pci_bus, pci_slot, pci_func, (unsigned long long)io_addr[0], (unsigned long long)io_addr[1], (unsigned long long)io_addr[2], (unsigned long long)io_addr[3]); - if ((this_board->pc_EepromChip == NULL) - || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - /************************************/ - /* Test if more that 1 address used */ - /************************************/ + this_board = addi_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; - if (this_board->i_IorangeBase1 != 0) { - dev->iobase = (unsigned long)iobase_main; /* DAQ base address... */ - } else { - dev->iobase = (unsigned long)iobase_a; /* DAQ base address... */ - } - - dev->board_name = this_board->pc_DriverName; - devpriv->amcc = card; - devpriv->iobase = (int) dev->iobase; - devpriv->i_IobaseAmcc = (int) iobase_a; /* AMCC base address... */ - devpriv->i_IobaseAddon = (int) iobase_addon; /* ADD ON base address.... */ - devpriv->i_IobaseReserved = (int) iobase_reserved; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + + if (!this_board->pc_EepromChip || + strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + /* board does not have an eeprom or is not ADDIDATA_9054 */ + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); } else { - dev->board_name = this_board->pc_DriverName; - dev->iobase = (unsigned long)io_addr[2]; - devpriv->amcc = card; - devpriv->iobase = (int) io_addr[2]; - devpriv->i_IobaseReserved = (int) io_addr[3]; - printk("\nioremap begin"); - devpriv->dw_AiBase = ioremap(io_addr[3], + /* board has an ADDIDATA_9054 eeprom */ + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->iobase = pci_resource_start(pcidev, 2); + devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), this_board->i_IorangeBase3); - printk("\nioremap end"); } + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; @@ -1566,30 +155,19 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) /* ## */ - if (irq > 0) { - if (request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED, - this_board->pc_DriverName, dev) < 0) { - printk(", unable to allocate IRQ %u, DISABLING IT", - irq); - irq = 0; /* Can't use IRQ */ - } else { - printk("\nirq=%u", irq); - } - } else { - printk(", IRQ disabled"); + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; } - printk("\nOption %d %d %d\n", it->options[0], it->options[1], - it->options[2]); - dev->irq = irq; - /* Read eepeom and fill addi_board Structure */ if (this_board->i_PCIEeprom) { - printk("\nPCI Eeprom used"); if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { /* Set 3 wait stait */ - if (!(strcmp(this_board->pc_DriverName, "apci035"))) { + if (!(strcmp(dev->board_name, "apci035"))) { outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); } else { outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); @@ -1597,340 +175,174 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Enable the interrupt for the controller */ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - printk("\nEnable the interrupt for the controller"); } - printk("\nRead Eeprom"); - i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip, - dev); - } else { - printk("\nPCI Eeprom unused"); - } - - if (it->options[2] > 0) { - devpriv->us_UseDma = ADDI_DISABLE; - } else { - devpriv->us_UseDma = ADDI_ENABLE; + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); } - if (devpriv->s_EeParameters.i_Dma) { - printk("\nDMA used"); - if (devpriv->us_UseDma == ADDI_ENABLE) { - /* alloc DMA buffers */ - devpriv->b_DmaDoubleBuffer = 0; - for (i = 0; i < 2; i++) { - for (pages = 4; pages >= 0; pages--) { - devpriv->ul_DmaBufferVirtual[i] = - (void *) __get_free_pages(GFP_KERNEL, pages); - - if (devpriv->ul_DmaBufferVirtual[i]) - break; - } - if (devpriv->ul_DmaBufferVirtual[i]) { - devpriv->ui_DmaBufferPages[i] = pages; - devpriv->ui_DmaBufferSize[i] = - PAGE_SIZE * pages; - devpriv->ui_DmaBufferSamples[i] = - devpriv-> - ui_DmaBufferSize[i] >> 1; - devpriv->ul_DmaBufferHw[i] = - virt_to_bus((void *)devpriv-> - ul_DmaBufferVirtual[i]); - } - } - if (!devpriv->ul_DmaBufferVirtual[0]) { - printk - (", Can't allocate DMA buffer, DMA disabled!"); - devpriv->us_UseDma = ADDI_DISABLE; - } - - if (devpriv->ul_DmaBufferVirtual[1]) { - devpriv->b_DmaDoubleBuffer = 1; - } - } - - if ((devpriv->us_UseDma == ADDI_ENABLE)) { - printk("\nDMA ENABLED\n"); + n_subdevices = 7; + ret = comedi_alloc_subdevices(dev, n_subdevices); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) { + s->n_chan = + devpriv->s_EeParameters.i_NbrAiChannel; + devpriv->b_SingelDiff = 0; } else { - printk("\nDMA DISABLED\n"); + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; } - } - - if (!strcmp(this_board->pc_DriverName, "apci1710")) { -#ifdef CONFIG_APCI_1710 - i_ADDI_AttachPCI1710(dev); - - /* save base address */ - devpriv->s_BoardInfos.ui_Address = io_addr[2]; -#endif - } else { - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret) - return ret; + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) { - s->n_chan = - devpriv->s_EeParameters.i_NbrAiChannel; - devpriv->b_SingelDiff = 0; - } else { - s->n_chan = this_board->i_NbrAiChannelDiff; - devpriv->b_SingelDiff = 1; - } - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - - /* Set the initialisation flag */ - devpriv->b_AiInitialisation = 1; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - s->range_table = this_board->pr_AoRangelist; - s->insn_config = this_board->ao_config; - s->insn_write = this_board->ao_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - s->io_bits = 0; /* all bits input */ - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - s->io_bits = 0xf; /* all bits output */ + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + } else { + s->type = COMEDI_SUBD_UNUSED; + } - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->range_table = this_board->pr_AoRangelist; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - if (this_board->i_NbrTTLChannel) { - s->type = COMEDI_SUBD_TTLIO; - s->subdev_flags = - SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrTTLChannel; - s->maxdata = 1; - s->io_bits = 0; /* all bits input */ - s->len_chanlist = this_board->i_NbrTTLChannel; - s->range_table = &range_digital; - s->insn_config = this_board->ttl_config; - s->insn_bits = this_board->ttl_bits; - s->insn_read = this_board->ttl_read; - s->insn_write = this_board->ttl_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + if (this_board->i_NbrTTLChannel) { + s->type = COMEDI_SUBD_TTLIO; + s->subdev_flags = + SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrTTLChannel; + s->maxdata = 1; + s->io_bits = 0; /* all bits input */ + s->len_chanlist = this_board->i_NbrTTLChannel; + s->range_table = &range_digital; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } - /* EEPROM */ - s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; } - printk("\ni_ADDI_Attach end\n"); i_ADDI_Reset(dev); - devpriv->b_ValidDriver = 1; return 0; } static void i_ADDI_Detach(struct comedi_device *dev) { - if (dev->private) { - if (devpriv->b_ValidDriver) + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct addi_private *devpriv = dev->private; + + if (devpriv) { + if (dev->iobase) i_ADDI_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if ((this_board->pc_EepromChip == NULL) || - (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - if (devpriv->allocated) - i_pci_card_free(devpriv->amcc); - if (devpriv->ul_DmaBufferVirtual[0]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[0], - devpriv->ui_DmaBufferPages[0]); - } - if (devpriv->ul_DmaBufferVirtual[1]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[1], - devpriv->ui_DmaBufferPages[1]); - } - } else { + if (devpriv->dw_AiBase) iounmap(devpriv->dw_AiBase); - if (devpriv->allocated) - i_pci_card_free(devpriv->amcc); - } - if (pci_list_builded) { - v_pci_card_list_cleanup(this_board->i_VendorId); - pci_list_builded = 0; - } } -} - -/* -+----------------------------------------------------------------------------+ -| Function name : static int i_ADDI_Reset(struct comedi_device *dev) | -| | -+----------------------------------------------------------------------------+ -| Task : Disables all interrupts, Resets digital output to low, | -| Set all analog output to low | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_ADDI_Reset(struct comedi_device *dev) -{ - - this_board->reset(dev); - return 0; -} - -/* Interrupt function */ -/* -+----------------------------------------------------------------------------+ -| Function name : | -|static void v_ADDI_Interrupt(int irq, void *d) | -| | -+----------------------------------------------------------------------------+ -| Task : Registerd interrupt routine | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - this_board->interrupt(irq, d); - return IRQ_RETVAL(1); -} - -/* EEPROM Read Function */ -/* -+----------------------------------------------------------------------------+ -| Function name : | -|INT i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,struct comedi_subdevice *s, - struct comedi_insn *insn,unsigned int *data) -| | -+----------------------------------------------------------------------------+ -| Task : Read 256 words from EEPROM | -| | -+----------------------------------------------------------------------------+ -| Input Parameters :(struct comedi_device *dev,struct comedi_subdevice *s, - struct comedi_insn *insn,unsigned int *data) | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned short w_Data; - unsigned short w_Address; - w_Address = CR_CHAN(insn->chanspec); /* address to be read as 0,1,2,3...255 */ - - w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 0x100 + (2 * w_Address)); - data[0] = w_Data; - /* multiplied by 2 bcozinput will be like 0,1,2...255 */ - return insn->n; - + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index b7bbb71..6d8b29f94 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -15,26 +15,8 @@ * any later version. */ -#include <linux/kernel.h> -#include <linux/module.h> #include <linux/sched.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/timex.h> -#include <linux/timer.h> -#include <linux/pci.h> -#include <linux/io.h> -#include <linux/kmod.h> -#include <linux/uaccess.h> -#include "../../comedidev.h" -#include "addi_amcc_s5933.h" - -#define ERROR -1 -#define SUCCESS 1 #define LOBYTE(W) (unsigned char)((W) & 0xFF) #define HIBYTE(W) (unsigned char)(((W) >> 8) & 0xFF) @@ -312,9 +294,6 @@ struct addi_private { int i_IobaseAddon; /* addon base address */ int i_IobaseReserved; void __iomem *dw_AiBase; - struct pcilst_struct *amcc; /* ptr too AMCC data */ - unsigned char allocated; /* we have blocked card */ - unsigned char b_ValidDriver; /* driver is ok */ unsigned char b_AiContinuous; /* we do unlimited AI */ unsigned char b_AiInitialisation; unsigned int ui_AiActualScan; /* how many scans we finished */ @@ -410,14 +389,3 @@ struct addi_private { /* Minimum Delay in Nano secs */ } s_EeParameters; }; - -static unsigned short pci_list_builded; /* set to 1 when list of card is known */ - -/* Function declarations */ -static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it); -static void i_ADDI_Detach(struct comedi_device *dev); -static int i_ADDI_Reset(struct comedi_device *dev); - -static irqreturn_t v_ADDI_Interrupt(int irq, void *d); -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 3a9339b..5124ac9 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -1,1162 +1,365 @@ -/** -@verbatim - -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 - -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. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ /* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-----------------------------------------------------------------------+ - | Project : ADDI DATA | Compiler : GCC | - | Modulname : addi_eeprom.c | Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-----------------------------------------------------------------------+ - | Description : ADDI EEPROM Module | - +-----------------------------------------------------------------------+ - | UPDATE'S | - +-----------------------------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ -#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ -#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ -#define EE76_CMD_LEN 13 /* bits in instructions */ -#define EE_READ 0x0180 /* 01 1000 0000 read instruction */ - -#define EEPROM_DIGITALINPUT 0 -#define EEPROM_DIGITALOUTPUT 1 -#define EEPROM_ANALOGINPUT 2 -#define EEPROM_ANALOGOUTPUT 3 -#define EEPROM_TIMER 4 -#define EEPROM_WATCHDOG 5 + * addi_eeprom.c - ADDI EEPROM Module + * 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 + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * You should also find the complete GPL in the COPYING file accompanying + * this source code. + */ + +#define NVRAM_USER_DATA_START 0x100 + +#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ +#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ +#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ + +#define EE93C76_CLK_BIT (1 << 0) +#define EE93C76_CS_BIT (1 << 1) +#define EE93C76_DOUT_BIT (1 << 2) +#define EE93C76_DIN_BIT (1 << 3) +#define EE93C76_READ_CMD (0x0180 << 4) +#define EE93C76_CMD_LEN 13 + +#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 str_Functionality { - unsigned char b_Type; - unsigned short w_Address; -}; - -struct str_MainHeader { - unsigned short w_HeaderSize; - unsigned char b_Nfunctions; - struct str_Functionality s_Functions[7]; -}; - -struct str_DigitalInputHeader { - unsigned short w_Nchannel; - unsigned char b_Interruptible; - unsigned short w_NinterruptLogic; -}; - -struct str_DigitalOutputHeader { - - unsigned short w_Nchannel; -}; - - -/* used for timer as well as watchdog */ - -struct str_TimerDetails { - - unsigned short w_HeaderSize; - unsigned char b_Resolution; - unsigned char b_Mode; /* in case of Watchdog it is functionality */ - unsigned short w_MinTiming; - unsigned char b_TimeBase; -}; - -struct str_TimerMainHeader { - - - unsigned short w_Ntimer; - struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */ -}; - - -struct str_AnalogOutputHeader { - unsigned short w_Nchannel; - unsigned char b_Resolution; -}; - -struct str_AnalogInputHeader { - unsigned short w_Nchannel; - unsigned short w_MinConvertTiming; - unsigned short w_MinDelayTiming; - unsigned char b_HasDma; - unsigned char b_Resolution; -}; - - - /*****************************************/ - /* Read Header Functions */ - /*****************************************/ - -int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, struct comedi_device *dev); - -int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalInputHeader *s_Header); - -int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalOutputHeader *s_Header); - -int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_TimerMainHeader *s_Header); - -int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogOutputHeader *s_Header); - -int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogInputHeader *s_Header); - - /******************************************/ - /* Eeprom Specific Functions */ - /******************************************/ -unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, - unsigned short w_EepromStartAddress); -void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); -void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue); -void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); -void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, - unsigned char b_DataLengthInBits); -void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value); - -/* -+----------------------------------------------------------------------------+ -| Function Name : unsigned short w_EepromReadWord | -| (unsigned short w_PCIBoardEepromAddress, | -| char * pc_PCIChipInformation, | -| unsigned short w_EepromStartAddress) | -+----------------------------------------------------------------------------+ -| Task : Read from eepromn a word | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| unsigned short w_EepromStartAddress : Selected eeprom address | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : Read word value from eeprom | -+----------------------------------------------------------------------------+ -*/ - -unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, - unsigned short w_EepromStartAddress) +static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) { - - unsigned char b_Counter = 0; - - unsigned char b_ReadByte = 0; - - unsigned char b_ReadLowByte = 0; - - unsigned char b_ReadHighByte = 0; - - unsigned char b_SelectedAddressLow = 0; - - unsigned char b_SelectedAddressHigh = 0; - - unsigned short w_ReadWord = 0; - - /**************************/ - - /* Test the PCI chip type */ - - /**************************/ - - if ((!strcmp(pc_PCIChipInformation, "S5920")) || - (!strcmp(pc_PCIChipInformation, "S5933"))) - { - - for (b_Counter = 0; b_Counter < 2; b_Counter++) - { - - b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */ - - b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */ - - /************************************/ - - /* Select the load low address mode */ - - /************************************/ - - outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F); - - /****************/ - - /* Wait on busy */ - - /****************/ - - v_EepromWaitBusy(w_PCIBoardEepromAddress); - - /************************/ - - /* Load the low address */ - - /************************/ - - outb(b_SelectedAddressLow, - w_PCIBoardEepromAddress + 0x3E); - - /****************/ - - /* Wait on busy */ - - /****************/ - - v_EepromWaitBusy(w_PCIBoardEepromAddress); - - /*************************************/ - - /* Select the load high address mode */ - - /*************************************/ - - outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F); - - /****************/ - - /* Wait on busy */ - - /****************/ - - v_EepromWaitBusy(w_PCIBoardEepromAddress); - - /*************************/ - - /* Load the high address */ - - /*************************/ - - outb(b_SelectedAddressHigh, - w_PCIBoardEepromAddress + 0x3E); - - /****************/ - - /* Wait on busy */ - - /****************/ - - v_EepromWaitBusy(w_PCIBoardEepromAddress); - - /************************/ - - /* Select the READ mode */ - - /************************/ - - outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F); - - /****************/ - - /* Wait on busy */ - - /****************/ - - v_EepromWaitBusy(w_PCIBoardEepromAddress); - - /*****************************/ - - /* Read data into the EEPROM */ - - /*****************************/ - - b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E); - - /****************/ - - /* Wait on busy */ - - /****************/ - - v_EepromWaitBusy(w_PCIBoardEepromAddress); - - /*********************************/ - - /* Select the upper address part */ - - /*********************************/ - - if (b_Counter == 0) - { - - b_ReadLowByte = b_ReadByte; - - } /* if(b_Counter==0) */ - - else - { - - b_ReadHighByte = b_ReadByte; - - } /* if(b_Counter==0) */ - - } /* for (b_Counter=0; b_Counter<2; b_Counter++) */ - - w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); - - } /* end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */ - - if (!strcmp(pc_PCIChipInformation, "93C76")) - { - - /*************************************/ - - /* Read 16 bit from the EEPROM 93C76 */ - - /*************************************/ - - v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress, - &w_ReadWord); - - } - - return w_ReadWord; - -} - -/* - -+----------------------------------------------------------------------------+ - -| Function Name : void v_EepromWaitBusy | - -| (unsigned short w_PCIBoardEepromAddress) | - -+----------------------------------------------------------------------------+ - -| Task : Wait the busy flag from PCI controller | - -+----------------------------------------------------------------------------+ - -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address | - -+----------------------------------------------------------------------------+ - -| Output Parameters : - | - -+----------------------------------------------------------------------------+ - -| Return Value : - | - -+----------------------------------------------------------------------------+ - -*/ - -void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) -{ - - unsigned char b_EepromBusy = 0; - - do - { - - /*************/ - - /* IMPORTANT */ - - /*************/ - - /************************************************************************/ - - /* An error has been written in the AMCC 5933 book at the page B-13 */ - - /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */ - - /* the operator register is AMCC_OP_REG_MCSR+3 */ - - /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */ - - /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */ - - /************************************************************************/ - - b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); - b_EepromBusy = b_EepromBusy & 0x80; - - } while (b_EepromBusy == 0x80); - -} - -/* - -+---------------------------------------------------------------------------------+ - -| Function Name : void v_EepromClock76(unsigned int dw_Address, | - -| unsigned int dw_RegisterValue) | - -+---------------------------------------------------------------------------------+ - -| Task : This function sends the clocking sequence to the EEPROM. | - -+---------------------------------------------------------------------------------+ - -| Input Parameters : unsigned int dw_Address : PCI eeprom base address | - -| unsigned int dw_RegisterValue : PCI eeprom register value to write.| - -+---------------------------------------------------------------------------------+ - -| Output Parameters : - | - -+---------------------------------------------------------------------------------+ - -| Return Value : - | - -+---------------------------------------------------------------------------------+ - -*/ - -void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) -{ - - /************************/ - - /* Set EEPROM clock Low */ - - /************************/ - - outl(dw_RegisterValue & 0x6, dw_Address); - - /***************/ - - /* Wait 0.1 ms */ - - /***************/ - + outl(val & ~EE93C76_CLK_BIT, iobase); udelay(100); - /*************************/ - - /* Set EEPROM clock High */ - - /*************************/ - - outl(dw_RegisterValue | 0x1, dw_Address); - - /***************/ - - /* Wait 0.1 ms */ - - /***************/ - + outl(val | EE93C76_CLK_BIT, iobase); udelay(100); - } -/* - -+---------------------------------------------------------------------------------+ - -| Function Name : void v_EepromSendCommand76(unsigned int dw_Address, | - -| unsigned int dw_EepromCommand, | - -| unsigned char b_DataLengthInBits) | - -+---------------------------------------------------------------------------------+ - -| Task : This function sends a Command to the EEPROM 93C76. | - -+---------------------------------------------------------------------------------+ - -| Input Parameters : unsigned int dw_Address : PCI eeprom base address | - -| unsigned int dw_EepromCommand : PCI eeprom command to write. | - -| unsigned char b_DataLengthInBits : PCI eeprom command data length. | - -+---------------------------------------------------------------------------------+ - -| Output Parameters : - | - -+---------------------------------------------------------------------------------+ - -| Return Value : - | - -+---------------------------------------------------------------------------------+ - -*/ - -void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, - unsigned char b_DataLengthInBits) +static unsigned int addi_eeprom_cmd_93c76(unsigned long iobase, + unsigned int cmd, + unsigned char len) { - - char c_BitPos = 0; - - unsigned int dw_RegisterValue = 0; - - /*****************************/ - - /* Enable EEPROM Chip Select */ - - /*****************************/ - - dw_RegisterValue = 0x2; - - /********************************************************************/ + unsigned int val = EE93C76_CS_BIT; + int i; /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - - /********************************************************************/ - - outl(dw_RegisterValue, dw_Address); - - /***************/ - - /* Wait 0.1 ms */ - - /***************/ - + outl(val, iobase); udelay(100); - /*******************************************/ - /* Send EEPROM command - one bit at a time */ - - /*******************************************/ - - for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) - { - - /**********************************/ - - /* Check if current bit is 0 or 1 */ - - /**********************************/ - - if (dw_EepromCommand & (1 << c_BitPos)) - { - - /***********/ - - /* Write 1 */ - - /***********/ - - dw_RegisterValue = dw_RegisterValue | 0x4; - - } - + for (i = (len - 1); i >= 0; i--) { + if (cmd & (1 << i)) + val |= EE93C76_DOUT_BIT; else - { - - /***********/ - - /* Write 0 */ - - /***********/ - - dw_RegisterValue = dw_RegisterValue & 0x3; - - } - - /*********************/ + val &= ~EE93C76_DOUT_BIT; /* Write the command */ - - /*********************/ - - outl(dw_RegisterValue, dw_Address); - - /***************/ - - /* Wait 0.1 ms */ - - /***************/ - + outl(val, iobase); udelay(100); - /****************************/ - - /* Trigger the EEPROM clock */ - - /****************************/ - - v_EepromClock76(dw_Address, dw_RegisterValue); - + addi_eeprom_clk_93c76(iobase, val); } - + return val; } -/* - -+---------------------------------------------------------------------------------+ - -| Function Name : void v_EepromCs76Read(unsigned int dw_Address, | - -| unsigned short w_offset, | - -| unsigned short * pw_Value) | - -+---------------------------------------------------------------------------------+ - -| Task : This function read a value from the EEPROM 93C76. | - -+---------------------------------------------------------------------------------+ - -| Input Parameters : unsigned int dw_Address : PCI eeprom base address | - -| unsigned short w_offset : Offset of the address to read | - -| unsigned short * pw_Value : PCI eeprom 16 bit read value. | - -+---------------------------------------------------------------------------------+ - -| Output Parameters : - | - -+---------------------------------------------------------------------------------+ - -| Return Value : - | - -+---------------------------------------------------------------------------------+ - -*/ - -void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value) +static unsigned short addi_eeprom_readw_93c76(unsigned long iobase, + unsigned short addr) { - - char c_BitPos = 0; - - unsigned int dw_RegisterValue = 0; - - unsigned int dw_RegisterValueRead = 0; - - /*************************************************/ + unsigned short val = 0; + unsigned int cmd; + unsigned int tmp; + int i; /* Send EEPROM read command and offset to EEPROM */ - - /*************************************************/ - - v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), - EE76_CMD_LEN); - - /*******************************/ - - /* Get the last register value */ - - /*******************************/ - - dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; - - /*****************************/ - - /* Set the 16-bit value of 0 */ - - /*****************************/ - - *pw_Value = 0; - - /************************/ + cmd = EE93C76_READ_CMD | (addr / 2); + cmd = addi_eeprom_cmd_93c76(iobase, cmd, EE93C76_CMD_LEN); /* Get the 16-bit value */ + for (i = 0; i < 16; i++) { + addi_eeprom_clk_93c76(iobase, cmd); - /************************/ - - for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) - { - - /****************************/ - - /* Trigger the EEPROM clock */ - - /****************************/ - - v_EepromClock76(dw_Address, dw_RegisterValue); - - /**********************/ - - /* Get the result bit */ - - /**********************/ - - dw_RegisterValueRead = inl(dw_Address); - - /***************/ - - /* Wait 0.1 ms */ - - /***************/ - + tmp = inl(iobase); udelay(100); - /***************************************/ - - /* Get bit value and shift into result */ - - /***************************************/ - - if (dw_RegisterValueRead & 0x8) - { - - /**********/ + val <<= 1; + if (tmp & EE93C76_DIN_BIT) + val |= 0x1; + } - /* Read 1 */ + /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ + outl(0, iobase); + udelay(100); - /**********/ + return val; +} - *pw_Value = (*pw_Value << 1) | 0x1; +static void addi_eeprom_nvram_wait(unsigned long iobase) +{ + unsigned char val; - } + do { + val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD); + } while (val & 0x80); +} +static unsigned short addi_eeprom_readw_nvram(unsigned long iobase, + unsigned short addr) +{ + unsigned short val = 0; + unsigned char tmp; + unsigned char i; + + for (i = 0; i < 2; i++) { + /* Load the low 8 bit address */ + outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD); + addi_eeprom_nvram_wait(iobase); + outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); + addi_eeprom_nvram_wait(iobase); + + /* Load the high 8 bit address */ + outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD); + addi_eeprom_nvram_wait(iobase); + outb(((addr + i) >> 8) & 0xff, + iobase + AMCC_OP_REG_MCSR_NVDATA); + addi_eeprom_nvram_wait(iobase); + + /* Read the eeprom data byte */ + outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); + addi_eeprom_nvram_wait(iobase); + tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); + addi_eeprom_nvram_wait(iobase); + + if (i == 0) + val |= tmp; else - { - - /**********/ - - /* Read 0 */ + val |= (tmp << 8); + } - /**********/ + return val; +} - *pw_Value = (*pw_Value << 1); +static unsigned short addi_eeprom_readw(unsigned long iobase, + char *type, + unsigned short addr) +{ + unsigned short val = 0; - } + /* Add the offset to the start of the user data */ + addr += NVRAM_USER_DATA_START; - } + if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) + val = addi_eeprom_readw_nvram(iobase, addr); - /*************************/ + if (!strcmp(type, "93C76")) + val = addi_eeprom_readw_93c76(iobase, addr); - /* Clear all EEPROM bits */ + return val; +} - /*************************/ +static void addi_eeprom_read_di_info(struct comedi_device *dev, + unsigned long iobase, + unsigned short addr) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; + unsigned short tmp; - dw_RegisterValue = 0x0; + /* Number of channels */ + tmp = addi_eeprom_readw(iobase, type, addr + 6); + devpriv->s_EeParameters.i_NbrDiChannel = tmp; - /********************************************************************/ + /* Interruptible or not */ + tmp = addi_eeprom_readw(iobase, type, addr + 8); + tmp = (tmp >> 7) & 0x01; - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ + /* How many interruptible logic */ + tmp = addi_eeprom_readw(iobase, type, addr + 10); +} - /********************************************************************/ +static void addi_eeprom_read_do_info(struct comedi_device *dev, + unsigned long iobase, + unsigned short addr) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; + unsigned short tmp; - outl(dw_RegisterValue, dw_Address); + /* Number of channels */ + tmp = addi_eeprom_readw(iobase, type, addr + 6); + devpriv->s_EeParameters.i_NbrDoChannel = tmp; - /***************/ + devpriv->s_EeParameters.i_DoMaxdata = 0xffffffff >> (32 - tmp); +} - /* Wait 0.1 ms */ +static void addi_eeprom_read_timer_info(struct comedi_device *dev, + unsigned long iobase, + unsigned short addr) +{ + struct addi_private *devpriv = dev->private; +#if 0 + const struct addi_board *this_board = comedi_board(dev); + char *type = this_board->pc_EepromChip; + unsigned short offset = 0; + unsigned short ntimers; + unsigned short tmp; + int i; + + /* Number of Timers */ + ntimers = addi_eeprom_readw(iobase, type, addr + 6); + + /* Read header size */ + for (i = 0; i < ntimers; i++) { + unsigned short size; + unsigned short res; + unsigned short mode; + unsigned short min_timing; + unsigned short timebase; + + size = addi_eeprom_readw(iobase, type, addr + 8 + offset + 0); + + /* Resolution / Mode */ + tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 2); + res = (tmp >> 10) & 0x3f; + mode = (tmp >> 4) & 0x3f; + + /* MinTiming / Timebase */ + tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 4); + min_timing = (tmp >> 6) & 0x3ff; + Timebase = tmp & 0x3f; + + offset += size; + } +#endif + /* Timer subdevice present */ + devpriv->s_EeParameters.i_Timer = 1; +} - /***************/ +static void addi_eeprom_read_ao_info(struct comedi_device *dev, + unsigned long iobase, + unsigned short addr) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; + unsigned short tmp; + + /* No of channels for 1st hard component */ + tmp = addi_eeprom_readw(iobase, type, addr + 10); + devpriv->s_EeParameters.i_NbrAoChannel = (tmp >> 4) & 0x3ff; + + /* Resolution for 1st hard component */ + tmp = addi_eeprom_readw(iobase, type, addr + 16); + tmp = (tmp >> 8) & 0xff; + devpriv->s_EeParameters.i_AoMaxdata = 0xfff >> (16 - tmp); +} - udelay(100); +static void addi_eeprom_read_ai_info(struct comedi_device *dev, + unsigned long iobase, + unsigned short addr) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; + unsigned short offset; + unsigned short tmp; + + /* No of channels for 1st hard component */ + tmp = addi_eeprom_readw(iobase, type, addr + 10); + devpriv->s_EeParameters.i_NbrAiChannel = (tmp >> 4) & 0x3ff; + if (!strcmp(this_board->pc_DriverName, "apci3200")) + devpriv->s_EeParameters.i_NbrAiChannel *= 4; + + tmp = addi_eeprom_readw(iobase, type, addr + 16); + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = tmp * 1000; + + tmp = addi_eeprom_readw(iobase, type, addr + 30); + devpriv->s_EeParameters.ui_MinDelaytimeNs = tmp * 1000; + + tmp = addi_eeprom_readw(iobase, type, addr + 20); + devpriv->s_EeParameters.i_Dma = (tmp >> 13) & 0x01; + + tmp = addi_eeprom_readw(iobase, type, addr + 72) & 0xff; + if (tmp) { /* > 0 */ + /* offset of first analog input single header */ + offset = 74 + (2 * tmp) + (10 * (1 + (tmp / 16))); + } else { /* = 0 */ + offset = 74; + } + /* Resolution */ + tmp = addi_eeprom_readw(iobase, type, addr + offset + 2) & 0x1f; + devpriv->s_EeParameters.i_AiMaxdata = 0xffff >> (16 - tmp); } - /******************************************/ - /* EEPROM HEADER READ FUNCTIONS */ - /******************************************/ - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, | -| char * pc_PCIChipInformation,struct comedi_device *dev) | -+----------------------------------------------------------------------------+ -| Task : Read from eeprom Main Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct comedi_device *dev : comedi device structure | -| pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ - -int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, struct comedi_device *dev) +static void addi_eeprom_read_info(struct comedi_device *dev, + unsigned long iobase) { - unsigned short w_Temp, i, w_Count = 0; - unsigned int ui_Temp; - struct str_MainHeader s_MainHeader; - struct str_DigitalInputHeader s_DigitalInputHeader; - struct str_DigitalOutputHeader s_DigitalOutputHeader; - /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ - struct str_AnalogOutputHeader s_AnalogOutputHeader; - struct str_AnalogInputHeader s_AnalogInputHeader; - - /* Read size */ - s_MainHeader.w_HeaderSize = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + 8); - - /* Read nbr of functionality */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + 10); - s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; + const struct addi_board *this_board = comedi_board(dev); + char *type = this_board->pc_EepromChip; + unsigned short size; + unsigned char nfuncs; + int i; + + size = addi_eeprom_readw(iobase, type, 8); + nfuncs = addi_eeprom_readw(iobase, type, 10) & 0xff; /* Read functionality details */ - for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { - /* Read Type */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + 12 + w_Count); - s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; - w_Count = w_Count + 2; - /* Read Address */ - s_MainHeader.s_Functions[i].w_Address = - w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + 12 + w_Count); - w_Count = w_Count + 2; - } + for (i = 0; i < nfuncs; i++) { + unsigned short offset = i * 4; + unsigned short addr; + unsigned char func; - /* Display main header info */ - for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { + func = addi_eeprom_readw(iobase, type, 12 + offset) & 0x3f; + addr = addi_eeprom_readw(iobase, type, 14 + offset); - switch (s_MainHeader.s_Functions[i].b_Type) { + switch (func) { case EEPROM_DIGITALINPUT: - i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - s_MainHeader.s_Functions[i].w_Address, - &s_DigitalInputHeader); - devpriv->s_EeParameters.i_NbrDiChannel = - s_DigitalInputHeader.w_Nchannel; + addi_eeprom_read_di_info(dev, iobase, addr); break; case EEPROM_DIGITALOUTPUT: - i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - s_MainHeader.s_Functions[i].w_Address, - &s_DigitalOutputHeader); - devpriv->s_EeParameters.i_NbrDoChannel = - s_DigitalOutputHeader.w_Nchannel; - ui_Temp = 0xffffffff; - devpriv->s_EeParameters.i_DoMaxdata = - ui_Temp >> (32 - - devpriv->s_EeParameters.i_NbrDoChannel); + addi_eeprom_read_do_info(dev, iobase, addr); break; case EEPROM_ANALOGINPUT: - i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - s_MainHeader.s_Functions[i].w_Address, - &s_AnalogInputHeader); - if (!(strcmp(this_board->pc_DriverName, "apci3200"))) - devpriv->s_EeParameters.i_NbrAiChannel = - s_AnalogInputHeader.w_Nchannel * 4; - else - devpriv->s_EeParameters.i_NbrAiChannel = - s_AnalogInputHeader.w_Nchannel; - devpriv->s_EeParameters.i_Dma = - s_AnalogInputHeader.b_HasDma; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - (unsigned int) s_AnalogInputHeader.w_MinConvertTiming * - 1000; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - (unsigned int) s_AnalogInputHeader.w_MinDelayTiming * - 1000; - ui_Temp = 0xffff; - devpriv->s_EeParameters.i_AiMaxdata = - ui_Temp >> (16 - - s_AnalogInputHeader.b_Resolution); + addi_eeprom_read_ai_info(dev, iobase, addr); break; case EEPROM_ANALOGOUTPUT: - i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - s_MainHeader.s_Functions[i].w_Address, - &s_AnalogOutputHeader); - devpriv->s_EeParameters.i_NbrAoChannel = - s_AnalogOutputHeader.w_Nchannel; - ui_Temp = 0xffff; - devpriv->s_EeParameters.i_AoMaxdata = - ui_Temp >> (16 - - s_AnalogOutputHeader.b_Resolution); + addi_eeprom_read_ao_info(dev, iobase, addr); break; case EEPROM_TIMER: - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; - break; - case EEPROM_WATCHDOG: - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; - break; - case EEPROM_TIMER_WATCHDOG_COUNTER: - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; + addi_eeprom_read_timer_info(dev, iobase, addr); break; } } - - return 0; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadDigitalInputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,struct str_DigitalInputHeader *s_Header) | -| | -+----------------------------------------------------------------------------+ -| Task : Read Digital Input Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_DigitalInputHeader *s_Header: Digita Input Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ -int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalInputHeader *s_Header) -{ - unsigned short w_Temp; - - /* read nbr of channels */ - s_Header->w_Nchannel = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); - - /* interruptible or not */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 8); - s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; - -/* How many interruptible logic */ - s_Header->w_NinterruptLogic = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 10); - - return 0; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadDigitalOutputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,struct str_DigitalOutputHeader *s_Header) | -| | -+----------------------------------------------------------------------------+ -| Task : Read Digital Output Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_DigitalOutputHeader *s_Header: Digital Output Header| -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ -int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalOutputHeader *s_Header) -{ -/* Read Nbr channels */ - s_Header->w_Nchannel = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); - return 0; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, | -| char *pc_PCIChipInformation,WORD w_Address, | -| struct str_TimerMainHeader *s_Header) | -+----------------------------------------------------------------------------+ -| Task : Read Timer or Watchdog Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_TimerMainHeader *s_Header: Timer Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ -int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_TimerMainHeader *s_Header) -{ - - unsigned short i, w_Size = 0, w_Temp; - -/* Read No of Timer */ - s_Header->w_Ntimer = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); -/* Read header size */ - - for (i = 0; i < s_Header->w_Ntimer; i++) { - s_Header->s_TimerDetails[i].w_HeaderSize = - w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 0); - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 2); - - /* Read Resolution */ - s_Header->s_TimerDetails[i].b_Resolution = - (unsigned char) (w_Temp >> 10) & 0x3F; - - /* Read Mode */ - s_Header->s_TimerDetails[i].b_Mode = - (unsigned char) (w_Temp >> 4) & 0x3F; - - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 4); - - /* Read MinTiming */ - s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; - - /* Read Timebase */ - s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F; - w_Size += s_Header->s_TimerDetails[i].w_HeaderSize; - } - - return 0; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadAnlogOutputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,str_AnalogOutputHeader *s_Header) | -+----------------------------------------------------------------------------+ -| Task : Read Nalog Output Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| str_AnalogOutputHeader *s_Header:Anlog Output Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ - -int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogOutputHeader *s_Header) -{ - unsigned short w_Temp; - /* No of channels for 1st hard component */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 10); - s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - /* Resolution for 1st hard component */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 16); - s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; - return 0; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadAnlogInputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,struct str_AnalogInputHeader *s_Header) | -+----------------------------------------------------------------------------+ -| Task : Read Nalog Output Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_AnalogInputHeader *s_Header:Anlog Input Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ - -/* Reads only for ONE hardware component */ -int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogInputHeader *s_Header) -{ - unsigned short w_Temp, w_Offset; - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 10); - s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - s_Header->w_MinConvertTiming = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 16); - s_Header->w_MinDelayTiming = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 30); - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 20); - s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ - - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */ - w_Temp = w_Temp & 0x00FF; - if (w_Temp) /* Y>0 */ - { - w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */ - w_Offset = w_Offset + 2; /* resolution */ - } else /* Y=0 */ - { - w_Offset = 74; - w_Offset = w_Offset + 2; /* resolution */ - } - -/* read Resolution */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + w_Offset); - s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ - - return 0; } diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index f9a8937..b05f850 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -44,7 +44,35 @@ You should also find the complete GPL in the COPYING file accompanying this sour | | | | +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_APCI1710.h" + +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */ +#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */ +#define COMEDI_SUBD_TOR 14 /* Tor counter */ +#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */ +#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */ +#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */ + +#define APCI1710_BOARD_NAME "apci1710" +#define APCI1710_BOARD_DEVICE_ID 0x818F +#define APCI1710_ADDRESS_RANGE 256 +#define APCI1710_CONFIG_ADDRESS_RANGE 8 +#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL +#define APCI1710_SSI_COUNTER 0x53490000UL +#define APCI1710_TTL_IO 0x544C0000UL +#define APCI1710_DIGITAL_IO 0x44490000UL +#define APCI1710_82X54_TIMER 0x49430000UL +#define APCI1710_CHRONOMETER 0x43480000UL +#define APCI1710_PULSE_ENCODER 0x495A0000UL +#define APCI1710_TOR_COUNTER 0x544F0000UL +#define APCI1710_PWM 0x50570000UL +#define APCI1710_ETM 0x45540000UL +#define APCI1710_CDA 0x43440000UL +#define APCI1710_DISABLE 0 +#define APCI1710_ENABLE 1 +#define APCI1710_SYNCHRONOUS_MODE 1 +#define APCI1710_ASYNCHRONOUS_MODE 0 + #include "APCI1710_Inp_cpt.c" #include "APCI1710_Ssi.c" @@ -56,7 +84,34 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include "APCI1710_Pwm.c" #include "APCI1710_INCCPT.c" -void i_ADDI_AttachPCI1710(struct comedi_device *dev) +static const struct comedi_lrange range_apci1710_ttl = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1) + } +}; + +static const struct comedi_lrange range_apci1710_ssi = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1) + } +}; + +static const struct comedi_lrange range_apci1710_inccpt = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1) + } +}; + +static void i_ADDI_AttachPCI1710(struct comedi_device *dev) { struct comedi_subdevice *s; int ret = 0; @@ -195,12 +250,9 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_bits = i_APCI1710_InsnBitsINCCPT; } -int i_APCI1710_Reset(struct comedi_device *dev); -void v_APCI1710_Interrupt(int irq, void *d); -/* for 1710 */ - -int i_APCI1710_Reset(struct comedi_device *dev) +static int i_APCI1710_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int ret; unsigned int dw_Dummy; @@ -247,9 +299,10 @@ int i_APCI1710_Reset(struct comedi_device *dev) +----------------------------------------------------------------------------+ */ -void v_APCI1710_Interrupt(int irq, void *d) +static void v_APCI1710_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned char b_ModuleCpt = 0; unsigned char b_InterruptFlag = 0; unsigned char b_PWMCpt = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h deleted file mode 100644 index 89c99eb..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */ -#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */ -#define COMEDI_SUBD_TOR 14 /* Tor counter */ -#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */ -#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */ -#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */ - -#define APCI1710_BOARD_NAME "apci1710" -#define APCI1710_BOARD_VENDOR_ID 0x10E8 -#define APCI1710_BOARD_DEVICE_ID 0x818F -#define APCI1710_ADDRESS_RANGE 256 -#define APCI1710_CONFIG_ADDRESS_RANGE 8 -#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL -#define APCI1710_SSI_COUNTER 0x53490000UL -#define APCI1710_TTL_IO 0x544C0000UL -#define APCI1710_DIGITAL_IO 0x44490000UL -#define APCI1710_82X54_TIMER 0x49430000UL -#define APCI1710_CHRONOMETER 0x43480000UL -#define APCI1710_PULSE_ENCODER 0x495A0000UL -#define APCI1710_TOR_COUNTER 0x544F0000UL -#define APCI1710_PWM 0x50570000UL -#define APCI1710_ETM 0x45540000UL -#define APCI1710_CDA 0x43440000UL -#define APCI1710_DISABLE 0 -#define APCI1710_ENABLE 1 -#define APCI1710_SYNCHRONOUS_MODE 1 -#define APCI1710_ASYNCHRONOUS_MODE 0 - -/* MODULE INFO STRUCTURE */ - -static const struct comedi_lrange range_apci1710_ttl = { 4, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1) - } -}; - -static const struct comedi_lrange range_apci1710_ssi = { 4, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1) - } -}; - -static const struct comedi_lrange range_apci1710_inccpt = { 4, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1) - } -}; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 5997b2f..3d66e48 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -46,12 +46,70 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci035.h" +/* Card Specific information */ +#define APCI035_ADDRESS_RANGE 255 + +/* Timer / Watchdog Related Defines */ +#define APCI035_TCW_SYNC_ENABLEDISABLE 0 +#define APCI035_TCW_RELOAD_VALUE 4 +#define APCI035_TCW_TIMEBASE 8 +#define APCI035_TCW_PROG 12 +#define APCI035_TCW_TRIG_STATUS 16 +#define APCI035_TCW_IRQ 20 +#define APCI035_TCW_WARN_TIMEVAL 24 +#define APCI035_TCW_WARN_TIMEBASE 28 + +#define ADDIDATA_TIMER 0 +/* #define ADDIDATA_WATCHDOG 1 */ + +#define APCI035_TW1 0 +#define APCI035_TW2 32 +#define APCI035_TW3 64 +#define APCI035_TW4 96 + +#define APCI035_AI_OFFSET 0 +#define APCI035_TEMP 128 +#define APCI035_ALR_SEQ 4 +#define APCI035_START_STOP_INDEX 8 +#define APCI035_ALR_START_STOP 12 +#define APCI035_ALR_IRQ 16 +#define APCI035_EOS 20 +#define APCI035_CHAN_NO 24 +#define APCI035_CHAN_VAL 28 +#define APCI035_CONV_TIME_TIME_BASE 36 +#define APCI035_RELOAD_CONV_TIME_VAL 32 +#define APCI035_DELAY_TIME_TIME_BASE 44 +#define APCI035_RELOAD_DELAY_TIME_VAL 40 +#define ENABLE_EXT_TRIG 1 +#define ENABLE_EXT_GATE 2 +#define ENABLE_EXT_TRIG_GATE 3 + +#define ANALOG_INPUT 0 +#define TEMPERATURE 1 +#define RESISTANCE 2 + +#define ADDIDATA_GREATER_THAN_TEST 0 +#define ADDIDATA_LESS_THAN_TEST 1 + +#define APCI035_MAXVOLT 2.5 + +#define ADDIDATA_UNIPOLAR 1 +#define ADDIDATA_BIPOLAR 2 + +/* ANALOG INPUT RANGE */ +static struct comedi_lrange range_apci035_ai = { + 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 int i_WatchdogNbr = 0; static int i_Temp = 0; static int i_Flag = 1; @@ -109,12 +167,16 @@ static int i_Flag = 1; | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Status = 0; unsigned int ui_Command = 0; unsigned int ui_Mode = 0; + i_Temp = 0; devpriv->tsk_Current = current; devpriv->b_TimerSelectMode = data[0]; @@ -278,11 +340,15 @@ int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Command = 0; int i_Count = 0; + if (data[0] == 1) { ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); @@ -393,10 +459,14 @@ int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Status = 0; /* Status register */ + i_WatchdogNbr = insn->unused[0]; /******************/ @@ -453,9 +523,13 @@ int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevi | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->tsk_Current = current; outl(0x200 | 0, devpriv->iobase + 128 + 0x4); outl(0, devpriv->iobase + 128 + 0); @@ -490,10 +564,14 @@ int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevi | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ReadAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_CommandRegister = 0; + /******************/ /* Set the start */ /******************/ @@ -525,9 +603,11 @@ int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice | | +----------------------------------------------------------------------------+ */ -int i_APCI035_Reset(struct comedi_device *dev) +static int i_APCI035_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int i_Count = 0; + for (i_Count = 1; i_Count <= 4; i_Count++) { i_WatchdogNbr = i_Count; outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); /* stop all timers */ @@ -557,11 +637,13 @@ int i_APCI035_Reset(struct comedi_device *dev) static void v_APCI035_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_StatusRegister1 = 0; unsigned int ui_StatusRegister2 = 0; unsigned int ui_ReadCommand = 0; unsigned int ui_ChannelNumber = 0; unsigned int ui_DigitalTemperature = 0; + if (i_Temp == 1) { i_WatchdogNbr = i_Flag; i_Flag = i_Flag + 1; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h deleted file mode 100644 index 3c700c7..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/* Card Specific information */ -#define APCI035_BOARD_VENDOR_ID 0x15B8 -#define APCI035_ADDRESS_RANGE 255 - -/* ANALOG INPUT RANGE */ -static struct comedi_lrange range_apci035_ai = { 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) - } -}; - -/* Timer / Watchdog Related Defines */ -#define APCI035_TCW_SYNC_ENABLEDISABLE 0 -#define APCI035_TCW_RELOAD_VALUE 4 -#define APCI035_TCW_TIMEBASE 8 -#define APCI035_TCW_PROG 12 -#define APCI035_TCW_TRIG_STATUS 16 -#define APCI035_TCW_IRQ 20 -#define APCI035_TCW_WARN_TIMEVAL 24 -#define APCI035_TCW_WARN_TIMEBASE 28 - -#define ADDIDATA_TIMER 0 -/* #define ADDIDATA_WATCHDOG 1 */ - -#define APCI035_TW1 0 -#define APCI035_TW2 32 -#define APCI035_TW3 64 -#define APCI035_TW4 96 - -#define APCI035_AI_OFFSET 0 -#define APCI035_TEMP 128 -#define APCI035_ALR_SEQ 4 -#define APCI035_START_STOP_INDEX 8 -#define APCI035_ALR_START_STOP 12 -#define APCI035_ALR_IRQ 16 -#define APCI035_EOS 20 -#define APCI035_CHAN_NO 24 -#define APCI035_CHAN_VAL 28 -#define APCI035_CONV_TIME_TIME_BASE 36 -#define APCI035_RELOAD_CONV_TIME_VAL 32 -#define APCI035_DELAY_TIME_TIME_BASE 44 -#define APCI035_RELOAD_DELAY_TIME_VAL 40 -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define APCI035_MAXVOLT 2.5 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -/* ADDIDATA Enable Disable */ -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* Hardware Layer functions for Apci035 */ - -/* TIMER */ -/* timer value is passed as u seconds */ -int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Temperature Related Defines (Analog Input Subdevice) */ - -int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt */ -static void v_APCI035_Interrupt(int irq, void *d); - -/* Reset functions */ -int i_APCI035_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c deleted file mode 100644 index bab7b61..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ /dev/null @@ -1,287 +0,0 @@ -/** -@verbatim - -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 - -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. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-1032 | Compiler : GCC | - | Module name : hwdrv_apci1032.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-1032 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci1032.h" -#include <linux/delay.h> - -static unsigned int ui_InterruptStatus; - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_ConfigDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures the digital input Subdevice | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -| data[0] : 1 Enable Digital Input Interrupt | -| 0 Disable Digital Input Interrupt | -| data[1] : 0 ADDIDATA Interrupt OR LOGIC | -| : 1 ADDIDATA Interrupt AND LOGIC | -| data[2] : Interrupt mask for the mode 1 | -| data[3] : Interrupt mask for the mode 2 | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_TmpValue; - - unsigned int ul_Command1 = 0; - unsigned int ul_Command2 = 0; - devpriv->tsk_Current = current; - - /*******************************/ - /* Set the digital input logic */ - /*******************************/ - if (data[0] == ADDIDATA_ENABLE) { - ul_Command1 = ul_Command1 | data[2]; - ul_Command2 = ul_Command2 | data[3]; - outl(ul_Command1, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); - outl(ul_Command2, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); - if (data[1] == ADDIDATA_OR) { - outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); - ui_TmpValue = - inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); - } /* if (data[1] == ADDIDATA_OR) */ - else - outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); - /* else if(data[1] == ADDIDATA_OR) */ - } /* if( data[0] == ADDIDATA_ENABLE) */ - else { - ul_Command1 = ul_Command1 & 0xFFFF0000; - ul_Command2 = ul_Command2 & 0xFFFF0000; - outl(ul_Command1, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); - outl(ul_Command2, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); - } /* else if ( data[0] == ADDIDATA_ENABLE) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_Channel : Channel number to read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; - ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel <= 31) { - ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); -/* -* since only 1 channel reqd to bring it to last bit it is rotated 8 -* +(chan - 1) times then ANDed with 1 for last bit. -*/ - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=31) */ - else { - /* comedi_error(dev," \n chan spec wrong\n"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=31) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To be Read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; - - ui_NoOfChannels = CR_CHAN(insn->chanspec); - if (data[1] == 0) { - *data = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 8: - ui_Mask = 255; - *data = (*data >> (8 * ui_PortValue)) & ui_Mask; - break; - case 16: - ui_Mask = 65535; - *data = (*data >> (16 * ui_PortValue)) & ui_Mask; - break; - case 31: - break; - default: - /* comedi_error(dev," \nchan spec wrong\n"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ - } /* if(data[1]==0) */ - else { - if (data[1] == 1) - *data = ui_InterruptStatus; - /* if(data[1]==1) */ - } /* else if(data[1]==0) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : static void v_APCI1032_Interrupt | -| (int irq , void *d) | -+----------------------------------------------------------------------------+ -| Task : Interrupt handler for the interruptible digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq : irq number | -| void *d : void pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static void v_APCI1032_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - - unsigned int ui_Temp; - /* disable the interrupt */ - ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); - outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE, - devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); - ui_InterruptStatus = - inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); - ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* enable the interrupt */ - return; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | | -+----------------------------------------------------------------------------+ -| Task :resets all the registers | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1032_Reset(struct comedi_device *dev) -{ - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* disable the interrupts */ - inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */ - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */ - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h deleted file mode 100644 index 7114acb..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/********* Definitions for APCI-1032 card *****/ - -#define APCI1032_BOARD_VENDOR_ID 0x15B8 -#define APCI1032_ADDRESS_RANGE 20 -/* DIGITAL INPUT DEFINE */ - -#define APCI1032_DIGITAL_IP 0 -#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4 -#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8 -#define APCI1032_DIGITAL_IP_IRQ 16 - -/* Digital Input IRQ Function Selection */ -#define ADDIDATA_OR 0 -#define ADDIDATA_AND 1 - -/* Digital Input Interrupt Status */ -#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12 - -/* Digital Input Interrupt Enable Disable. */ -#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4 -#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* Hardware Layer functions for Apci1032 */ - -/* -* DI for di read -*/ - -int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt functions..... */ - -static void v_APCI1032_Interrupt(int irq, void *d); -/* Reset */ -int i_APCI1032_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 62f421a..24c4c98 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -45,7 +45,105 @@ You should also find the complete GPL in the COPYING file accompanying this sour | | | | +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_apci1500.h" + +/********* Definitions for APCI-1500 card *****/ + +/* Card Specific information */ +#define APCI1500_ADDRESS_RANGE 4 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI1500_DIGITAL_OP 2 +#define APCI1500_DIGITAL_IP 0 +#define APCI1500_AND 2 +#define APCI1500_OR 4 +#define APCI1500_OR_PRIORITY 6 +#define APCI1500_CLK_SELECT 0 +#define COUNTER1 0 +#define COUNTER2 1 +#define COUNTER3 2 +#define APCI1500_COUNTER 0x20 +#define APCI1500_TIMER 0 +#define APCI1500_WATCHDOG 0 +#define APCI1500_SINGLE 0 +#define APCI1500_CONTINUOUS 0x80 +#define APCI1500_DISABLE 0 +#define APCI1500_ENABLE 1 +#define APCI1500_SOFTWARE_TRIGGER 0x4 +#define APCI1500_HARDWARE_TRIGGER 0x10 +#define APCI1500_SOFTWARE_GATE 0 +#define APCI1500_HARDWARE_GATE 0x8 +#define START 0 +#define STOP 1 +#define TRIGGER 2 + +/* + * Zillog I/O enumeration + */ +enum { + APCI1500_Z8536_PORT_C, + APCI1500_Z8536_PORT_B, + APCI1500_Z8536_PORT_A, + APCI1500_Z8536_CONTROL_REGISTER +}; + +/* + * Z8536 CIO Internal Address + */ +enum { + APCI1500_RW_MASTER_INTERRUPT_CONTROL, + APCI1500_RW_MASTER_CONFIGURATION_CONTROL, + APCI1500_RW_PORT_A_INTERRUPT_CONTROL, + APCI1500_RW_PORT_B_INTERRUPT_CONTROL, + APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR, + APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY, + APCI1500_RW_PORT_C_DATA_DIRECTION, + APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL, + + APCI1500_RW_PORT_A_COMMAND_AND_STATUS, + APCI1500_RW_PORT_B_COMMAND_AND_STATUS, + APCI1500_RW_CPT_TMR1_CMD_STATUS, + APCI1500_RW_CPT_TMR2_CMD_STATUS, + APCI1500_RW_CPT_TMR3_CMD_STATUS, + APCI1500_RW_PORT_A_DATA, + APCI1500_RW_PORT_B_DATA, + APCI1500_RW_PORT_C_DATA, + + APCI1500_R_CPT_TMR1_VALUE_HIGH, + APCI1500_R_CPT_TMR1_VALUE_LOW, + APCI1500_R_CPT_TMR2_VALUE_HIGH, + APCI1500_R_CPT_TMR2_VALUE_LOW, + APCI1500_R_CPT_TMR3_VALUE_HIGH, + APCI1500_R_CPT_TMR3_VALUE_LOW, + APCI1500_RW_CPT_TMR1_TIME_CST_HIGH, + APCI1500_RW_CPT_TMR1_TIME_CST_LOW, + APCI1500_RW_CPT_TMR2_TIME_CST_HIGH, + APCI1500_RW_CPT_TMR2_TIME_CST_LOW, + APCI1500_RW_CPT_TMR3_TIME_CST_HIGH, + APCI1500_RW_CPT_TMR3_TIME_CST_LOW, + APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION, + APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION, + APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION, + APCI1500_R_CURRENT_VECTOR, + + APCI1500_RW_PORT_A_SPECIFICATION, + APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION, + APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY, + APCI1500_RW_PORT_A_DATA_DIRECTION, + APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL, + APCI1500_RW_PORT_A_PATTERN_POLARITY, + APCI1500_RW_PORT_A_PATTERN_TRANSITION, + APCI1500_RW_PORT_A_PATTERN_MASK, + + APCI1500_RW_PORT_B_SPECIFICATION, + APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION, + APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY, + APCI1500_RW_PORT_B_DATA_DIRECTION, + APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL, + APCI1500_RW_PORT_B_PATTERN_POLARITY, + APCI1500_RW_PORT_B_PATTERN_TRANSITION, + APCI1500_RW_PORT_B_PATTERN_MASK +}; static int i_TimerCounter1Init = 0; static int i_TimerCounter2Init = 0; @@ -141,6 +239,7 @@ static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0; int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0; int i_PatternTransitionCount = 0, i_RegValue; @@ -525,8 +624,10 @@ static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_Event1InterruptStatus = 0, i_Event2InterruptStatus = 0, i_RegValue; + switch (data[0]) { case START: /*************************/ @@ -792,7 +893,9 @@ static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_DummyRead = 0; + /******************/ /* Software reset */ /******************/ @@ -939,82 +1042,15 @@ static int i_APCI1500_Initialisation(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1500_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To be Read | -| unsigned int *data : Data Pointer -| data[0] : 0 Read a single channel -| 1 read a port value -| data[1] : port value -+----------------------------------------------------------------------------+ -| Output Parameters : -- data[0] :The read status value -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1500_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_PortValue = data[1]; - unsigned int ui_Mask = 0; - unsigned int ui_Channel; - unsigned int ui_TmpValue = 0; - ui_Channel = CR_CHAN(insn->chanspec); + struct addi_private *devpriv = dev->private; - switch (data[0]) { - case 0: - if (ui_Channel <= 15) { - ui_TmpValue = - (unsigned int) inw(devpriv->i_IobaseAddon + - APCI1500_DIGITAL_IP); - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=15) */ - else { - printk("\nThe channel specification are in error\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=15) */ - break; - case 1: + data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP); - *data = (unsigned int) inw(devpriv->i_IobaseAddon + - APCI1500_DIGITAL_IP); - switch (ui_Channel) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 8: - ui_Mask = 255; - *data = (*data >> (8 * ui_PortValue)) & ui_Mask; - break; - case 15: - break; - - default: - printk("\nSpecified channel cannot be read \n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_Channel) */ - break; - default: - printk("\nThe specified functionality does not exist\n"); - return -EINVAL; - } /* switch(data[0]) */ return insn->n; } @@ -1051,6 +1087,8 @@ static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *de struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->b_OutputMemoryStatus = data[0]; return insn->n; } @@ -1079,9 +1117,9 @@ static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; static unsigned int ui_Temp = 0; unsigned int ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ if (!devpriv->b_OutputMemoryStatus) { @@ -1274,6 +1312,7 @@ static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_TimerCounterMode, i_MasterConfiguration; devpriv->tsk_Current = current; @@ -1875,6 +1914,7 @@ static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_CommandAndStatusValue; switch (data[0]) { @@ -2198,7 +2238,9 @@ static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_CommandAndStatusValue; + switch (data[0]) { case COUNTER1: /* Read counter/timer1 */ @@ -2421,9 +2463,11 @@ static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Status; int i_RegValue; int i_Constant; + devpriv->tsk_Current = current; outl(0x0, devpriv->i_IobaseAmcc + 0x38); if (data[0] == 1) { @@ -2597,6 +2641,7 @@ static void v_APCI1500_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_InterruptStatus = 0; int i_RegValue = 0; i_InterruptMask = 0; @@ -2840,7 +2885,9 @@ static void v_APCI1500_Interrupt(int irq, void *d) */ static int i_APCI1500_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int i_DummyRead = 0; + i_TimerCounter1Init = 0; i_TimerCounter2Init = 0; i_WatchdogCounter3Init = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h deleted file mode 100644 index 647f9eb..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/********* Definitions for APCI-1500 card *****/ - -/* Card Specific information */ -#define APCI1500_BOARD_VENDOR_ID 0x10e8 -#define APCI1500_ADDRESS_RANGE 4 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI1500_DIGITAL_OP 2 -#define APCI1500_DIGITAL_IP 0 -#define APCI1500_AND 2 -#define APCI1500_OR 4 -#define APCI1500_OR_PRIORITY 6 -#define APCI1500_CLK_SELECT 0 -#define COUNTER1 0 -#define COUNTER2 1 -#define COUNTER3 2 -#define APCI1500_COUNTER 0x20 -#define APCI1500_TIMER 0 -#define APCI1500_WATCHDOG 0 -#define APCI1500_SINGLE 0 -#define APCI1500_CONTINUOUS 0x80 -#define APCI1500_DISABLE 0 -#define APCI1500_ENABLE 1 -#define APCI1500_SOFTWARE_TRIGGER 0x4 -#define APCI1500_HARDWARE_TRIGGER 0x10 -#define APCI1500_SOFTWARE_GATE 0 -#define APCI1500_HARDWARE_GATE 0x8 -#define START 0 -#define STOP 1 -#define TRIGGER 2 - -/* - * Zillog I/O enumeration - */ -enum { - APCI1500_Z8536_PORT_C, - APCI1500_Z8536_PORT_B, - APCI1500_Z8536_PORT_A, - APCI1500_Z8536_CONTROL_REGISTER -}; - -/* - * Z8536 CIO Internal Address - */ -enum { - APCI1500_RW_MASTER_INTERRUPT_CONTROL, - APCI1500_RW_MASTER_CONFIGURATION_CONTROL, - APCI1500_RW_PORT_A_INTERRUPT_CONTROL, - APCI1500_RW_PORT_B_INTERRUPT_CONTROL, - APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR, - APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY, - APCI1500_RW_PORT_C_DATA_DIRECTION, - APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL, - - APCI1500_RW_PORT_A_COMMAND_AND_STATUS, - APCI1500_RW_PORT_B_COMMAND_AND_STATUS, - APCI1500_RW_CPT_TMR1_CMD_STATUS, - APCI1500_RW_CPT_TMR2_CMD_STATUS, - APCI1500_RW_CPT_TMR3_CMD_STATUS, - APCI1500_RW_PORT_A_DATA, - APCI1500_RW_PORT_B_DATA, - APCI1500_RW_PORT_C_DATA, - - APCI1500_R_CPT_TMR1_VALUE_HIGH, - APCI1500_R_CPT_TMR1_VALUE_LOW, - APCI1500_R_CPT_TMR2_VALUE_HIGH, - APCI1500_R_CPT_TMR2_VALUE_LOW, - APCI1500_R_CPT_TMR3_VALUE_HIGH, - APCI1500_R_CPT_TMR3_VALUE_LOW, - APCI1500_RW_CPT_TMR1_TIME_CST_HIGH, - APCI1500_RW_CPT_TMR1_TIME_CST_LOW, - APCI1500_RW_CPT_TMR2_TIME_CST_HIGH, - APCI1500_RW_CPT_TMR2_TIME_CST_LOW, - APCI1500_RW_CPT_TMR3_TIME_CST_HIGH, - APCI1500_RW_CPT_TMR3_TIME_CST_LOW, - APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION, - APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION, - APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION, - APCI1500_R_CURRENT_VECTOR, - - APCI1500_RW_PORT_A_SPECIFICATION, - APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION, - APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY, - APCI1500_RW_PORT_A_DATA_DIRECTION, - APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL, - APCI1500_RW_PORT_A_PATTERN_POLARITY, - APCI1500_RW_PORT_A_PATTERN_TRANSITION, - APCI1500_RW_PORT_A_PATTERN_MASK, - - APCI1500_RW_PORT_B_SPECIFICATION, - APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION, - APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY, - APCI1500_RW_PORT_B_DATA_DIRECTION, - APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL, - APCI1500_RW_PORT_B_PATTERN_POLARITY, - APCI1500_RW_PORT_B_PATTERN_TRANSITION, - APCI1500_RW_PORT_B_PATTERN_MASK -}; - - /*----------DIGITAL INPUT----------------*/ -static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/*---------- DIGITAL OUTPUT------------*/ -static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/*----------TIMER----------------*/ -static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/*----------INTERRUPT HANDLER------*/ -static void v_APCI1500_Interrupt(int irq, void *d); -static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/*----------RESET---------------*/ -static int i_APCI1500_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c deleted file mode 100644 index 8a584a0..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ /dev/null @@ -1,542 +0,0 @@ -/** -@verbatim - -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 - -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. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-1516 | Compiler : GCC | - | Module name : hwdrv_apci1516.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-1516 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci1516.h" - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; - ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel <= 7) { - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP); - /* since only 1 channel reqd to bring it to last bit it is rotated */ - /* 8 +(chan - 1) times then ANDed with 1 for last bit. */ - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=7) */ - else { - /* comedi_error(dev," \n chan spec wrong\n"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=7) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; - - ui_NoOfChannels = CR_CHAN(insn->chanspec); - - *data = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 7: - break; - - default: - printk("\nWrong parameters\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ConfigDigitalOutput (struct comedi_device *dev, -| struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| data[0] :1:Memory on | -| 0:Memory off | -| | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - devpriv->b_OutputMemoryStatus = data[0]; - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - - printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP); - - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP); - - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - - case 7: - data[0] = data[0] | ui_Temp; - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xff; - data[0] = data[0] & ui_Temp; - outw(data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xff) & ui_Temp; - break; - - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xff) & ui_Temp; - break; - - case 7: - break; - - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + - APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", - data[0], - devpriv->iobase + - APCI1516_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return (insn->n); -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - unsigned int ui_Temp; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - ui_Temp = data[0]; - *data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if(ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 7: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - } /* if(ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif(ui_Temp==1) */ - } /* elseif(ui_Temp==0) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, -| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Configures The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if (data[0] == 0) { - /* Disable the watchdog */ - outw(0x0, - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_ENABLEDISABLE); - /* Loading the Reload value */ - outw(data[1], - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_RELOAD_VALUE); - data[1] = data[1] >> 16; - outw(data[1], - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_RELOAD_VALUE + 2); - } /* if(data[0]==0) */ - else { - printk("\nThe input parameters are wrong\n"); - return -EINVAL; - } /* elseif(data[0]==0) */ - - return insn->n; -} - - /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI1516_StartStopWriteWatchdog | - | (struct comedi_device *dev,struct comedi_subdevice *s, - struct comedi_insn *insn,unsigned int *data); | - +----------------------------------------------------------------------------+ - | Task : Start / Stop The Watchdog | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s, :pointer to subdevice structure - struct comedi_insn *insn :pointer to insn structure | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ - */ - -int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - switch (data[0]) { - case 0: /* stop the watchdog */ - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */ - break; - case 1: /* start the watchdog */ - outw(0x0001, - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_ENABLEDISABLE); - break; - case 2: /* Software trigger */ - outw(0x0201, - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_ENABLEDISABLE); - break; - default: - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* switch(data[0]) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ReadWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, - unsigned int *data); | -+----------------------------------------------------------------------------+ -| Task : Read The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure - struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1; - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_Reset(struct comedi_device *dev) | | -+----------------------------------------------------------------------------+ -| Task :resets all the registers | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1516_Reset(struct comedi_device *dev) -{ - outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */ - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2); - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h deleted file mode 100644 index 4472829..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/********* Definitions for APCI-1516 card *****/ - -/* Card Specific information */ -#define APCI1516_BOARD_VENDOR_ID 0x15B8 -#define APCI1516_ADDRESS_RANGE 8 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI1516_DIGITAL_OP 4 -#define APCI1516_DIGITAL_OP_RW 4 -#define APCI1516_DIGITAL_IP 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_WATCHDOG 2 -#define APCI1516_DIGITAL_OP_WATCHDOG 0 -#define APCI1516_WATCHDOG_ENABLEDISABLE 12 -#define APCI1516_WATCHDOG_RELOAD_VALUE 4 -#define APCI1516_WATCHDOG_STATUS 16 - -/* Hardware Layer functions for Apci1516 */ - -/* Digital Input */ -int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Digital Output */ -int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* TIMER timer value is passed as u seconds -*/ -int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* reset */ -int i_APCI1516_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 5b92e45..fc31c4b 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -46,14 +46,62 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ - -#include <linux/delay.h> -#include "hwdrv_apci1564.h" +/********* Definitions for APCI-1564 card *****/ + +#define APCI1564_ADDRESS_RANGE 128 + +/* DIGITAL INPUT-OUTPUT DEFINE */ +/* Input defines */ +#define APCI1564_DIGITAL_IP 0x04 +#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4 +#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8 +#define APCI1564_DIGITAL_IP_IRQ 16 + +/* Output defines */ +#define APCI1564_DIGITAL_OP 0x18 +#define APCI1564_DIGITAL_OP_RW 0 +#define APCI1564_DIGITAL_OP_INTERRUPT 4 +#define APCI1564_DIGITAL_OP_IRQ 12 + +/* Digital Input IRQ Function Selection */ +#define ADDIDATA_OR 0 +#define ADDIDATA_AND 1 + +/* Digital Input Interrupt Status */ +#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12 + +/* Digital Output Interrupt Status */ +#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8 + +/* Digital Input Interrupt Enable Disable. */ +#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4 +#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb + +/* Digital Output Interrupt Enable Disable. */ +#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 +#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xfffffffe +#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 +#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd + +/* TIMER COUNTER WATCHDOG DEFINES */ + +#define ADDIDATA_TIMER 0 +#define ADDIDATA_COUNTER 1 +#define ADDIDATA_WATCHDOG 2 +#define APCI1564_DIGITAL_OP_WATCHDOG 0x28 +#define APCI1564_TIMER 0x48 +#define APCI1564_COUNTER1 0x0 +#define APCI1564_COUNTER2 0x20 +#define APCI1564_COUNTER3 0x40 +#define APCI1564_COUNTER4 0x60 +#define APCI1564_TCW_SYNC_ENABLEDISABLE 0 +#define APCI1564_TCW_RELOAD_VALUE 4 +#define APCI1564_TCW_TIMEBASE 8 +#define APCI1564_TCW_PROG 12 +#define APCI1564_TCW_TRIG_STATUS 16 +#define APCI1564_TCW_IRQ 20 +#define APCI1564_TCW_WARN_TIMEVAL 24 +#define APCI1564_TCW_WARN_TIMEBASE 28 /* Global variables */ static unsigned int ui_InterruptStatus_1564 = 0; @@ -86,9 +134,13 @@ static unsigned int ui_InterruptData, ui_Type; | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->tsk_Current = current; /*******************************/ /* Set the digital input logic */ @@ -128,107 +180,15 @@ int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_Channel : Channel number to read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int apci1564_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; + struct addi_private *devpriv = dev->private; - ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel <= 31) { - ui_TmpValue = - (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); -/* -* since only 1 channel reqd to bring it to last bit it is rotated 8 -* +(chan - 1) times then ANDed with 1 for last bit. -*/ - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if (ui_Channel >= 0 && ui_Channel <=31) */ - else { - comedi_error(dev, "Not a valid channel number !!! \n"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if (ui_Channel >= 0 && ui_Channel <=31) */ - return insn->n; -} + data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To be Read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; - - ui_NoOfChannels = CR_CHAN(insn->chanspec); - if (data[1] == 0) { - *data = (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 8: - ui_Mask = 255; - *data = (*data >> (8 * ui_PortValue)) & ui_Mask; - break; - case 16: - ui_Mask = 65535; - *data = (*data >> (16 * ui_PortValue)) & ui_Mask; - break; - case 31: - break; - default: - comedi_error(dev, "Not a valid Channel number !!!\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch (ui_NoOfChannels) */ - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - *data = ui_InterruptStatus_1564; - } /* if (data[1]==1) */ - } /* else if (data[1]==0) */ return insn->n; } @@ -257,9 +217,12 @@ int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command = 0; if ((data[0] != 0) && (data[0] != 1)) { @@ -295,244 +258,27 @@ int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To Write | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int apci1564_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel; + struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = - inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + + s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_RW); - } /* if (devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* else if (devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], - devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - case 16: - data[0] = - (data[0] << (16 * - data[2])) | ui_Temp; - break; - case 31: - data[0] = data[0] | ui_Temp; - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch (ui_NoOfChannels) */ - outl(data[0], - devpriv->i_IobaseAmcc + - APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if (data[1]==1) */ - } /* else if (data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - (data[0] << ui_NoOfChannel) ^ - 0xffffffff; - data[0] = data[0] & ui_Temp; - outl(data[0], - devpriv->i_IobaseAmcc + - APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 16: - data[0] = ~data[0] & 0xffff; - ui_Temp1 = 65535; - ui_Temp1 = - ui_Temp1 << 16 * - data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (16 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 31: - break; - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - outl(data[0], - devpriv->i_IobaseAmcc + - APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if (data[1]==1) */ - } /* else if (data[1]==0) */ - } /* if (data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* else if (data[3]==1) */ - } /* else if (data[3]==0) */ - return insn->n; -} + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + + APCI1564_DIGITAL_OP_RW); + } + + data[1] = s->state; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 16: - *data = (*data >> (16 * data[1])) & 65535; - break; - - case 31: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* else if (ui_Temp==0) */ return insn->n; } @@ -566,10 +312,14 @@ int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; + devpriv->tsk_Current = current; if (data[0] == ADDIDATA_WATCHDOG) { devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG; @@ -720,10 +470,14 @@ int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; + if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { switch (data[1]) { case 0: /* stop the watchdog */ @@ -815,9 +569,12 @@ int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { @@ -894,8 +651,10 @@ int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { *data = ui_Type; return insn->n; @@ -921,10 +680,12 @@ int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subd static void v_APCI1564_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_DO, ui_DI; unsigned int ui_Timer; unsigned int ui_C1, ui_C2, ui_C3, ui_C4; unsigned int ul_Command2 = 0; + ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ) & 0x01; ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + @@ -1104,8 +865,10 @@ static void v_APCI1564_Interrupt(int irq, void *d) +----------------------------------------------------------------------------+ */ -int i_APCI1564_Reset(struct comedi_device *dev) +static int i_APCI1564_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ); /* disable the interrupts */ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h deleted file mode 100644 index c91594d..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/********* Definitions for APCI-1564 card *****/ - -#define APCI1564_BOARD_VENDOR_ID 0x15B8 -#define APCI1564_ADDRESS_RANGE 128 - -/* DIGITAL INPUT-OUTPUT DEFINE */ -/* Input defines */ -#define APCI1564_DIGITAL_IP 0x04 -#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4 -#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8 -#define APCI1564_DIGITAL_IP_IRQ 16 - -/* Output defines */ -#define APCI1564_DIGITAL_OP 0x18 -#define APCI1564_DIGITAL_OP_RW 0 -#define APCI1564_DIGITAL_OP_INTERRUPT 4 -#define APCI1564_DIGITAL_OP_IRQ 12 - -/* Digital Input IRQ Function Selection */ -#define ADDIDATA_OR 0 -#define ADDIDATA_AND 1 - -/* Digital Input Interrupt Status */ -#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12 - -/* Digital Output Interrupt Status */ -#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8 - -/* Digital Input Interrupt Enable Disable. */ -#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4 -#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB - -/* Digital Output Interrupt Enable Disable. */ -#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 -#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE -#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 -#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_TIMER 0 -#define ADDIDATA_COUNTER 1 -#define ADDIDATA_WATCHDOG 2 -#define APCI1564_DIGITAL_OP_WATCHDOG 0x28 -#define APCI1564_TIMER 0x48 -#define APCI1564_COUNTER1 0x0 -#define APCI1564_COUNTER2 0x20 -#define APCI1564_COUNTER3 0x40 -#define APCI1564_COUNTER4 0x60 -#define APCI1564_TCW_SYNC_ENABLEDISABLE 0 -#define APCI1564_TCW_RELOAD_VALUE 4 -#define APCI1564_TCW_TIMEBASE 8 -#define APCI1564_TCW_PROG 12 -#define APCI1564_TCW_TRIG_STATUS 16 -#define APCI1564_TCW_IRQ 20 -#define APCI1564_TCW_WARN_TIMEVAL 24 -#define APCI1564_TCW_WARN_TIMEBASE 28 - -/* Hardware Layer functions for Apci1564 */ - -/* -* DI for di read -*/ -int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* DO */ -int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* TIMER timer value is passed as u seconds -*/ -int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* intERRUPT */ -static void v_APCI1564_Interrupt(int irq, void *d); - -/* RESET */ -int i_APCI1564_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c index 00a088f..5958a9c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c @@ -47,13 +47,24 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif + +#define APCI16XX_TTL_INIT 0 +#define APCI16XX_TTL_INITDIRECTION 1 +#define APCI16XX_TTL_OUTPUTMEMORY 2 + +#define APCI16XX_TTL_READCHANNEL 0 +#define APCI16XX_TTL_READPORT 1 + +#define APCI16XX_TTL_WRITECHANNEL_ON 0 +#define APCI16XX_TTL_WRITECHANNEL_OFF 1 +#define APCI16XX_TTL_WRITEPORT_ON 2 +#define APCI16XX_TTL_WRITEPORT_OFF 3 -#include "hwdrv_apci16xx.h" +#define APCI16XX_TTL_READ_ALL_INPUTS 0 +#define APCI16XX_TTL_READ_ALL_OUTPUTS 1 /* +----------------------------------------------------------------------------+ @@ -90,9 +101,13 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; unsigned char b_Cpt = 0; @@ -283,9 +298,13 @@ int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; unsigned char b_NumberOfPort = @@ -430,9 +449,13 @@ int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; unsigned char b_Command = (unsigned char) CR_AREF(insn->chanspec); int i_ReturnValue = insn->n; unsigned char b_Cpt = 0; @@ -570,9 +593,13 @@ int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; unsigned char b_NumberOfPort = @@ -774,7 +801,7 @@ int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_Reset(struct comedi_device *dev) +static int i_APCI16XX_Reset(struct comedi_device *dev) { return 0; } diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h deleted file mode 100644 index a12df4b..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - -#ifndef ADDIDATA_ENABLE -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -#endif - -#define APCI16XX_TTL_INIT 0 -#define APCI16XX_TTL_INITDIRECTION 1 -#define APCI16XX_TTL_OUTPUTMEMORY 2 - -#define APCI16XX_TTL_READCHANNEL 0 -#define APCI16XX_TTL_READPORT 1 - -#define APCI16XX_TTL_WRITECHANNEL_ON 0 -#define APCI16XX_TTL_WRITECHANNEL_OFF 1 -#define APCI16XX_TTL_WRITEPORT_ON 2 -#define APCI16XX_TTL_WRITEPORT_OFF 3 - -#define APCI16XX_TTL_READ_ALL_INPUTS 0 -#define APCI16XX_TTL_READ_ALL_OUTPUTS 1 - -#ifdef __KERNEL__ - -/* -+----------------------------------------------------------------------------+ -| TTL INISIALISATION FUNCTION | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - -/* -+----------------------------------------------------------------------------+ -| TTL INPUT FUNCTION | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - -int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -+----------------------------------------------------------------------------+ -| TTL OUTPUT FUNCTIONS | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - -int i_APCI16XX_Reset(struct comedi_device *dev); -#endif diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c deleted file mode 100644 index 49dcbe2..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ /dev/null @@ -1,460 +0,0 @@ -/** -@verbatim - -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 - -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. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-2016 | Compiler : GCC | - | Module name : hwdrv_apci2016.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-2016 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci2016.h" - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_ConfigDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -| data[0] : 1 Digital Memory On | -| 0 Digital Memory Off | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } /* if ((data[0]!=0) && (data[0]!=1)) */ - if (data[0]) { - devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0] */ - else { - devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0] */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To Write | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_NoOfChannel; - unsigned int ui_Temp, ui_Temp1; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - if (ui_NoOfChannel > 15) { - comedi_error(dev, - "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); - return -EINVAL; - } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */ - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* else if (devpriv->b_OutputMemoryStatus ) */ - if ((data[1] != 0) && (data[1] != 1)) { - comedi_error(dev, - "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n"); - return -EINVAL; - } /* if ((data[1]!=0) && (data[1]!=1)) */ - - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - case 15: - data[0] = data[0] | ui_Temp; - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - outw(data[0], - devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if (data[1]==1) */ - } /* else if (data[1]==0) */ - } /* if (data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff; - data[0] = data[0] & ui_Temp; - outw(data[0], - devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 15: - break; - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - outw(data[0], - devpriv->iobase + - APCI2016_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_BitsDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - if (ui_NoOfChannel > 15) { - comedi_error(dev, - "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); - return -EINVAL; - } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */ - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n"); - return -EINVAL; - } /* if ((data[0]!=0) && (data[0]!=1)) */ - ui_Temp = data[0]; - *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 15: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannel) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* if (ui_Temp==0) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_ConfigWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure | -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - if (data[0] == 0) { - /* Disable the watchdog */ - outw(0x0, - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_ENABLEDISABLE); - /* Loading the Reload value */ - outw(data[1], - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_RELOAD_VALUE); - data[1] = data[1] >> 16; - outw(data[1], - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_RELOAD_VALUE + 2); - } else { - printk("\nThe input parameters are wrong\n"); - } - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_StartStopWriteWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Start / Stop The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure | -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - switch (data[0]) { - case 0: /* stop the watchdog */ - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */ - break; - case 1: /* start the watchdog */ - outw(0x0001, - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_ENABLEDISABLE); - break; - case 2: /* Software trigger */ - outw(0x0201, - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_ENABLEDISABLE); - break; - default: - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* switch(data[0]) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_ReadWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure | -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - udelay(5); - data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1; - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | | -+----------------------------------------------------------------------------+ -| Task :resets all the registers | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2016_Reset(struct comedi_device *dev) -{ - outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); /* Resets the digital output channels */ - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE); - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2); - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h deleted file mode 100644 index c42612a..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 - * - * 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. - */ -/********* Definitions for APCI-2016 card *****/ - -#define APCI2016_BOARD_VENDOR_ID 0x15B8 -#define APCI2016_ADDRESS_RANGE 8 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI2016_DIGITAL_OP 0x04 -#define APCI2016_DIGITAL_OP_RW 4 - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_WATCHDOG 2 -#define APCI2016_DIGITAL_OP_WATCHDOG 0 -#define APCI2016_WATCHDOG_ENABLEDISABLE 12 -#define APCI2016_WATCHDOG_RELOAD_VALUE 4 -#define APCI2016_WATCHDOG_STATUS 16 - -/* Hardware Layer functions for Apci2016 */ - -/* DO */ -int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* TIMER -* timer value is passed as u seconds -*/ - -int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt functions..... */ - -/* void v_APCI2016_Interrupt(int irq, void *d); */ - -/* void v_APCI2016_Interrupt(int irq, void *d); */ -/* RESET */ -int i_APCI2016_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c deleted file mode 100644 index 002297d..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ /dev/null @@ -1,579 +0,0 @@ -/** -@verbatim - -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 - -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. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-2032 | Compiler : GCC | - | Module name : hwdrv_apci2032.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-2032 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ - -#include "hwdrv_apci2032.h" -static unsigned int ui_InterruptData, ui_Type; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_ConfigDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -| data[1] : 1 Enable VCC Interrupt | -| 0 Disable VCC Interrupt | -| data[2] : 1 Enable CC Interrupt | -| 0 Disable CC Interrupt | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ul_Command = 0; - devpriv->tsk_Current = current; - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } /* if ( (data[0]!=0) && (data[0]!=1) ) */ - if (data[0]) { - devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0]) */ - else { - devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0]) */ - - if (data[1] == ADDIDATA_ENABLE) { - ul_Command = ul_Command | 0x1; - } /* if (data[1] == ADDIDATA_ENABLE) */ - else { - ul_Command = ul_Command & 0xFFFFFFFE; - } /* elseif (data[1] == ADDIDATA_ENABLE) */ - if (data[2] == ADDIDATA_ENABLE) { - ul_Command = ul_Command | 0x2; - } /* if (data[2] == ADDIDATA_ENABLE) */ - else { - ul_Command = ul_Command & 0xFFFFFFFD; - } /* elseif (data[2] == ADDIDATA_ENABLE) */ - outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); - ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To Write | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP); - - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - - case 16: - data[0] = - (data[0] << (16 * - data[2])) | ui_Temp; - break; - case 31: - data[0] = data[0] | ui_Temp; - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outl(data[0], - devpriv->iobase + APCI2032_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - (data[0] << ui_NoOfChannel) ^ - 0xffffffff; - data[0] = data[0] & ui_Temp; - outl(data[0], - devpriv->iobase + APCI2032_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 16: - data[0] = ~data[0] & 0xffff; - ui_Temp1 = 65535; - ui_Temp1 = - ui_Temp1 << 16 * - data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (16 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 31: - break; - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outl(data[0], - devpriv->iobase + - APCI2032_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 16: - *data = (*data >> (16 * data[1])) & 65535; - break; - - case 31: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif (ui_Temp==1) */ - } - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_ConfigWatchdog(comedi_device -| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)| -| | -+----------------------------------------------------------------------------+ -| Task : Configures The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if (data[0] == 0) { - /* Disable the watchdog */ - outl(0x0, - devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + - APCI2032_TCW_PROG); - /* Loading the Reload value */ - outl(data[1], - devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + - APCI2032_TCW_RELOAD_VALUE); - } else { - printk("\nThe input parameters are wrong\n"); - return -EINVAL; - } - - return insn->n; -} - - /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI2032_StartStopWriteWatchdog | - | (struct comedi_device *dev,struct comedi_subdevice *s, - struct comedi_insn *insn,unsigned int *data); | - +----------------------------------------------------------------------------+ - | Task : Start / Stop The Watchdog | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s, :pointer to subdevice structure - struct comedi_insn *insn :pointer to insn structure | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ - */ - -int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - switch (data[0]) { - case 0: /* stop the watchdog */ - outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); /* disable the watchdog */ - break; - case 1: /* start the watchdog */ - outl(0x0001, - devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + - APCI2032_TCW_PROG); - break; - case 2: /* Software trigger */ - outl(0x0201, - devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + - APCI2032_TCW_PROG); - break; - default: - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_ReadWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data); | -+----------------------------------------------------------------------------+ -| Task : Read The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - data[0] = - inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + - APCI2032_TCW_TRIG_STATUS) & 0x1; - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : void v_APCI2032_Interrupt | -| (int irq , void *d) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq : irq number | -| void *d : void pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -void v_APCI2032_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - unsigned int ui_DO; - - ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; /* Check if VCC OR CC interrupt has occurred. */ - - if (ui_DO == 0) { - printk("\nInterrupt from unKnown source\n"); - } /* if(ui_DO==0) */ - if (ui_DO) { - /* Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. */ - ui_Type = - inl(devpriv->iobase + - APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3; - outl(0x0, - devpriv->iobase + APCI2032_DIGITAL_OP + - APCI2032_DIGITAL_OP_INTERRUPT); - if (ui_Type == 1) { - /* Sends signal to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - } /* if (ui_Type==1) */ - else { - if (ui_Type == 2) { - /* Sends signal to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - } /* if (ui_Type==2) */ - } /* else if (ui_Type==1) */ - } /* if(ui_DO) */ - - return; - -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_ReadInterruptStatus | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task :Reads the interrupt status register | -+----------------------------------------------------------------------------+ -| Input Parameters : | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - *data = ui_Type; - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_Reset(struct comedi_device *dev) | -| | -+----------------------------------------------------------------------------+ -| Task :Resets the registers of the card | -+----------------------------------------------------------------------------+ -| Input Parameters : | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2032_Reset(struct comedi_device *dev) -{ - devpriv->b_DigitalOutputRegister = 0; - ui_Type = 0; - outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); /* Resets the output channels */ - outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); /* Disables the interrupt. */ - outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); /* disable the watchdog */ - outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); /* reload=0 */ - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h deleted file mode 100644 index ab145e7..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/********* Definitions for APCI-2032 card *****/ - -/* Card Specific information */ -#define APCI2032_BOARD_VENDOR_ID 0x15B8 -#define APCI2032_ADDRESS_RANGE 63 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI2032_DIGITAL_OP 0 -#define APCI2032_DIGITAL_OP_RW 0 -#define APCI2032_DIGITAL_OP_INTERRUPT 4 -#define APCI2032_DIGITAL_OP_IRQ 12 - -/* Digital Output Interrupt Status */ -#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8 - -/* Digital Output Interrupt Enable Disable. */ -#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 -#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE -#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 -#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_WATCHDOG 2 -#define APCI2032_DIGITAL_OP_WATCHDOG 16 -#define APCI2032_TCW_RELOAD_VALUE 4 -#define APCI2032_TCW_TIMEBASE 8 -#define APCI2032_TCW_PROG 12 -#define APCI2032_TCW_TRIG_STATUS 16 -#define APCI2032_TCW_IRQ 20 - -/* Hardware Layer functions for Apci2032 */ - -/* DO */ -int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* TIMER - * timer value is passed as u seconds -*/ - -int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt functions..... */ - -void v_APCI2032_Interrupt(int irq, void *d); - -/* Reset functions */ -int i_APCI2032_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index 3d378b5..9d4a117 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -46,354 +46,54 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci2200.h" +/********* Definitions for APCI-2200 card *****/ -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; - ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel <= 7) { - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP); - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=7) */ - else { - printk("\nThe specified channel does not exist\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=7) */ +/* Card Specific information */ +#define APCI2200_ADDRESS_RANGE 64 - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ +/* DIGITAL INPUT-OUTPUT DEFINE */ -int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ +#define APCI2200_DIGITAL_OP 4 +#define APCI2200_DIGITAL_IP 0 - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; +/* TIMER COUNTER WATCHDOG DEFINES */ - ui_NoOfChannels = CR_CHAN(insn->chanspec); +#define APCI2200_WATCHDOG 0x08 +#define APCI2200_WATCHDOG_ENABLEDISABLE 12 +#define APCI2200_WATCHDOG_RELOAD_VALUE 4 +#define APCI2200_WATCHDOG_STATUS 16 - *data = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 7: - break; +static int apci2200_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; - default: - printk("\nWrong parameters\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ + data[1] = inw(devpriv->iobase + APCI2200_DIGITAL_IP); return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev, -| struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| data[0] :1:Memory on | -| 0:Memory off | -| | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int apci2200_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - devpriv->b_OutputMemoryStatus = data[0]; - return insn->n; -} + struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ + s->state = inw(devpriv->iobase + APCI2200_DIGITAL_OP); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); -int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP); + outw(s->state, devpriv->iobase + APCI2200_DIGITAL_OP); + } - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - case 15: - data[0] = data[0] | ui_Temp; - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + APCI2200_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff; - data[0] = data[0] & ui_Temp; - outw(data[0], - devpriv->iobase + APCI2200_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 15: - break; - - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + - APCI2200_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ + data[1] = s->state; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - ui_Temp = data[0]; - *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if(ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 15: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - } /* if(ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif(ui_Temp==1) */ - } /* elseif(ui_Temp==0) */ return insn->n; } @@ -418,9 +118,13 @@ int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + if (data[0] == 0) { /* Disable the watchdog */ outw(0x0, @@ -464,9 +168,13 @@ int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice +----------------------------------------------------------------------------+ */ -int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + switch (data[0]) { case 0: /* stop the watchdog */ outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */ @@ -509,9 +217,13 @@ int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s +----------------------------------------------------------------------------+ */ -int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_ReadWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + data[0] = inw(devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_STATUS) & 0x1; @@ -533,8 +245,10 @@ int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * +----------------------------------------------------------------------------+ */ -int i_APCI2200_Reset(struct comedi_device *dev) +static int i_APCI2200_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */ outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h deleted file mode 100644 index 83f42af..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/********* Definitions for APCI-2200 card *****/ - -/* Card Specific information */ -#define APCI2200_BOARD_VENDOR_ID 0x15b8 -#define APCI2200_ADDRESS_RANGE 64 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI2200_DIGITAL_OP 4 -#define APCI2200_DIGITAL_IP 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define APCI2200_WATCHDOG 0x08 -#define APCI2200_WATCHDOG_ENABLEDISABLE 12 -#define APCI2200_WATCHDOG_RELOAD_VALUE 4 -#define APCI2200_WATCHDOG_STATUS 16 - -/* Hardware Layer functions for Apci2200 */ - -/* Digital Input */ -int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Digital Output */ -int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* TIMER */ -int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* reset */ -int i_APCI2200_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index f406dfb..74065ba 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -44,8 +44,203 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_apci3120.h" -static unsigned int ui_Temp; +/* + * ADDON RELATED ADDITIONS + */ +/* Constant */ +#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00 +#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200 +#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L +#define APCI3120_AMWEN_ENABLE 0x02 +#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 +#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L +#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L +#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L +#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 +#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 +#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 + +/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ +#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C +#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2) +#define APCI3120_ADD_ON_MWAR_LOW 0x24 +#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2) +#define APCI3120_ADD_ON_MWTC_LOW 0x058 +#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2) + +/* AMCC */ +#define APCI3120_AMCC_OP_MCSR 0x3C +#define APCI3120_AMCC_OP_REG_INTCSR 0x38 + +/* for transfer count enable bit */ +#define AGCSTS_TC_ENABLE 0x10000000 + +/* used for test on mixture of BIP/UNI ranges */ +#define APCI3120_BIPOLAR_RANGES 4 + +#define APCI3120_ADDRESS_RANGE 16 + +#define APCI3120_DISABLE 0 +#define APCI3120_ENABLE 1 + +#define APCI3120_START 1 +#define APCI3120_STOP 0 + +#define APCI3120_EOC_MODE 1 +#define APCI3120_EOS_MODE 2 +#define APCI3120_DMA_MODE 3 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI3120_DIGITAL_OUTPUT 0x0d +#define APCI3120_RD_STATUS 0x02 +#define APCI3120_RD_FIFO 0x00 + +/* digital output insn_write ON /OFF selection */ +#define APCI3120_SET4DIGITALOUTPUTON 1 +#define APCI3120_SET4DIGITALOUTPUTOFF 0 + +/* analog output SELECT BIT */ +#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000 +#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000 +#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000 +#define APCI3120_ANALOG_OP_CHANNEL_4 0xc000 +#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000 +#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000 +#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000 +#define APCI3120_ANALOG_OP_CHANNEL_8 0xc000 + +/* Enable external trigger bit in nWrAddress */ +#define APCI3120_ENABLE_EXT_TRIGGER 0x8000 + +/* ANALOG OUTPUT AND INPUT DEFINE */ +#define APCI3120_UNIPOLAR 0x80 +#define APCI3120_BIPOLAR 0x00 +#define APCI3120_ANALOG_OUTPUT_1 0x08 +#define APCI3120_ANALOG_OUTPUT_2 0x0a +#define APCI3120_1_GAIN 0x00 +#define APCI3120_2_GAIN 0x10 +#define APCI3120_5_GAIN 0x20 +#define APCI3120_10_GAIN 0x30 +#define APCI3120_SEQ_RAM_ADDRESS 0x06 +#define APCI3120_RESET_FIFO 0x0c +#define APCI3120_TIMER_0_MODE_2 0x01 +#define APCI3120_TIMER_0_MODE_4 0x2 +#define APCI3120_SELECT_TIMER_0_WORD 0x00 +#define APCI3120_ENABLE_TIMER0 0x1000 +#define APCI3120_CLEAR_PR 0xf0ff +#define APCI3120_CLEAR_PA 0xfff0 +#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA) + +/* nWrMode_Select */ +#define APCI3120_ENABLE_SCAN 0x8 +#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) +#define APCI3120_ENABLE_EOS_INT 0x2 + +#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) +#define APCI3120_ENABLE_EOC_INT 0x1 +#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) +#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER \ + (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) +#define APCI3120_DISABLE_ALL_INTERRUPT \ + (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) + +/* status register bits */ +#define APCI3120_EOC 0x8000 +#define APCI3120_EOS 0x2000 + +/* software trigger dummy register */ +#define APCI3120_START_CONVERSION 0x02 + +/* TIMER DEFINE */ +#define APCI3120_QUARTZ_A 70 +#define APCI3120_QUARTZ_B 50 +#define APCI3120_TIMER 1 +#define APCI3120_WATCHDOG 2 +#define APCI3120_TIMER_DISABLE 0 +#define APCI3120_TIMER_ENABLE 1 +#define APCI3120_ENABLE_TIMER2 0x4000 +#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) +#define APCI3120_ENABLE_TIMER_INT 0x04 +#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) +#define APCI3120_WRITE_MODE_SELECT 0x0e +#define APCI3120_SELECT_TIMER_0_WORD 0x00 +#define APCI3120_SELECT_TIMER_1_WORD 0x01 +#define APCI3120_TIMER_1_MODE_2 0x4 + +/* $$ BIT FOR MODE IN nCsTimerCtr1 */ +#define APCI3120_TIMER_2_MODE_0 0x0 +#define APCI3120_TIMER_2_MODE_2 0x10 +#define APCI3120_TIMER_2_MODE_5 0x30 + +/* $$ BIT FOR MODE IN nCsTimerCtr0 */ +#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02 +#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03 + +#define APCI3120_TIMER_CRT0 0x0d +#define APCI3120_TIMER_CRT1 0x0c + +#define APCI3120_TIMER_VALUE 0x04 +#define APCI3120_TIMER_STATUS_REGISTER 0x0d +#define APCI3120_RD_STATUS 0x02 +#define APCI3120_WR_ADDRESS 0x00 +#define APCI3120_ENABLE_WATCHDOG 0x20 +#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) +#define APCI3120_ENABLE_TIMER_COUNTER 0x10 +#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER) +#define APCI3120_FC_TIMER 0x1000 +#define APCI3120_ENABLE_TIMER0 0x1000 +#define APCI3120_ENABLE_TIMER1 0x2000 +#define APCI3120_ENABLE_TIMER2 0x4000 +#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0) +#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1) +#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) + +#define APCI3120_TIMER2_SELECT_EOS 0xc0 +#define APCI3120_COUNTER 3 +#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & \ + APCI3120_DISABLE_TIMER1 & \ + APCI3120_DISABLE_TIMER2) + +#define MAX_ANALOGINPUT_CHANNELS 32 + +struct str_AnalogReadInformation { + /* EOC or EOS */ + unsigned char b_Type; + /* Interrupt use or not */ + unsigned char b_InterruptFlag; + /* Selection of the conversion time */ + unsigned int ui_ConvertTiming; + /* Number of channel to read */ + unsigned char b_NbrOfChannel; + /* Number of the channel to be read */ + unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; + /* Gain of each channel */ + unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; +}; + +/* ANALOG INPUT RANGE */ +static const struct comedi_lrange range_apci3120_ai = { + 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) + } +}; + +/* ANALOG OUTPUT RANGE */ +static const struct comedi_lrange range_apci3120_ao = { + 2, { + BIP_RANGE(10), + UNI_RANGE(10) + } +}; + /* FUNCTION DEFINITIONS */ @@ -55,28 +250,13 @@ static unsigned int ui_Temp; +----------------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev,| -| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Calls card specific function | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; unsigned int i; if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE)) @@ -91,7 +271,7 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su for (i = 0; i < data[3]; i++) { if (CR_CHAN(data[4 + i]) >= - devpriv->s_EeParameters.i_NbrAiChannel) { + this_board->i_NbrAiChannel) { printk("bad channel list\n"); return -2; } @@ -121,31 +301,72 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, | -| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : card specific function | -| Reads analog input in synchronous mode | -| EOC and EOS is selected as per configured | -| if no conversion time is set uses default conversion | -| time 10 microsec. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ + * This function will first check channel list is ok or not and then + * initialize the sequence RAM with the polarity, Gain,Channel number. + * If the last argument of function "check"is 1 then it only checks + * the channel list is ok or not. + */ +static int i_APCI3120_SetupChannelList(struct comedi_device *dev, + struct comedi_subdevice *s, + int n_chan, + unsigned int *chanlist, + char check) +{ + struct addi_private *devpriv = dev->private; + unsigned int i; /* , differencial=0, bipolar=0; */ + unsigned int gain; + unsigned short us_TmpValue; -int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + /* correct channel and range number check itself comedi/range.c */ + if (n_chan < 1) { + if (!check) + comedi_error(dev, "range/channel list is empty!"); + return 0; + } + /* All is ok, so we can setup channel/range list */ + if (check) + return 1; + + /* Code to set the PA and PR...Here it set PA to 0.. */ + devpriv->us_OutputRegister = + devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR; + devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + + for (i = 0; i < n_chan; i++) { + /* store range list to card */ + us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */ + + if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) + us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ + else + us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */ + + gain = CR_RANGE(chanlist[i]); /* get gain number */ + us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ + us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */ + outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + + printk("\n Gain = %i", + (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2)); + printk("\n Channel = %i", CR_CHAN(chanlist[i])); + printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR); + } + return 1; /* we can serve this with scan logic */ +} + +/* + * Reads analog input in synchronous mode EOC and EOS is selected + * as per configured if no conversion time is set uses default + * conversion time 10 microsec. + */ +static int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; unsigned short us_ConvertTiming, us_TmpValue, i; unsigned char b_Tmp; @@ -387,26 +608,86 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd } +static int i_APCI3120_Reset(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + unsigned int i; + unsigned short us_TmpValue; + + devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + devpriv->b_EocEosInterrupt = APCI3120_DISABLE; + devpriv->b_InterruptMode = APCI3120_EOC_MODE; + devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */ + devpriv->b_OutputMemoryStatus = 0; + + /* variables used in timer subdevice */ + devpriv->b_Timer2Mode = 0; + devpriv->b_Timer2Interrupt = 0; + devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */ + + /* Disable all interrupts, watchdog for the anolog output */ + devpriv->b_ModeSelectRegister = 0; + outb(devpriv->b_ModeSelectRegister, + dev->iobase + APCI3120_WRITE_MODE_SELECT); + + /* Disables all counters, ext trigger and clears PA, PR */ + devpriv->us_OutputRegister = 0; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev,| -| struct comedi_subdevice *s)| -| | -+----------------------------------------------------------------------------+ -| Task : Stops Cyclic acquisition | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| | -+----------------------------------------------------------------------------+ -| Return Value :0 | -| | -+----------------------------------------------------------------------------+ -*/ + * Code to set the all anolog o/p channel to 0v 8191 is decimal + * value for zero(0 v)volt in bipolar mode(default) + */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */ -int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s) + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */ + + /* Reset digital output to L0W */ + +/* ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT); */ + udelay(10); + + inw(dev->iobase + 0); /* make a dummy read */ + inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ + inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ + + /* code to reset the RAM sequence */ + for (i = 0; i < 16; i++) { + us_TmpValue = i << 8; /* select the location */ + outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + } + return 0; +} + +static int i_APCI3120_ExttrigEnable(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + + devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + return 0; +} + +static int i_APCI3120_ExttrigDisable(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + + devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + return 0; +} + +static int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct addi_private *devpriv = dev->private; + /* Disable A2P Fifo write and AMWEN signal */ outw(0, devpriv->i_IobaseAddon + 4); @@ -456,28 +737,11 @@ int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su return 0; } -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev| -| ,struct comedi_subdevice *s,struct comedi_cmd *cmd) | -| | -+----------------------------------------------------------------------------+ -| Task : Test validity for a command for cyclic anlog input | -| acquisition | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_cmd *cmd | -+----------------------------------------------------------------------------+ -| Return Value :0 | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd) +static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { + const struct addi_board *this_board = comedi_board(dev); int err = 0; /* Step 1 : check if triggers are trivially valid */ @@ -503,63 +767,32 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */ - if (cmd->scan_begin_arg < - devpriv->s_EeParameters.ui_MinDelaytimeNs) { - cmd->scan_begin_arg = - devpriv->s_EeParameters.ui_MinDelaytimeNs; - err++; - } - } + if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */ if (cmd->scan_begin_src == TRIG_TIMER) { - if ((cmd->convert_arg) - && (cmd->convert_arg < - devpriv->s_EeParameters. - ui_MinAcquisitiontimeNs)) { - cmd->convert_arg = devpriv->s_EeParameters. - ui_MinAcquisitiontimeNs; - err++; - } + if (cmd->convert_arg) + err |= cfc_check_trigger_arg_min( + &cmd->convert_arg, 10000); } else { - if (cmd->convert_arg < - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs - ) { - cmd->convert_arg = devpriv->s_EeParameters. - ui_MinAcquisitiontimeNs; - err++; - - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + 10000); } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->chanlist_len > this_board->i_AiChannelList) { - cmd->chanlist_len = this_board->i_AiChannelList; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, + this_board->i_AiChannelList); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -584,100 +817,17 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s } /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, | -| struct comedi_subdevice *s) | -| | -+----------------------------------------------------------------------------+ -| Task : Does asynchronous acquisition | -| Determines the mode 1 or 2. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct comedi_cmd *cmd = &s->async->cmd; - - /* loading private structure with cmd structure inputs */ - devpriv->ui_AiFlags = cmd->flags; - devpriv->ui_AiNbrofChannels = cmd->chanlist_len; - devpriv->ui_AiScanLength = cmd->scan_end_arg; - devpriv->pui_AiChannelList = cmd->chanlist; - - /* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */ - devpriv->AiData = s->async->prealloc_buf; - /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */ - devpriv->ui_AiDataLength = s->async->prealloc_bufsz; - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ui_AiNbrofScans = cmd->stop_arg; - else - devpriv->ui_AiNbrofScans = 0; - - devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ - devpriv->ui_AiTimer1 = 0; - if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1)) - devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */ - /* stopped using cancel */ - - if (cmd->start_src == TRIG_EXT) - devpriv->b_ExttrigEnable = APCI3120_ENABLE; - else - devpriv->b_ExttrigEnable = APCI3120_DISABLE; - - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* mode 1 or 3 */ - if (cmd->convert_src == TRIG_TIMER) { - /* mode 1 */ - - devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */ - /* return this_board->ai_cmd(1,dev,s); */ - return i_APCI3120_CyclicAnalogInput(1, dev, s); - } - - } - if ((cmd->scan_begin_src == TRIG_TIMER) - && (cmd->convert_src == TRIG_TIMER)) { - /* mode 2 */ - devpriv->ui_AiTimer1 = cmd->scan_begin_arg; - devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */ - /* return this_board->ai_cmd(2,dev,s); */ - return i_APCI3120_CyclicAnalogInput(2, dev, s); - } - return -1; -} - -/* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_CyclicAnalogInput(int mode, | -| struct comedi_device * dev,struct comedi_subdevice * s) | -+----------------------------------------------------------------------------+ -| Task : This is used for analog input cyclic acquisition | -| Performs the command operations. | -| If DMA is configured does DMA initialization | -| otherwise does the acquisition with EOS interrupt. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, - struct comedi_subdevice *s) + * This is used for analog input cyclic acquisition. + * Performs the command operations. + * If DMA is configured does DMA initialization otherwise does the + * acquisition with EOS interrupt. + */ +static int i_APCI3120_CyclicAnalogInput(int mode, + struct comedi_device *dev, + struct comedi_subdevice *s) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; unsigned char b_Tmp; unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 = 0, dmalen1 = 0, ui_TimerValue2 = @@ -1186,241 +1336,277 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, } /* -+----------------------------------------------------------------------------+ -| intERNAL FUNCTIONS | -+----------------------------------------------------------------------------+ -*/ + * Does asynchronous acquisition. + * Determines the mode 1 or 2. + */ +static int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct addi_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; -/* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_Reset(struct comedi_device *dev) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : Hardware reset function | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ + /* loading private structure with cmd structure inputs */ + devpriv->ui_AiFlags = cmd->flags; + devpriv->ui_AiNbrofChannels = cmd->chanlist_len; + devpriv->ui_AiScanLength = cmd->scan_end_arg; + devpriv->pui_AiChannelList = cmd->chanlist; -int i_APCI3120_Reset(struct comedi_device *dev) -{ - unsigned int i; - unsigned short us_TmpValue; + /* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */ + devpriv->AiData = s->async->prealloc_buf; + /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */ + devpriv->ui_AiDataLength = s->async->prealloc_bufsz; - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */ - devpriv->b_OutputMemoryStatus = 0; + if (cmd->stop_src == TRIG_COUNT) + devpriv->ui_AiNbrofScans = cmd->stop_arg; + else + devpriv->ui_AiNbrofScans = 0; - /* variables used in timer subdevice */ - devpriv->b_Timer2Mode = 0; - devpriv->b_Timer2Interrupt = 0; - devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */ + devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ + devpriv->ui_AiTimer1 = 0; + if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1)) + devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */ + /* stopped using cancel */ - /* Disable all interrupts, watchdog for the anolog output */ - devpriv->b_ModeSelectRegister = 0; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + if (cmd->start_src == TRIG_EXT) + devpriv->b_ExttrigEnable = APCI3120_ENABLE; + else + devpriv->b_ExttrigEnable = APCI3120_DISABLE; - /* Disables all counters, ext trigger and clears PA, PR */ - devpriv->us_OutputRegister = 0; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + if (cmd->scan_begin_src == TRIG_FOLLOW) { + /* mode 1 or 3 */ + if (cmd->convert_src == TRIG_TIMER) { + /* mode 1 */ + + devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */ + /* return this_board->ai_cmd(1,dev,s); */ + return i_APCI3120_CyclicAnalogInput(1, dev, s); + } + + } + if ((cmd->scan_begin_src == TRIG_TIMER) + && (cmd->convert_src == TRIG_TIMER)) { + /* mode 2 */ + devpriv->ui_AiTimer1 = cmd->scan_begin_arg; + devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */ + /* return this_board->ai_cmd(2,dev,s); */ + return i_APCI3120_CyclicAnalogInput(2, dev, s); + } + return -1; +} /* - * Code to set the all anolog o/p channel to 0v 8191 is decimal - * value for zero(0 v)volt in bipolar mode(default) + * This function copies the data from DMA buffer to the Comedi buffer. */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */ +static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, + struct comedi_subdevice *s, + short *dma_buffer, + unsigned int num_samples) +{ + struct addi_private *devpriv = dev->private; - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */ + devpriv->ui_AiActualScan += + (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength; + s->async->cur_chan += num_samples; + s->async->cur_chan %= devpriv->ui_AiScanLength; - /* Reset digital output to L0W */ + cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short)); +} -/* ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT); */ - udelay(10); +/* + * This is a handler for the DMA interrupt. + * This function copies the data to Comedi Buffer. + * For continuous DMA it reinitializes the DMA operation. + * For single mode DMA it stop the acquisition. + */ +static void v_APCI3120_InterruptDma(int irq, void *d) +{ + struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; + struct comedi_subdevice *s = &dev->subdevices[0]; + unsigned int next_dma_buf, samplesinbuf; + unsigned long low_word, high_word, var; + unsigned int ui_Tmp; - inw(dev->iobase + 0); /* make a dummy read */ - inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ - inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ + samplesinbuf = + devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] - + inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); - /* code to reset the RAM sequence */ - for (i = 0; i < 16; i++) { - us_TmpValue = i << 8; /* select the location */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + if (samplesinbuf < + devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) { + comedi_error(dev, "Interrupted DMA transfer!"); } - return 0; -} + if (samplesinbuf & 1) { + comedi_error(dev, "Odd count of bytes in DMA ring!"); + i_APCI3120_StopCyclicAcquisition(dev, s); + devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + + return; + } + samplesinbuf = samplesinbuf >> 1; /* number of received samples */ + if (devpriv->b_DmaDoubleBuffer) { + /* switch DMA buffers if is used double buffering */ + next_dma_buf = 1 - devpriv->ui_DmaActualBuffer; + + ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; + outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); + + /* changed since 16 bit interface for add on */ + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, + devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ + + var = devpriv->ul_DmaBufferHw[next_dma_buf]; + low_word = var & 0xffff; + var = devpriv->ul_DmaBufferHw[next_dma_buf]; + high_word = var / 65536; + + /* DMA Start Address Low */ + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + + /* DMA Start Address High */ + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); + + var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; + low_word = var & 0xffff; + var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; + high_word = var / 65536; + + /* Nbr of acquisition LOW */ + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + + /* Nbr of acquisition HIGH */ + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_SetupChannelList(struct comedi_device * dev, | -| struct comedi_subdevice * s, int n_chan,unsigned int *chanlist| -| ,char check) | -| | -+----------------------------------------------------------------------------+ -| Task :This function will first check channel list is ok or not| -|and then initialize the sequence RAM with the polarity, Gain,Channel number | -|If the last argument of function "check"is 1 then it only checks the channel| -|list is ok or not. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device * dev | -| struct comedi_subdevice * s | -| int n_chan | - unsigned int *chanlist - char check -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ + * To configure A2P FIFO + * ENABLE A2P FIFO WRITE AND ENABLE AMWEN + * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 + */ + outw(3, devpriv->i_IobaseAddon + 4); + /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ + outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | + APCI3120_ENABLE_WRITE_TC_INT), + devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); -int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s, - int n_chan, unsigned int *chanlist, char check) -{ - unsigned int i; /* , differencial=0, bipolar=0; */ - unsigned int gain; - unsigned short us_TmpValue; + } + if (samplesinbuf) { + v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, + devpriv->ul_DmaBufferVirtual[devpriv-> + ui_DmaActualBuffer], samplesinbuf); - /* correct channel and range number check itself comedi/range.c */ - if (n_chan < 1) { - if (!check) - comedi_error(dev, "range/channel list is empty!"); - return 0; + if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) { + s->async->events |= COMEDI_CB_EOS; + comedi_event(dev, s); + } } - /* All is ok, so we can setup channel/range list */ - if (check) - return 1; + if (!devpriv->b_AiContinuous) + if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) { + /* all data sampled */ + i_APCI3120_StopCyclicAcquisition(dev, s); + devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + s->async->events |= COMEDI_CB_EOA; + comedi_event(dev, s); + return; + } - /* Code to set the PA and PR...Here it set PA to 0.. */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR; - devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */ + devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; + } else { +/* + * restart DMA if is not used double buffering + * ADDED REINITIALISE THE DMA + */ + ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; + outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); - for (i = 0; i < n_chan; i++) { - /* store range list to card */ - us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */ + /* changed since 16 bit interface for add on */ + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, + devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* */ +/* + * A2P FIFO MANAGEMENT + * A2P fifo reset & transfer control enable + */ + outl(APCI3120_A2P_FIFO_MANAGEMENT, + devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); - if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) - us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ - else - us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */ + var = devpriv->ul_DmaBufferHw[0]; + low_word = var & 0xffff; + var = devpriv->ul_DmaBufferHw[0]; + high_word = var / 65536; + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); - gain = CR_RANGE(chanlist[i]); /* get gain number */ - us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ - us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + var = devpriv->ui_DmaBufferUsesize[0]; + low_word = var & 0xffff; /* changed */ + var = devpriv->ui_DmaBufferUsesize[0]; + high_word = var / 65536; + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); - printk("\n Gain = %i", - (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2)); - printk("\n Channel = %i", CR_CHAN(chanlist[i])); - printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR); +/* + * To configure A2P FIFO + * ENABLE A2P FIFO WRITE AND ENABLE AMWEN + * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 + */ + outw(3, devpriv->i_IobaseAddon + 4); + /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ + outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | + APCI3120_ENABLE_WRITE_TC_INT), + devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); } - return 1; /* we can serve this with scan logic */ } /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_ExttrigEnable(struct comedi_device * dev) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : Enable the external trigger | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device * dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_ExttrigEnable(struct comedi_device *dev) + * This function handles EOS interrupt. + * This function copies the acquired data(from FIFO) to Comedi buffer. + */ +static int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + int n_chan, i; + struct comedi_subdevice *s = &dev->subdevices[0]; + int err = 1; - devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - return 0; -} + n_chan = devpriv->ui_AiNbrofChannels; -/* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_ExttrigDisable(struct comedi_device * dev) | -| | -+----------------------------------------------------------------------------+ -| Task : Disables the external trigger | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device * dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ + s->async->events = 0; -int i_APCI3120_ExttrigDisable(struct comedi_device *dev) -{ - devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - return 0; -} + for (i = 0; i < n_chan; i++) + err &= comedi_buf_put(s->async, inw(dev->iobase + 0)); -/* -+----------------------------------------------------------------------------+ -| intERRUPT FUNCTIONS | -+----------------------------------------------------------------------------+ -*/ + s->async->events |= COMEDI_CB_EOS; -/* -+----------------------------------------------------------------------------+ -| Function name : void v_APCI3120_Interrupt(int irq, void *d) | -| | -| | -+----------------------------------------------------------------------------+ -| Task :Interrupt handler for APCI3120 | -| When interrupt occurs this gets called. | -| First it finds which interrupt has been generated and | -| handles corresponding interrupt | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq | -| void *d | -| | -+----------------------------------------------------------------------------+ -| Return Value : void | -| | -+----------------------------------------------------------------------------+ -*/ + if (err == 0) + s->async->events |= COMEDI_CB_OVERFLOW; + + comedi_event(dev, s); + + return 0; +} -void v_APCI3120_Interrupt(int irq, void *d) +static void v_APCI3120_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned short int_daq; - unsigned int int_amcc, ui_Check, i; unsigned short us_TmpValue; unsigned char b_DummyRead; - struct comedi_subdevice *s = &dev->subdevices[0]; + ui_Check = 1; int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */ @@ -1602,284 +1788,20 @@ void v_APCI3120_Interrupt(int irq, void *d) } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : This function handles EOS interrupt. | -| This function copies the acquired data(from FIFO) | -| to Comedi buffer. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - - -int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) -{ - int n_chan, i; - struct comedi_subdevice *s = &dev->subdevices[0]; - int err = 1; - - n_chan = devpriv->ui_AiNbrofChannels; - - s->async->events = 0; - - for (i = 0; i < n_chan; i++) - err &= comedi_buf_put(s->async, inw(dev->iobase + 0)); - - s->async->events |= COMEDI_CB_EOS; - - if (err == 0) - s->async->events |= COMEDI_CB_OVERFLOW; - - comedi_event(dev, s); - - return 0; -} - -/* -+----------------------------------------------------------------------------+ -| Function name : void v_APCI3120_InterruptDma(int irq, void *d) | -| | -+----------------------------------------------------------------------------+ -| Task : This is a handler for the DMA interrupt | -| This function copies the data to Comedi Buffer. | -| For continuous DMA it reinitializes the DMA operation. | -| For single mode DMA it stop the acquisition. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq, void *d | -| | -+----------------------------------------------------------------------------+ -| Return Value : void | -| | -+----------------------------------------------------------------------------+ -*/ - -void v_APCI3120_InterruptDma(int irq, void *d) -{ - struct comedi_device *dev = d; - struct comedi_subdevice *s = &dev->subdevices[0]; - unsigned int next_dma_buf, samplesinbuf; - unsigned long low_word, high_word, var; - - unsigned int ui_Tmp; - samplesinbuf = - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] - - inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); - - if (samplesinbuf < - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) { - comedi_error(dev, "Interrupted DMA transfer!"); - } - if (samplesinbuf & 1) { - comedi_error(dev, "Odd count of bytes in DMA ring!"); - i_APCI3120_StopCyclicAcquisition(dev, s); - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - - return; - } - samplesinbuf = samplesinbuf >> 1; /* number of received samples */ - if (devpriv->b_DmaDoubleBuffer) { - /* switch DMA buffers if is used double buffering */ - next_dma_buf = 1 - devpriv->ui_DmaActualBuffer; - - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); - - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ - - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - high_word = var / 65536; - - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - high_word = var / 65536; - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - -/* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 + * Configure Timer 2 + * + * data[0] = TIMER configure as timer + * = WATCHDOG configure as watchdog + * data[1] = Timer constant + * data[2] = Timer2 interrupt (1)enable or(0) disable */ - outw(3, devpriv->i_IobaseAddon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); - - } - if (samplesinbuf) { - v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, - devpriv->ul_DmaBufferVirtual[devpriv-> - ui_DmaActualBuffer], samplesinbuf); - - if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) { - s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); - } - } - if (!devpriv->b_AiContinuous) - if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) { - /* all data sampled */ - i_APCI3120_StopCyclicAcquisition(dev, s); - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - return; - } - - if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */ - devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; - } else { -/* - * restart DMA if is not used double buffering - * ADDED REINITIALISE THE DMA - */ - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); - - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* */ -/* - * A2P FIFO MANAGEMENT - * A2P fifo reset & transfer control enable - */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, - devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); - - var = devpriv->ul_DmaBufferHw[0]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[0]; - high_word = var / 65536; - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - var = devpriv->ui_DmaBufferUsesize[0]; - low_word = var & 0xffff; /* changed */ - var = devpriv->ui_DmaBufferUsesize[0]; - high_word = var / 65536; - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - -/* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - outw(3, devpriv->i_IobaseAddon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); - } -} - -/* -+----------------------------------------------------------------------------+ -| Function name :void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device| -|*dev,struct comedi_subdevice *s,short *dma,short *data,int n) | -| | -+----------------------------------------------------------------------------+ -| Task : This function copies the data from DMA buffer to the | -| Comedi buffer | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| short *dma | -| short *data,int n | -+----------------------------------------------------------------------------+ -| Return Value : void | -| | -+----------------------------------------------------------------------------+ -*/ - -void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, - struct comedi_subdevice *s, short *dma_buffer, unsigned int num_samples) -{ - devpriv->ui_AiActualScan += - (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength; - s->async->cur_chan += num_samples; - s->async->cur_chan %= devpriv->ui_AiScanLength; - - cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short)); -} - -/* -+----------------------------------------------------------------------------+ -| TIMER SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, | -| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task :Configure Timer 2 | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| | -| data[0]= TIMER configure as timer | -| = WATCHDOG configure as watchdog | -| data[1] = Timer constant | -| data[2] = Timer2 interrupt (1)enable or(0) disable | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2; unsigned short us_TmpValue; unsigned char b_Tmp; @@ -2007,37 +1929,24 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, | -| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : To start and stop the timer | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| | -| data[0] = 1 (start) | -| data[0] = 0 (stop ) | -| data[0] = 2 (write new value) | -| data[1]= new value | -| | -| devpriv->b_Timer2Mode = 0 DISABLE | -| 1 Timer | -| 2 Watch dog | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * To start and stop the timer + * + * data[0] = 1 (start) + * = 0 (stop) + * = 2 (write new value) + * data[1] = new value + * + * devpriv->b_Timer2Mode = 0 DISABLE + * = 1 Timer + * = 2 Watch dog + */ +static int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2 = 0; unsigned short us_TmpValue; unsigned char b_Tmp; @@ -2196,31 +2105,19 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice } /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_InsnReadTimer(struct comedi_device *dev, | -| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : read the Timer value | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| for Timer: data[0]= Timer constant | -| | -| for watchdog: data[0]=0 (still running) | -| data[0]=1 (run down) | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Read the Timer value + * + * for Timer: data[0]= Timer constant + * + * for watchdog: data[0] = 0 (still running) + * = 1 (run down) + */ +static int i_APCI3120_InsnReadTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_Tmp; unsigned short us_TmpValue, us_TmpValue_2, us_StatusValue; @@ -2265,299 +2162,52 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice return insn->n; } -/* -+----------------------------------------------------------------------------+ -| DIGITAL INPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, | -| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the specified Digital input channel| -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int ui_Chan, ui_TmpValue; - - ui_Chan = CR_CHAN(insn->chanspec); /* channel specified */ - - /* this_board->di_read(dev,ui_Chan,data); */ - if (ui_Chan <= 3) { - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); - -/* - * since only 1 channel reqd to bring it to last bit it is rotated 8 - * +(chan - 1) times then ANDed with 1 for last bit. - */ - *data = (ui_TmpValue >> (ui_Chan + 8)) & 1; - /* return 0; */ - } else { - /* comedi_error(dev," chan spec wrong"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - } - return insn->n; - -} - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, | -|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the Digital input Port i.e.4channels| -| value is returned in data[0] | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_TmpValue; - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); - /***** state of 4 channels in the 11, 10, 9, 8 bits of status reg - rotated right 8 times to bring them to last four bits - ANDed with oxf for value. - *****/ - - *data = (ui_TmpValue >> 8) & 0xf; - /* this_board->di_bits(dev,data); */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| DIGITAL OUTPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device | -| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task :Configure the output memory ON or OFF | -| | -+----------------------------------------------------------------------------+ -| Input Parameters :struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) -{ - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } - if (data[0]) { - devpriv->b_OutputMemoryStatus = APCI3120_ENABLE; - - } else { - devpriv->b_OutputMemoryStatus = APCI3120_DISABLE; - devpriv->b_DigitalOutputRegister = 0; - } - if (!devpriv->b_OutputMemoryStatus) - ui_Temp = 0; - /* if(!devpriv->b_OutputMemoryStatus ) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, | -| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : write diatal output port | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| data[0] Value to be written -| data[1] :1 Set digital o/p ON -| data[1] 2 Set digital o/p OFF with memory ON -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3120_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - if ((data[0] > devpriv->s_EeParameters.i_DoMaxdata) || (data[0] < 0)) { - - comedi_error(dev, "Data is not valid !!! \n"); - return -EINVAL; - } + struct addi_private *devpriv = dev->private; + unsigned int val; - switch (data[1]) { - case 1: - data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister; - break; - - case 2: - data[0] = data[0]; - break; - default: - printk("\nThe parameter passed is in error \n"); - return -EINVAL; - } /* switch(data[1]) */ - outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT); - - devpriv->b_DigitalOutputRegister = data[0] & 0xF0; + /* the input channels are bits 11:8 of the status reg */ + val = inw(devpriv->iobase + APCI3120_RD_STATUS); + data[1] = (val >> 8) & 0xf; return insn->n; - } -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,| -|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Write digiatl output | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | - data[0] Value to be written - data[1] :1 Set digital o/p ON - data[1] 2 Set digital o/p OFF with memory ON -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3120_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - - unsigned int ui_Temp1; - - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } - if (ui_NoOfChannel > devpriv->s_EeParameters.i_NbrDoChannel - 1) { - comedi_error(dev, - "This board doesn't have specified channel !!! \n"); - return -EINVAL; + struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; + unsigned int val; + + /* The do channels are bits 7:4 of the do register */ + val = devpriv->b_DigitalOutputRegister >> 4; + if (mask) { + val &= ~mask; + val |= (bits & mask); + devpriv->b_DigitalOutputRegister = val << 4; + + outb(val << 4, devpriv->iobase + APCI3120_DIGITAL_OUTPUT); } - switch (data[1]) { - case 1: - data[0] = (data[0] << ui_NoOfChannel); -/* ES05 data[0]=(data[0]<<4)|ui_Temp; */ - data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister; - break; + data[1] = val; - case 2: - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp1 = ui_Temp1 << 4; -/* ES05 ui_Temp=ui_Temp|ui_Temp1; */ - devpriv->b_DigitalOutputRegister = - devpriv->b_DigitalOutputRegister | ui_Temp1; - - data[0] = (data[0] << ui_NoOfChannel) ^ 0xf; - data[0] = data[0] << 4; -/* ES05 data[0]=data[0]& ui_Temp; */ - data[0] = data[0] & devpriv->b_DigitalOutputRegister; - break; - default: - printk("\nThe parameter passed is in error \n"); - return -EINVAL; - } /* switch(data[1]) */ - outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT); - -/* ES05 ui_Temp=data[0] & 0xf0; */ - devpriv->b_DigitalOutputRegister = data[0] & 0xf0; return insn->n; - } -/* -+----------------------------------------------------------------------------+ -| ANALOG OUTPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,| -|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Write analog output | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Range, ui_Channel; unsigned short us_TmpValue; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h deleted file mode 100644 index 50eb0a0..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h +++ /dev/null @@ -1,249 +0,0 @@ - -/* hwdrv_apci3120.h */ - -/* - * 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 - * - * 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. - */ - -/* comedi related defines */ - -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3120_ai = { 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) - } -}; - -/* ANALOG OUTPUT RANGE */ -static const struct comedi_lrange range_apci3120_ao = { 2, { - BIP_RANGE(10), - UNI_RANGE(10) - } -}; - -#define APCI3120_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */ - -#define APCI3120_BOARD_VENDOR_ID 0x10E8 -#define APCI3120_ADDRESS_RANGE 16 - -#define APCI3120_DISABLE 0 -#define APCI3120_ENABLE 1 - -#define APCI3120_START 1 -#define APCI3120_STOP 0 - -#define APCI3120_EOC_MODE 1 -#define APCI3120_EOS_MODE 2 -#define APCI3120_DMA_MODE 3 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI3120_DIGITAL_OUTPUT 0x0D -#define APCI3120_RD_STATUS 0x02 -#define APCI3120_RD_FIFO 0x00 - -/* digital output insn_write ON /OFF selection */ -#define APCI3120_SET4DIGITALOUTPUTON 1 -#define APCI3120_SET4DIGITALOUTPUTOFF 0 - -/* analog output SELECT BIT */ -#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000 -#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000 - -/* Enable external trigger bit in nWrAddress */ -#define APCI3120_ENABLE_EXT_TRIGGER 0x8000 - -/* ANALOG OUTPUT AND INPUT DEFINE */ -#define APCI3120_UNIPOLAR 0x80 /* $$ RAM sequence polarity BIT */ -#define APCI3120_BIPOLAR 0x00 /* $$ RAM sequence polarity BIT */ -#define APCI3120_ANALOG_OUTPUT_1 0x08 /* (ADDRESS ) */ -#define APCI3120_ANALOG_OUTPUT_2 0x0A /* (ADDRESS ) */ -#define APCI3120_1_GAIN 0x00 /* $$ RAM sequence Gain Bits for gain 1 */ -#define APCI3120_2_GAIN 0x10 /* $$ RAM sequence Gain Bits for gain 2 */ -#define APCI3120_5_GAIN 0x20 /* $$ RAM sequence Gain Bits for gain 5 */ -#define APCI3120_10_GAIN 0x30 /* $$ RAM sequence Gain Bits for gain 10 */ -#define APCI3120_SEQ_RAM_ADDRESS 0x06 /* $$ EARLIER NAMED APCI3120_FIFO_ADDRESS */ -#define APCI3120_RESET_FIFO 0x0C /* (ADDRESS) */ -#define APCI3120_TIMER_0_MODE_2 0x01 /* $$ Bits for timer mode */ -#define APCI3120_TIMER_0_MODE_4 0x2 -#define APCI3120_SELECT_TIMER_0_WORD 0x00 -#define APCI3120_ENABLE_TIMER0 0x1000 /* $$Gatebit 0 in nWrAddress */ -#define APCI3120_CLEAR_PR 0xF0FF -#define APCI3120_CLEAR_PA 0xFFF0 -#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA) - -/* nWrMode_Select */ -#define APCI3120_ENABLE_SCAN 0x8 /* $$ bit in nWrMode_Select */ -#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) -#define APCI3120_ENABLE_EOS_INT 0x2 /* $$ bit in nWrMode_Select */ - -#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) -#define APCI3120_ENABLE_EOC_INT 0x1 -#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) - -/* status register bits */ -#define APCI3120_EOC 0x8000 -#define APCI3120_EOS 0x2000 - -/* software trigger dummy register */ -#define APCI3120_START_CONVERSION 0x02 /* (ADDRESS) */ - -/* TIMER DEFINE */ -#define APCI3120_QUARTZ_A 70 -#define APCI3120_QUARTZ_B 50 -#define APCI3120_TIMER 1 -#define APCI3120_WATCHDOG 2 -#define APCI3120_TIMER_DISABLE 0 -#define APCI3120_TIMER_ENABLE 1 -#define APCI3120_ENABLE_TIMER2 0x4000 /* $$ gatebit 2 in nWrAddress */ -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) -#define APCI3120_ENABLE_TIMER_INT 0x04 /* $$ ENAIRQ_FC_Bit in nWrModeSelect */ -#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) -#define APCI3120_WRITE_MODE_SELECT 0x0E /* (ADDRESS) */ -#define APCI3120_SELECT_TIMER_0_WORD 0x00 -#define APCI3120_SELECT_TIMER_1_WORD 0x01 -#define APCI3120_TIMER_1_MODE_2 0x4 - -/* $$ BIT FOR MODE IN nCsTimerCtr1 */ -#define APCI3120_TIMER_2_MODE_0 0x0 -#define APCI3120_TIMER_2_MODE_2 0x10 -#define APCI3120_TIMER_2_MODE_5 0x30 - -/* $$ BIT FOR MODE IN nCsTimerCtr0 */ -#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02 -#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03 - -#define APCI3120_TIMER_CRT0 0x0D /* (ADDRESS for cCsTimerCtr0) */ -#define APCI3120_TIMER_CRT1 0x0C /* (ADDRESS for cCsTimerCtr1) */ - -#define APCI3120_TIMER_VALUE 0x04 /* ADDRESS for nCsTimerWert */ -#define APCI3120_TIMER_STATUS_REGISTER 0x0D /* ADDRESS for delete timer 2 interrupt */ -#define APCI3120_RD_STATUS 0x02 /* ADDRESS */ -#define APCI3120_WR_ADDRESS 0x00 /* ADDRESS */ -#define APCI3120_ENABLE_WATCHDOG 0x20 /* $$BIT in nWrMode_Select */ -#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) -#define APCI3120_ENABLE_TIMER_COUNTER 0x10 /* $$BIT in nWrMode_Select */ -#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER) -#define APCI3120_FC_TIMER 0x1000 /* bit in status register */ -#define APCI3120_ENABLE_TIMER0 0x1000 -#define APCI3120_ENABLE_TIMER1 0x2000 -#define APCI3120_ENABLE_TIMER2 0x4000 -#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0) -#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1) -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) - -#define APCI3120_TIMER2_SELECT_EOS 0xC0 /* ADDED on 20-6 */ -#define APCI3120_COUNTER 3 /* on 20-6 */ -#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2) /* on 20-6 */ - -#define MAX_ANALOGINPUT_CHANNELS 32 - -struct str_AnalogReadInformation { - - unsigned char b_Type; /* EOC or EOS */ - unsigned char b_InterruptFlag; /* Interrupt use or not */ - unsigned int ui_ConvertTiming; /* Selection of the conversion time */ - unsigned char b_NbrOfChannel; /* Number of channel to read */ - unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */ - unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */ - -}; - - -/* Function Declaration For APCI-3120 */ - -/* Internal functions */ -int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s, - int n_chan, unsigned int *chanlist, char check); -int i_APCI3120_ExttrigEnable(struct comedi_device *dev); -int i_APCI3120_ExttrigDisable(struct comedi_device *dev); -int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s); -int i_APCI3120_Reset(struct comedi_device *dev); -int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, - struct comedi_subdevice *s); -/* Interrupt functions */ -void v_APCI3120_Interrupt(int irq, void *d); -/* UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n); */ -void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, - struct comedi_subdevice *s, - short *dma_buffer, - unsigned int num_samples); -int i_APCI3120_InterruptHandleEos(struct comedi_device *dev); -void v_APCI3120_InterruptDma(int irq, void *d); - -/* TIMER */ - -int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* DI for di read -*/ - -int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* DO */ -/* int i_APCI3120_WriteDigitalOutput(struct comedi_device *dev, - * unsigned char data); - */ -int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* AO */ -/* int i_APCI3120_Write1AnalogValue(struct comedi_device *dev,UINT ui_Range, - * UINT ui_Channel,UINT data ); - */ - -int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* AI HArdware layer */ - -int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s); -/* int i_APCI3120_CancelAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s); */ -int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 38ab499..829af18 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -51,15 +51,131 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* - +----------------------------------------------------------------------------+ - | Included files | - +----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci3200.h" - /* #define PRINT_INFO */ +/* Card Specific information */ +/* #define APCI3200_ADDRESS_RANGE 264 */ + +/* Analog Input related Defines */ +#define APCI3200_AI_OFFSET_GAIN 0 +#define APCI3200_AI_SC_TEST 4 +#define APCI3200_AI_IRQ 8 +#define APCI3200_AI_AUTOCAL 12 +#define APCI3200_RELOAD_CONV_TIME_VAL 32 +#define APCI3200_CONV_TIME_TIME_BASE 36 +#define APCI3200_RELOAD_DELAY_TIME_VAL 40 +#define APCI3200_DELAY_TIME_TIME_BASE 44 +#define APCI3200_AI_MODULE1 0 +#define APCI3200_AI_MODULE2 64 +#define APCI3200_AI_MODULE3 128 +#define APCI3200_AI_MODULE4 192 +#define TRUE 1 +#define FALSE 0 +#define APCI3200_AI_EOSIRQ 16 +#define APCI3200_AI_EOS 20 +#define APCI3200_AI_CHAN_ID 24 +#define APCI3200_AI_CHAN_VAL 28 +#define ANALOG_INPUT 0 +#define TEMPERATURE 1 +#define RESISTANCE 2 + +#define ENABLE_EXT_TRIG 1 +#define ENABLE_EXT_GATE 2 +#define ENABLE_EXT_TRIG_GATE 3 + +#define APCI3200_MAXVOLT 2.5 +#define ADDIDATA_GREATER_THAN_TEST 0 +#define ADDIDATA_LESS_THAN_TEST 1 + +#define ADDIDATA_UNIPOLAR 1 +#define ADDIDATA_BIPOLAR 2 + +#define MAX_MODULE 4 + +/* ANALOG INPUT RANGE */ +static const struct comedi_lrange range_apci3200_ai = { + 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 range_apci3300_ai = { + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; + +int MODULE_NO; +struct { + int i_Gain; + int i_Polarity; + int i_OffsetRange; + int i_Coupling; + int i_SingleDiff; + int i_AutoCalibration; + unsigned int ui_ReloadValue; + unsigned int ui_TimeUnitReloadVal; + int i_Interrupt; + int i_ModuleSelection; +} Config_Parameters_Module1, Config_Parameters_Module2, + Config_Parameters_Module3, Config_Parameters_Module4; + + +struct str_ADDIDATA_RTDStruct { + unsigned int ul_NumberOfValue; + unsigned int *pul_ResistanceValue; + unsigned int *pul_TemperatureValue; +}; + +struct str_Module { + unsigned long ul_CurrentSourceCJC; + unsigned long ul_CurrentSource[5]; + unsigned long ul_GainFactor[8]; /* Gain Factor */ + unsigned int w_GainValue[10]; +}; + +struct str_BoardInfos { + + int i_CJCAvailable; + int i_CJCPolarity; + int i_CJCGain; + int i_InterruptFlag; + int i_ADDIDATAPolarity; + int i_ADDIDATAGain; + int i_AutoCalibration; + int i_ADDIDATAConversionTime; + int i_ADDIDATAConversionTimeUnit; + int i_ADDIDATAType; + int i_ChannelNo; + int i_ChannelCount; + int i_ScanType; + int i_FirstChannel; + int i_LastChannel; + int i_Sum; + int i_Offset; + unsigned int ui_Channel_num; + int i_Count; + int i_Initialised; + unsigned int ui_InterruptChannelValue[144]; /* Buffer */ + unsigned char b_StructInitialized; + /* 7 is the maximal number of channels */ + unsigned int ui_ScanValueArray[7 + 12]; + + int i_ConnectionType; + int i_NbrOfModule; + struct str_Module s_Module[MAX_MODULE]; +}; + /* BEGIN JK 06.07.04: Management of sevrals boards */ /* int i_CJCAvailable=1; @@ -94,27 +210,10 @@ struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of board #define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ #define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */ -/*+----------------------------------------------------------------------------+*/ -/*| Function Name : int i_AddiHeaderRW_ReadEeprom |*/ -/*| (int i_NbOfWordsToRead, |*/ -/*| unsigned int dw_PCIBoardEepromAddress, |*/ -/*| unsigned short w_EepromStartAddress, |*/ -/*| unsigned short * pw_DataRead) |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Task : Read word from the 5920 eeprom. |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/ -/*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/ -/*| unsigned short w_EepromStartAddress : Eeprom start address |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Output Parameters : unsigned short * pw_DataRead : Read data |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Return Value : - |*/ -/*+----------------------------------------------------------------------------+*/ - -int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, - unsigned int dw_PCIBoardEepromAddress, - unsigned short w_EepromStartAddress, unsigned short *pw_DataRead) +static int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, + unsigned int dw_PCIBoardEepromAddress, + unsigned short w_EepromStartAddress, + unsigned short *pw_DataRead) { unsigned int dw_eeprom_busy = 0; int i_Counter = 0; @@ -241,20 +340,8 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, return 0; } -/*+----------------------------------------------------------------------------+*/ -/*| Function Name : void v_GetAPCI3200EepromCalibrationValue (void) |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Task : Read calibration value from the APCI-3200 eeprom. |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Input Parameters : - |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Output Parameters : - |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Return Value : - |*/ -/*+----------------------------------------------------------------------------+*/ - -void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, - struct str_BoardInfos *BoardInformations) +static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, + struct str_BoardInfos *BoardInformations) { unsigned short w_AnalogInputMainHeaderAddress; unsigned short w_AnalogInputComponentAddress; @@ -448,9 +535,11 @@ void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, } } -int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, - unsigned int ui_Channel_num, unsigned int *CJCCurrentSource, - unsigned int *ChannelCurrentSource, unsigned int *ChannelGainFactor) +static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, + unsigned int ui_Channel_num, + unsigned int *CJCCurrentSource, + unsigned int *ChannelCurrentSource, + unsigned int *ChannelGainFactor) { int i_DiffChannel = 0; int i_Module = 0; @@ -520,1135 +609,46 @@ int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, return 0; } -/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadDigitalInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel or port | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read for Port - Channel Numberfor single channel - | unsigned int data[0] : 0: Read single channel - 1: Read port value - data[1] Port number - +----------------------------------------------------------------------------+ - | Output Parameters : -- data[0] :Read status value - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int apci3200_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_Temp = 0; - unsigned int ui_NoOfChannel = 0; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->i_IobaseReserved); - - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - if (data[1] < 0 || data[1] > 1) { - printk("\nThe port number is in error\n"); - return -EINVAL; - } /* if(data[1] < 0 || data[1] >1) */ - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 0x3; - break; - case 3: - *data = (*data & 15); - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif (ui_Temp==1) */ - } - return insn->n; -} + struct addi_private *devpriv = dev->private; -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ConfigDigitalOutput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Configures The Digital Output Subdevice. | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | data[0] :1 Memory enable - 0 Memory Disable - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ + data[1] = inl(devpriv->i_IobaseReserved) & 0xf; - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } /* if ( (data[0]!=0) && (data[0]!=1) ) */ - if (data[0]) { - devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0]) */ - else { - devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0]) */ return insn->n; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_WriteDigitalOutput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : writes To the digital Output Subdevice | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer contains | - | configuration parameters as below | - | data[0] :Value to output - data[1] : 0 o/p single channel - 1 o/p port - data[2] : port no - data[3] :0 set the digital o/p on - 1 set the digital o/p off - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int apci3200_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_Temp = 0, ui_Temp1 = 0; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inl(devpriv->i_IobaseAddon); - - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - case 3: - data[0] = (data[0] | ui_Temp); - break; - } /* switch(ui_NoOfChannels) */ - - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xf; - data[0] = data[0] & ui_Temp; - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xf) & ui_Temp; - - break; - case 3: - break; - - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} - -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadDigitalOutput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel or port | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read | - | unsigned int *data : Data Pointer to read status | - data[0] :0 read single channel - 1 read port value - data[1] port no - - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->i_IobaseAddon); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - if (data[1] < 0 || data[1] > 1) { - printk("\nThe port selection is in error\n"); - return -EINVAL; - } /* if(data[1] <0 ||data[1] >1) */ - switch (ui_NoOfChannel) { - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 3: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* else if (ui_Temp==0) */ - return insn->n; -} - -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ConfigAnalogInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Configures The Analog Input Subdevice | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer contains | - | configuration parameters as below | - | | - | data[0] - | 0:Normal AI | - | 1:RTD | - | 2:THERMOCOUPLE | - | data[1] : Gain To Use | - | | - | data[2] : Polarity - | 0:Bipolar | - | 1:Unipolar | - | | - | data[3] : Offset Range - | | - | data[4] : Coupling - | 0:DC Coupling | - | 1:AC Coupling | - | | - | data[5] :Differential/Single - | 0:Single | - | 1:Differential | - | | - | data[6] :TimerReloadValue - | | - | data[7] :ConvertingTimeUnit - | | - | data[8] :0 Analog voltage measurement - 1 Resistance measurement - 2 Temperature measurement - | data[9] :Interrupt - | 0:Disable - | 1:Enable - data[10] :Type of Thermocouple - | data[11] : 0: single channel - Module Number - | - | data[12] - | 0:Single Read - | 1:Read more channel - 2:Single scan - | 3:Continuous Scan - data[13] :Number of channels to read - | data[14] :RTD connection type - :0:RTD not used - 1:RTD 2 wire connection - 2:RTD 3 wire connection - 3:RTD 4 wire connection - | | - | | - | | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - unsigned int ul_Config = 0, ul_Temp = 0; - unsigned int ui_ChannelNo = 0; - unsigned int ui_Dummy = 0; - int i_err = 0; - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - -#ifdef PRINT_INFO - int i = 0, i2 = 0; -#endif - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* Initialize the structure */ - if (s_BoardInfos[dev->minor].b_StructInitialized != 1) { - s_BoardInfos[dev->minor].i_CJCAvailable = 1; - s_BoardInfos[dev->minor].i_CJCPolarity = 0; - s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */ - s_BoardInfos[dev->minor].i_ChannelCount = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].ui_Channel_num = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 1; - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_ConnectionType = 0; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - memset(s_BoardInfos[dev->minor].s_Module, 0, - sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE])); - - v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc, - &s_BoardInfos[dev->minor]); - -#ifdef PRINT_INFO - for (i = 0; i < MAX_MODULE; i++) { - printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i, - s_BoardInfos[dev->minor].s_Module[i]. - ul_CurrentSourceCJC); - - for (i2 = 0; i2 < 5; i2++) { - printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]); - } - - for (i2 = 0; i2 < 8; i2++) { - printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]); - } - - for (i2 = 0; i2 < 8; i2++) { - printk("\n s_Module[%i].w_GainValue [%i] = %u", - i, i2, - s_BoardInfos[dev->minor].s_Module[i]. - w_GainValue[i2]); - } - } -#endif - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - - if (data[0] != 0 && data[0] != 1 && data[0] != 2) { - printk("\nThe selection of acquisition type is in error\n"); - i_err++; - } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */ - if (data[0] == 1) { - if (data[14] != 0 && data[14] != 1 && data[14] != 2 - && data[14] != 4) { - printk("\n Error in selection of RTD connection type\n"); - i_err++; - } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */ - } /* if(data[0]==1 ) */ - if (data[1] < 0 || data[1] > 7) { - printk("\nThe selection of gain is in error\n"); - i_err++; - } /* if(data[1]<0 || data[1]>7) */ - if (data[2] != 0 && data[2] != 1) { - printk("\nThe selection of polarity is in error\n"); - i_err++; - } /* if(data[2]!=0 && data[2]!=1) */ - if (data[3] != 0) { - printk("\nThe selection of offset range is in error\n"); - i_err++; - } /* if(data[3]!=0) */ - if (data[4] != 0 && data[4] != 1) { - printk("\nThe selection of coupling is in error\n"); - i_err++; - } /* if(data[4]!=0 && data[4]!=1) */ - if (data[5] != 0 && data[5] != 1) { - printk("\nThe selection of single/differential mode is in error\n"); - i_err++; - } /* if(data[5]!=0 && data[5]!=1) */ - if (data[8] != 0 && data[8] != 1 && data[2] != 2) { - printk("\nError in selection of functionality\n"); - } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */ - if (data[12] == 0 || data[12] == 1) { - if (data[6] != 20 && data[6] != 40 && data[6] != 80 - && data[6] != 160) { - printk("\nThe selection of conversion time reload value is in error\n"); - i_err++; - } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */ - if (data[7] != 2) { - printk("\nThe selection of conversion time unit is in error\n"); - i_err++; - } /* if(data[7]!=2) */ - } - if (data[9] != 0 && data[9] != 1) { - printk("\nThe selection of interrupt enable is in error\n"); - i_err++; - } /* if(data[9]!=0 && data[9]!=1) */ - if (data[11] < 0 || data[11] > 4) { - printk("\nThe selection of module is in error\n"); - i_err++; - } /* if(data[11] <0 || data[11]>1) */ - if (data[12] < 0 || data[12] > 3) { - printk("\nThe selection of singlechannel/scan selection is in error\n"); - i_err++; - } /* if(data[12] < 0 || data[12]> 3) */ - if (data[13] < 0 || data[13] > 16) { - printk("\nThe selection of number of channels is in error\n"); - i_err++; - } /* if(data[13] <0 ||data[13] >15) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* - i_ChannelCount=data[13]; - i_ScanType=data[12]; - i_ADDIDATAPolarity = data[2]; - i_ADDIDATAGain=data[1]; - i_ADDIDATAConversionTime=data[6]; - i_ADDIDATAConversionTimeUnit=data[7]; - i_ADDIDATAType=data[0]; - */ - - /* Save acquisition configuration for the actual board */ - s_BoardInfos[dev->minor].i_ChannelCount = data[13]; - s_BoardInfos[dev->minor].i_ScanType = data[12]; - s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2]; - s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7]; - s_BoardInfos[dev->minor].i_ADDIDATAType = data[0]; - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - s_BoardInfos[dev->minor].i_ConnectionType = data[5]; - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* END JK 06.07.04: Management of sevrals boards */ - - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */ - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - /* while(i_InterruptFlag==1) */ - while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { -#ifndef MSXBOX - udelay(1); -#else - /* In the case where the driver is compiled for the MSX-Box */ - /* we used a printk to have a little delay because udelay */ - /* seems to be broken under the MSX-Box. */ - /* This solution hat to be studied. */ - printk(""); -#endif - } - /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - - ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=ui_ChannelNo; */ - /* ui_Channel_num =ui_ChannelNo; */ - - s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo; - s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo; - - /* END JK 06.07.04: Management of sevrals boards */ - - if (data[5] == 0) { - if (ui_ChannelNo < 0 || ui_ChannelNo > 15) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */ - } /* if(data[5]==0) */ - else { - if (data[14] == 2) { - if (ui_ChannelNo < 0 || ui_ChannelNo > 3) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */ - } /* if(data[14]==2) */ - else { - if (ui_ChannelNo < 0 || ui_ChannelNo > 7) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */ - } /* elseif(data[14]==2) */ - } /* elseif(data[5]==0) */ - if (data[12] == 0 || data[12] == 1) { - switch (data[5]) { - case 0: - if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */ - if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */ - if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */ - break; - case 1: - if (data[14] == 2) { - if (ui_ChannelNo == 0) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==0 ) */ - if (ui_ChannelNo == 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==1) */ - if (ui_ChannelNo == 2) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==2 ) */ - if (ui_ChannelNo == 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==3) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=0; */ - s_BoardInfos[dev->minor].i_ChannelNo = 0; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = 0; - break; - } /* if(data[14]==2) */ - if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */ - if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-2; */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 2; - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 2; - } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-4; */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 4; - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 4; - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */ - if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-6; */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 6; - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 6; - } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */ - break; - - default: - printk("\n This selection of polarity does not exist\n"); - i_err++; - } /* switch(data[2]) */ - } /* if(data[12]==0 || data[12]==1) */ - else { - switch (data[11]) { - case 1: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 2: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 3: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 4: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - break; - default: - printk("\nError in module selection\n"); - i_err++; - } /* switch(data[11]) */ - } /* elseif(data[12]==0 || data[12]==1) */ - if (i_err) { - i_APCI3200_Reset(dev); - return -EINVAL; - } - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Count=0; */ - /* i_Sum=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ScanType!=1) */ - - ul_Config = - data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) | - (data[4] << 9); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */ - outl(0 | ui_ChannelNo, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - /**************************/ - /* Reset the configuration */ - /**************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 , devpriv->iobase+i_Offset + 0x0); */ - outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - - /***************************/ - /* Write the configuration */ - /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */ - outl(ul_Config, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ - - /***************************/ - /*Reset the calibration bit */ - /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */ - ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */ - outl((ul_Temp & 0xFFF9FFFF), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ + struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; - if (data[9] == 1) { - devpriv->tsk_Current = current; - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=1; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 1; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(data[9]==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* else if(data[9]==1) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Initialised=1; */ - s_BoardInfos[dev->minor].i_Initialised = 1; - /* END JK 06.07.04: Management of sevrals boards */ + s->state = inl(devpriv->i_IobaseAddon) & 0xf; + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask) - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor].i_ScanType == 1) - /* END JK 06.07.04: Management of sevrals boards */ - { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Sum=i_Sum+1; */ - s_BoardInfos[dev->minor].i_Sum = - s_BoardInfos[dev->minor].i_Sum + 1; - /* END JK 06.07.04: Management of sevrals boards */ - - insn->unused[0] = 0; - i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy); + outl(s->state, devpriv->i_IobaseAddon); } - return insn->n; -} - -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadAnalogInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Digital Value Of Input | - | data[1] : Calibration Offset Value | - | data[2] : Calibration Gain Value - | data[3] : CJC value - | data[4] : CJC offset value - | data[5] : CJC gain value - | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values - | data[6] : CJC current source from eeprom - | data[7] : Channel current source from eeprom - | data[8] : Channle gain factor from eeprom - | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_DummyValue = 0; - int i_ConvertCJCCalibration; - int i = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_Initialised==0) */ - if (s_BoardInfos[dev->minor].i_Initialised == 0) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_Reset(dev); - return -EINVAL; - } /* if(i_Initialised==0); */ - -#ifdef PRINT_INFO - printk("\n insn->unused[0] = %i", insn->unused[0]); -#endif - - switch (insn->unused[0]) { - case 0: - - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 0] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - - /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 6], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 7], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 8]); - -#ifdef PRINT_INFO - printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]); - - printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]); - - printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]); -#endif - - /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCJCValue(dev, &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=0; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCalibrationOffsetValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 1] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 2] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - /**********************************************************/ - /*Test if the Calibration channel must be read for the CJC */ - /**********************************************************/ - /**********************************/ - /*Test if the polarity is the same */ - /**********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (s_BoardInfos[dev->minor].i_CJCPolarity != - s_BoardInfos[dev->minor].i_ADDIDATAPolarity) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 1; - } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCGain==i_ADDIDATAGain) */ - if (s_BoardInfos[dev->minor].i_CJCGain == - s_BoardInfos[dev->minor].i_ADDIDATAGain) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 0; - } /* if(i_CJCGain==i_ADDIDATAGain) */ - else { - i_ConvertCJCCalibration = 1; - } /* elseif(i_CJCGain==i_ADDIDATAGain) */ - } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (i_ConvertCJCCalibration == 1) { - i_APCI3200_ReadCJCCalOffset(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - - i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue); - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ConvertCJCCalibration==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=0; */ - /* ui_InterruptChannelValue[i_Count+5]=0; */ - - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = 0; - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif(i_ConvertCJCCalibration==1) */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* i_Count=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - } /* if(i_ScanType!=1) */ - else { - /* i_Count=i_Count +6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* else if(i_ScanType!=1) */ - - /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */ - if ((s_BoardInfos[dev->minor].i_ScanType == 1) - && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) { - /* i_Count=i_Count-6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count - 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - /* if(i_ScanType==0) */ - if (s_BoardInfos[dev->minor].i_ScanType == 0) { - /* - data[0]= ui_InterruptChannelValue[0]; - data[1]= ui_InterruptChannelValue[1]; - data[2]= ui_InterruptChannelValue[2]; - data[3]= ui_InterruptChannelValue[3]; - data[4]= ui_InterruptChannelValue[4]; - data[5]= ui_InterruptChannelValue[5]; - */ -#ifdef PRINT_INFO - printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];"); -#endif - data[0] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[0]; - data[1] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[1]; - data[2] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[2]; - data[3] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[3]; - data[4] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[4]; - data[5] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[5]; - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &data[6], &data[7], &data[8]); - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - break; - case 1: - - for (i = 0; i < insn->n; i++) { - /* data[i]=ui_InterruptChannelValue[i]; */ - data[i] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[i]; - } - - /* i_Count=0; */ - /* i_Sum=0; */ - /* if(i_ScanType==1) */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - if (s_BoardInfos[dev->minor].i_ScanType == 1) { - /* i_Initialised=0; */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } - break; - default: - printk("\nThe parameters passed are in error\n"); - i_APCI3200_Reset(dev); - return -EINVAL; - } /* switch(insn->unused[0]) */ + data[1] = s->state; return insn->n; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_Read1AnalogInputChannel | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannel : Channel No to read | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Digital Value read | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; unsigned int ui_ChannelNo = 0; unsigned int ui_CommandRegister = 0; @@ -1751,28 +751,10 @@ int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCalibrationOffsetValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read calibration offset value of the selected channel| - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Calibration offset Value | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp = 0, ui_EOC = 0; unsigned int ui_CommandRegister = 0; @@ -1887,28 +869,10 @@ int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned in return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCalibrationGainValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read calibration gain value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Calibration gain Value Of Input | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; @@ -2022,29 +986,10 @@ int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCJCValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read CJC value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : CJC Value | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_ReadCJCValue(struct comedi_device *dev, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; @@ -2142,30 +1087,13 @@ int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data) return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCJCCalOffset | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read CJC calibration offset value of the selected channel - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : CJC calibration offset Value - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; + /*******************************************/ /*Read calibration offset value for the CJC */ /*******************************************/ @@ -2257,31 +1185,13 @@ int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data) return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCJCGainValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read CJC calibration gain value - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : CJC calibration gain value - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; + /*******************************/ /* Set the convert timing unit */ /*******************************/ @@ -2367,43 +1277,842 @@ int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data) return 0; } +static int i_APCI3200_Reset(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + int i_Temp; + unsigned int dw_Dummy; + + /* i_InterruptFlag=0; */ + /* i_Initialised==0; */ + /* i_Count=0; */ + /* i_Sum=0; */ + + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + s_BoardInfos[dev->minor].i_Initialised = 0; + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + s_BoardInfos[dev->minor].b_StructInitialized = 0; + + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + outl(0, devpriv->i_IobaseAddon); /* Resets the output */ + /***************/ + /*Empty the buffer */ + /**************/ + for (i_Temp = 0; i_Temp <= 95; i_Temp++) { + /* ui_InterruptChannelValue[i_Temp]=0; */ + s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0; + } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */ + /*****************************/ + /*Reset the START and IRQ bit */ + /*****************************/ + for (i_Temp = 0; i_Temp <= 192;) { + while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ; + outl(0, devpriv->iobase + i_Temp + 8); + i_Temp = i_Temp + 64; + } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */ + return 0; +} + /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_InsnBits_AnalogInput_Test | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Tests the Selected Anlog Input Channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer contains | - | configuration parameters as below | - | - | - | data[0] : 0 TestAnalogInputShortCircuit - | 1 TestAnalogInputConnection | - - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Digital value obtained | - | data[1] : calibration offset | - | data[2] : calibration gain | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ + * Read value of the selected channel + * + * data[0] : Digital Value Of Input + * data[1] : Calibration Offset Value + * data[2] : Calibration Gain Value + * data[3] : CJC value + * data[4] : CJC offset value + * data[5] : CJC gain value + * data[6] : CJC current source from eeprom + * data[7] : Channel current source from eeprom + * data[8] : Channle gain factor from eeprom + */ +static int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int ui_DummyValue = 0; + int i_ConvertCJCCalibration; + int i = 0; + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_Initialised==0) */ + if (s_BoardInfos[dev->minor].i_Initialised == 0) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_APCI3200_Reset(dev); + return -EINVAL; + } /* if(i_Initialised==0); */ + +#ifdef PRINT_INFO + printk("\n insn->unused[0] = %i", insn->unused[0]); +#endif + + switch (insn->unused[0]) { + case 0: -int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) + i_APCI3200_Read1AnalogInputChannel(dev, s, insn, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 0] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + + /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + i_APCI3200_GetChannelCalibrationValue(dev, + s_BoardInfos[dev->minor].ui_Channel_num, + &s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 6], + &s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 7], + &s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 8]); + +#ifdef PRINT_INFO + printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]); + + printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]); + + printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]); +#endif + + /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ + if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) + && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) + && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_APCI3200_ReadCJCValue(dev, &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 3] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 3]=0; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 3] = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ + if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) + && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_APCI3200_ReadCalibrationOffsetValue(dev, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 1] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + i_APCI3200_ReadCalibrationGainValue(dev, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 2] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */ + if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) + && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) + && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) + /* END JK 06.07.04: Management of sevrals boards */ + { + /**********************************************************/ + /*Test if the Calibration channel must be read for the CJC */ + /**********************************************************/ + /**********************************/ + /*Test if the polarity is the same */ + /**********************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ + if (s_BoardInfos[dev->minor].i_CJCPolarity != + s_BoardInfos[dev->minor].i_ADDIDATAPolarity) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_ConvertCJCCalibration = 1; + } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_CJCGain==i_ADDIDATAGain) */ + if (s_BoardInfos[dev->minor].i_CJCGain == + s_BoardInfos[dev->minor].i_ADDIDATAGain) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_ConvertCJCCalibration = 0; + } /* if(i_CJCGain==i_ADDIDATAGain) */ + else { + i_ConvertCJCCalibration = 1; + } /* elseif(i_CJCGain==i_ADDIDATAGain) */ + } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ + if (i_ConvertCJCCalibration == 1) { + i_APCI3200_ReadCJCCalOffset(dev, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 4] = + ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + + i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue); + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 5] = + ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(i_ConvertCJCCalibration==1) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+4]=0; */ + /* ui_InterruptChannelValue[i_Count+5]=0; */ + + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 4] = 0; + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 5] = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* elseif(i_ConvertCJCCalibration==1) */ + } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_ScanType!=1) */ + if (s_BoardInfos[dev->minor].i_ScanType != 1) { + /* i_Count=0; */ + s_BoardInfos[dev->minor].i_Count = 0; + } /* if(i_ScanType!=1) */ + else { + /* i_Count=i_Count +6; */ + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */ + s_BoardInfos[dev->minor].i_Count = + s_BoardInfos[dev->minor].i_Count + 9; + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } /* else if(i_ScanType!=1) */ + + /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */ + if ((s_BoardInfos[dev->minor].i_ScanType == 1) + && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) { + /* i_Count=i_Count-6; */ + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */ + s_BoardInfos[dev->minor].i_Count = + s_BoardInfos[dev->minor].i_Count - 9; + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } + /* if(i_ScanType==0) */ + if (s_BoardInfos[dev->minor].i_ScanType == 0) { + /* + data[0]= ui_InterruptChannelValue[0]; + data[1]= ui_InterruptChannelValue[1]; + data[2]= ui_InterruptChannelValue[2]; + data[3]= ui_InterruptChannelValue[3]; + data[4]= ui_InterruptChannelValue[4]; + data[5]= ui_InterruptChannelValue[5]; + */ +#ifdef PRINT_INFO + printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];"); +#endif + data[0] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[0]; + data[1] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[1]; + data[2] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[2]; + data[3] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[3]; + data[4] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[4]; + data[5] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[5]; + + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */ + i_APCI3200_GetChannelCalibrationValue(dev, + s_BoardInfos[dev->minor].ui_Channel_num, + &data[6], &data[7], &data[8]); + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } + break; + case 1: + + for (i = 0; i < insn->n; i++) { + /* data[i]=ui_InterruptChannelValue[i]; */ + data[i] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[i]; + } + + /* i_Count=0; */ + /* i_Sum=0; */ + /* if(i_ScanType==1) */ + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + if (s_BoardInfos[dev->minor].i_ScanType == 1) { + /* i_Initialised=0; */ + /* i_InterruptFlag=0; */ + s_BoardInfos[dev->minor].i_Initialised = 0; + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } + break; + default: + printk("\nThe parameters passed are in error\n"); + i_APCI3200_Reset(dev); + return -EINVAL; + } /* switch(insn->unused[0]) */ + + return insn->n; +} + +/* + * Configures The Analog Input Subdevice + * + * data[0] = 0 Normal AI + * = 1 RTD + * = 2 THERMOCOUPLE + * data[1] = Gain To Use + * data[2] = 0 Bipolar + * = 1 Unipolar + * data[3] = Offset Range + * data[4] = 0 DC Coupling + * = 1 AC Coupling + * data[5] = 0 Single + * = 1 Differential + * data[6] = TimerReloadValue + * data[7] = ConvertingTimeUnit + * data[8] = 0 Analog voltage measurement + * = 1 Resistance measurement + * = 2 Temperature measurement + * data[9] = 0 Interrupt Disable + * = 1 INterrupt Enable + * data[10] = Type of Thermocouple + * data[11] = single channel Module Number + * data[12] = 0 Single Read + * = 1 Read more channel + * = 2 Single scan + * = 3 Continuous Scan + * data[13] = Number of channels to read + * data[14] = 0 RTD not used + * = 1 RTD 2 wire connection + * = 2 RTD 3 wire connection + * = 3 RTD 4 wire connection + */ +static int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + unsigned int ul_Config = 0, ul_Temp = 0; + unsigned int ui_ChannelNo = 0; + unsigned int ui_Dummy = 0; + int i_err = 0; + + /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + +#ifdef PRINT_INFO + int i = 0, i2 = 0; +#endif + /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* Initialize the structure */ + if (s_BoardInfos[dev->minor].b_StructInitialized != 1) { + s_BoardInfos[dev->minor].i_CJCAvailable = 1; + s_BoardInfos[dev->minor].i_CJCPolarity = 0; + s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */ + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */ + s_BoardInfos[dev->minor].i_ChannelCount = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + s_BoardInfos[dev->minor].ui_Channel_num = 0; + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Initialised = 0; + s_BoardInfos[dev->minor].b_StructInitialized = 1; + + /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + s_BoardInfos[dev->minor].i_ConnectionType = 0; + /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + + /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + memset(s_BoardInfos[dev->minor].s_Module, 0, + sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE])); + + v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc, + &s_BoardInfos[dev->minor]); + +#ifdef PRINT_INFO + for (i = 0; i < MAX_MODULE; i++) { + printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i, + s_BoardInfos[dev->minor].s_Module[i]. + ul_CurrentSourceCJC); + + for (i2 = 0; i2 < 5; i2++) { + printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]); + } + + for (i2 = 0; i2 < 8; i2++) { + printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]); + } + + for (i2 = 0; i2 < 8; i2++) { + printk("\n s_Module[%i].w_GainValue [%i] = %u", + i, i2, + s_BoardInfos[dev->minor].s_Module[i]. + w_GainValue[i2]); + } + } +#endif + /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } + + if (data[0] != 0 && data[0] != 1 && data[0] != 2) { + printk("\nThe selection of acquisition type is in error\n"); + i_err++; + } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */ + if (data[0] == 1) { + if (data[14] != 0 && data[14] != 1 && data[14] != 2 + && data[14] != 4) { + printk("\n Error in selection of RTD connection type\n"); + i_err++; + } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */ + } /* if(data[0]==1 ) */ + if (data[1] < 0 || data[1] > 7) { + printk("\nThe selection of gain is in error\n"); + i_err++; + } /* if(data[1]<0 || data[1]>7) */ + if (data[2] != 0 && data[2] != 1) { + printk("\nThe selection of polarity is in error\n"); + i_err++; + } /* if(data[2]!=0 && data[2]!=1) */ + if (data[3] != 0) { + printk("\nThe selection of offset range is in error\n"); + i_err++; + } /* if(data[3]!=0) */ + if (data[4] != 0 && data[4] != 1) { + printk("\nThe selection of coupling is in error\n"); + i_err++; + } /* if(data[4]!=0 && data[4]!=1) */ + if (data[5] != 0 && data[5] != 1) { + printk("\nThe selection of single/differential mode is in error\n"); + i_err++; + } /* if(data[5]!=0 && data[5]!=1) */ + if (data[8] != 0 && data[8] != 1 && data[2] != 2) { + printk("\nError in selection of functionality\n"); + } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */ + if (data[12] == 0 || data[12] == 1) { + if (data[6] != 20 && data[6] != 40 && data[6] != 80 + && data[6] != 160) { + printk("\nThe selection of conversion time reload value is in error\n"); + i_err++; + } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */ + if (data[7] != 2) { + printk("\nThe selection of conversion time unit is in error\n"); + i_err++; + } /* if(data[7]!=2) */ + } + if (data[9] != 0 && data[9] != 1) { + printk("\nThe selection of interrupt enable is in error\n"); + i_err++; + } /* if(data[9]!=0 && data[9]!=1) */ + if (data[11] < 0 || data[11] > 4) { + printk("\nThe selection of module is in error\n"); + i_err++; + } /* if(data[11] <0 || data[11]>1) */ + if (data[12] < 0 || data[12] > 3) { + printk("\nThe selection of singlechannel/scan selection is in error\n"); + i_err++; + } /* if(data[12] < 0 || data[12]> 3) */ + if (data[13] < 0 || data[13] > 16) { + printk("\nThe selection of number of channels is in error\n"); + i_err++; + } /* if(data[13] <0 ||data[13] >15) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* + i_ChannelCount=data[13]; + i_ScanType=data[12]; + i_ADDIDATAPolarity = data[2]; + i_ADDIDATAGain=data[1]; + i_ADDIDATAConversionTime=data[6]; + i_ADDIDATAConversionTimeUnit=data[7]; + i_ADDIDATAType=data[0]; + */ + + /* Save acquisition configuration for the actual board */ + s_BoardInfos[dev->minor].i_ChannelCount = data[13]; + s_BoardInfos[dev->minor].i_ScanType = data[12]; + s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2]; + s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1]; + s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6]; + s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7]; + s_BoardInfos[dev->minor].i_ADDIDATAType = data[0]; + /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + s_BoardInfos[dev->minor].i_ConnectionType = data[5]; + /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* END JK 06.07.04: Management of sevrals boards */ + + /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */ + /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */ + /* while(i_InterruptFlag==1) */ + while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { +#ifndef MSXBOX + udelay(1); +#else + /* In the case where the driver is compiled for the MSX-Box */ + /* we used a printk to have a little delay because udelay */ + /* seems to be broken under the MSX-Box. */ + /* This solution hat to be studied. */ + printk(""); +#endif + } + /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */ + + ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=ui_ChannelNo; */ + /* ui_Channel_num =ui_ChannelNo; */ + + s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo; + s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo; + + /* END JK 06.07.04: Management of sevrals boards */ + + if (data[5] == 0) { + if (ui_ChannelNo < 0 || ui_ChannelNo > 15) { + printk("\nThe Selection of the channel is in error\n"); + i_err++; + } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */ + } /* if(data[5]==0) */ + else { + if (data[14] == 2) { + if (ui_ChannelNo < 0 || ui_ChannelNo > 3) { + printk("\nThe Selection of the channel is in error\n"); + i_err++; + } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */ + } /* if(data[14]==2) */ + else { + if (ui_ChannelNo < 0 || ui_ChannelNo > 7) { + printk("\nThe Selection of the channel is in error\n"); + i_err++; + } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */ + } /* elseif(data[14]==2) */ + } /* elseif(data[5]==0) */ + if (data[12] == 0 || data[12] == 1) { + switch (data[5]) { + case 0: + if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */ + if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=64; */ + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */ + if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */ + if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */ + break; + case 1: + if (data[14] == 2) { + if (ui_ChannelNo == 0) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==0 ) */ + if (ui_ChannelNo == 1) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==1) */ + if (ui_ChannelNo == 2) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==2 ) */ + if (ui_ChannelNo == 3) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==3) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=0; */ + s_BoardInfos[dev->minor].i_ChannelNo = 0; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = 0; + break; + } /* if(data[14]==2) */ + if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */ + if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=i_ChannelNo-2; */ + /* i_Offset=64; */ + s_BoardInfos[dev->minor].i_ChannelNo = + s_BoardInfos[dev->minor].i_ChannelNo - + 2; + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = ui_ChannelNo - 2; + } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */ + if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=i_ChannelNo-4; */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_ChannelNo = + s_BoardInfos[dev->minor].i_ChannelNo - + 4; + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = ui_ChannelNo - 4; + } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */ + if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=i_ChannelNo-6; */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_ChannelNo = + s_BoardInfos[dev->minor].i_ChannelNo - + 6; + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = ui_ChannelNo - 6; + } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */ + break; + + default: + printk("\n This selection of polarity does not exist\n"); + i_err++; + } /* switch(data[2]) */ + } /* if(data[12]==0 || data[12]==1) */ + else { + switch (data[11]) { + case 1: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + break; + case 2: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=64; */ + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + break; + case 3: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + break; + case 4: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + break; + default: + printk("\nError in module selection\n"); + i_err++; + } /* switch(data[11]) */ + } /* elseif(data[12]==0 || data[12]==1) */ + if (i_err) { + i_APCI3200_Reset(dev); + return -EINVAL; + } + /* if(i_ScanType!=1) */ + if (s_BoardInfos[dev->minor].i_ScanType != 1) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Count=0; */ + /* i_Sum=0; */ + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(i_ScanType!=1) */ + + ul_Config = + data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) | + (data[4] << 9); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* END JK 06.07.04: Management of sevrals boards */ + /*********************************/ + /* Write the channel to configure */ + /*********************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */ + outl(0 | ui_ChannelNo, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* END JK 06.07.04: Management of sevrals boards */ + /**************************/ + /* Reset the configuration */ + /**************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl(0 , devpriv->iobase+i_Offset + 0x0); */ + outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* END JK 06.07.04: Management of sevrals boards */ + + /***************************/ + /* Write the configuration */ + /***************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */ + outl(ul_Config, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); + /* END JK 06.07.04: Management of sevrals boards */ + + /***************************/ + /*Reset the calibration bit */ + /***************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */ + ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */ + outl((ul_Temp & 0xFFF9FFFF), + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); + /* END JK 06.07.04: Management of sevrals boards */ + + if (data[9] == 1) { + devpriv->tsk_Current = current; + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_InterruptFlag=1; */ + s_BoardInfos[dev->minor].i_InterruptFlag = 1; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(data[9]==1) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_InterruptFlag=0; */ + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* else if(data[9]==1) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Initialised=1; */ + s_BoardInfos[dev->minor].i_Initialised = 1; + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_ScanType==1) */ + if (s_BoardInfos[dev->minor].i_ScanType == 1) + /* END JK 06.07.04: Management of sevrals boards */ + { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Sum=i_Sum+1; */ + s_BoardInfos[dev->minor].i_Sum = + s_BoardInfos[dev->minor].i_Sum + 1; + /* END JK 06.07.04: Management of sevrals boards */ + + insn->unused[0] = 0; + i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy); + } + + return insn->n; +} + +/* + * Tests the Selected Anlog Input Channel + * + * data[0] = 0 TestAnalogInputShortCircuit + * = 1 TestAnalogInputConnection + * + * data[0] : Digital value obtained + * data[1] : calibration offset + * data[2] : calibration gain + */ +static int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; unsigned int ui_Configuration = 0; int i_Temp; /* ,i_TimeUnit; */ + /* if(i_Initialised==0) */ if (s_BoardInfos[dev->minor].i_Initialised == 0) { @@ -2502,61 +2211,18 @@ int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, return insn->n; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Resets the channels | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { i_APCI3200_Reset(dev); return insn->n; } -/* - +----------------------------------------------------------------------------+ - | Function name :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev| - | ,struct comedi_subdevice *s,struct comedi_cmd *cmd) | - | | - +----------------------------------------------------------------------------+ - | Task : Test validity for a command for cyclic anlog input | - | acquisition | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | struct comedi_subdevice *s | - | struct comedi_cmd *cmd | - | | - | - | | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value :0 | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd) +static int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { int err = 0; @@ -2716,27 +2382,12 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s return 0; } -/* - +----------------------------------------------------------------------------+ - | Function name :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,| - | struct comedi_subdevice *s)| - | | - +----------------------------------------------------------------------------+ - | Task : Stop the acquisition | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | struct comedi_subdevice *s | - | | - +----------------------------------------------------------------------------+ - | Return Value :0 | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s) +static int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, + struct comedi_subdevice *s) { + struct addi_private *devpriv = dev->private; unsigned int ui_Configuration = 0; + /* i_InterruptFlag=0; */ /* i_Initialised=0; */ /* i_Count=0; */ @@ -2765,27 +2416,13 @@ int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su } /* - +----------------------------------------------------------------------------+ - | Function name : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, | - | struct comedi_subdevice *s) | - | | - +----------------------------------------------------------------------------+ - | Task : Does asynchronous acquisition | - | Determines the mode 1 or 2. | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | struct comedi_subdevice *s | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value : | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s) + * Does asynchronous acquisition + * Determines the mode 1 or 2. + */ +static int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s) { + struct addi_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int ui_Configuration = 0; /* INT i_CurrentSource = 0; */ @@ -2798,6 +2435,7 @@ int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde unsigned int ui_DelayTime = 0; unsigned int ui_DelayTimeBase = 0; unsigned int ui_DelayMode = 0; + /* i_FirstChannel=cmd->chanlist[0]; */ /* i_LastChannel=cmd->chanlist[1]; */ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0]; @@ -2956,80 +2594,155 @@ int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde } /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_Reset(struct comedi_device *dev) | - | | - +----------------------------------------------------------------------------+ - | Task :Resets the registers of the card | - +----------------------------------------------------------------------------+ - | Input Parameters : | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_Reset(struct comedi_device *dev) + * This function copies the acquired data(from FIFO) to Comedi buffer. + */ +static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) { - int i_Temp; - unsigned int dw_Dummy; - /* i_InterruptFlag=0; */ - /* i_Initialised==0; */ - /* i_Count=0; */ - /* i_Sum=0; */ + struct addi_private *devpriv = dev->private; + unsigned int ui_StatusRegister = 0; + struct comedi_subdevice *s = &dev->subdevices[0]; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 0; + /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* comedi_async *async = s->async; */ + /* UINT *data; */ + /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */ + int n = 0, i = 0; + /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + /************************************/ + /*Read the interrupt status register */ + /************************************/ + /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ + ui_StatusRegister = + inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16); - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - outl(0, devpriv->i_IobaseAddon); /* Resets the output */ - /***************/ - /*Empty the buffer */ - /**************/ - for (i_Temp = 0; i_Temp <= 95; i_Temp++) { - /* ui_InterruptChannelValue[i_Temp]=0; */ - s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0; - } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */ - /*****************************/ - /*Reset the START and IRQ bit */ - /*****************************/ - for (i_Temp = 0; i_Temp <= 192;) { - while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ; - outl(0, devpriv->iobase + i_Temp + 8); - i_Temp = i_Temp + 64; - } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */ + /*************************/ + /*Test if interrupt occur */ + /*************************/ + + if ((ui_StatusRegister & 0x2) == 0x2) { + /*************************/ + /*Read the channel number */ + /*************************/ + /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ + /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* This value is not used */ + /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */ + s->async->events = 0; + /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /*************************************/ + /*Read the digital Analog Input value */ + /*************************************/ + + /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */ + /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */ + s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count] = + inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 28); + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */ + if ((s_BoardInfos[dev->minor].i_Count == + (s_BoardInfos[dev->minor].i_LastChannel - + s_BoardInfos[dev->minor]. + i_FirstChannel + 3))) { + + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + s_BoardInfos[dev->minor].i_Count++; + + for (i = s_BoardInfos[dev->minor].i_FirstChannel; + i <= s_BoardInfos[dev->minor].i_LastChannel; + i++) { + i_APCI3200_GetChannelCalibrationValue(dev, i, + &s_BoardInfos[dev->minor]. + ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count + ((i - + s_BoardInfos + [dev->minor]. + i_FirstChannel) + * 3)], + &s_BoardInfos[dev->minor]. + ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count + ((i - + s_BoardInfos + [dev->minor]. + i_FirstChannel) + * 3) + 1], + &s_BoardInfos[dev->minor]. + ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count + ((i - + s_BoardInfos + [dev->minor]. + i_FirstChannel) + * 3) + 2]); + } + + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + + /* i_Count=-1; */ + + s_BoardInfos[dev->minor].i_Count = -1; + + /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ + /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ + /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ + /* comedi_eos(dev,s); */ + + /* Set the event type (Comedi Buffer End Of Scan) */ + s->async->events |= COMEDI_CB_EOS; + + /* Test if enougth memory is available and allocate it for 7 values */ + /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */ + n = comedi_buf_write_alloc(s->async, + (7 + 12) * sizeof(unsigned int)); + + /* If not enough memory available, event is set to Comedi Buffer Error */ + if (n > ((7 + 12) * sizeof(unsigned int))) { + printk("\ncomedi_buf_write_alloc n = %i", n); + s->async->events |= COMEDI_CB_ERROR; + } + /* Write all 7 scan values in the comedi buffer */ + comedi_buf_memcpy_to(s->async, 0, + (unsigned int *) s_BoardInfos[dev->minor]. + ui_ScanValueArray, (7 + 12) * sizeof(unsigned int)); + + /* Update comedi buffer pinters indexes */ + comedi_buf_write_free(s->async, + (7 + 12) * sizeof(unsigned int)); + + /* Send events */ + comedi_event(dev, s); + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* */ + /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */ + /* { */ + /* /* buffer rollover */ */ + /* s->async->buf_int_ptr=0; */ + /* comedi_eobuf(dev,s); */ + /* } */ + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + } + /* i_Count++; */ + s_BoardInfos[dev->minor].i_Count++; + } + /* i_InterruptFlag=0; */ + s_BoardInfos[dev->minor].i_InterruptFlag = 0; return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : static void v_APCI3200_Interrupt | - | (int irq , void *d) | - +----------------------------------------------------------------------------+ - | Task : Interrupt processing Routine | - +----------------------------------------------------------------------------+ - | Input Parameters : int irq : irq number | - | void *d : void pointer | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -void v_APCI3200_Interrupt(int irq, void *d) +static void v_APCI3200_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_StatusRegister = 0; unsigned int ui_ChannelNumber = 0; int i_CalibrationFlag = 0; @@ -3038,7 +2751,6 @@ void v_APCI3200_Interrupt(int irq, void *d) unsigned int ui_DigitalTemperature = 0; unsigned int ui_DigitalInput = 0; int i_ConvertCJCCalibration; - /* BEGIN JK TEST */ int i_ReturnValue = 0; /* END JK TEST */ @@ -3449,164 +3161,3 @@ void v_APCI3200_Interrupt(int irq, void *d) } /* switch(i_ScanType) */ return; } - -/* - +----------------------------------------------------------------------------+ - | Function name :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) | - | | - | | - +----------------------------------------------------------------------------+ - | Task : . | - | This function copies the acquired data(from FIFO) | - | to Comedi buffer. | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value : 0 | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) -{ - unsigned int ui_StatusRegister = 0; - struct comedi_subdevice *s = &dev->subdevices[0]; - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* comedi_async *async = s->async; */ - /* UINT *data; */ - /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */ - int n = 0, i = 0; - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /************************************/ - /*Read the interrupt status register */ - /************************************/ - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16); - - /*************************/ - /*Test if interrupt occur */ - /*************************/ - - if ((ui_StatusRegister & 0x2) == 0x2) { - /*************************/ - /*Read the channel number */ - /*************************/ - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* This value is not used */ - /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */ - s->async->events = 0; - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /*************************************/ - /*Read the digital Analog Input value */ - /*************************************/ - - /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */ - s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */ - if ((s_BoardInfos[dev->minor].i_Count == - (s_BoardInfos[dev->minor].i_LastChannel - - s_BoardInfos[dev->minor]. - i_FirstChannel + 3))) { - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_Count++; - - for (i = s_BoardInfos[dev->minor].i_FirstChannel; - i <= s_BoardInfos[dev->minor].i_LastChannel; - i++) { - i_APCI3200_GetChannelCalibrationValue(dev, i, - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3)], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 1], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 2]); - } - - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* i_Count=-1; */ - - s_BoardInfos[dev->minor].i_Count = -1; - - /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* comedi_eos(dev,s); */ - - /* Set the event type (Comedi Buffer End Of Scan) */ - s->async->events |= COMEDI_CB_EOS; - - /* Test if enougth memory is available and allocate it for 7 values */ - /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */ - n = comedi_buf_write_alloc(s->async, - (7 + 12) * sizeof(unsigned int)); - - /* If not enough memory available, event is set to Comedi Buffer Error */ - if (n > ((7 + 12) * sizeof(unsigned int))) { - printk("\ncomedi_buf_write_alloc n = %i", n); - s->async->events |= COMEDI_CB_ERROR; - } - /* Write all 7 scan values in the comedi buffer */ - comedi_buf_memcpy_to(s->async, 0, - (unsigned int *) s_BoardInfos[dev->minor]. - ui_ScanValueArray, (7 + 12) * sizeof(unsigned int)); - - /* Update comedi buffer pinters indexes */ - comedi_buf_write_free(s->async, - (7 + 12) * sizeof(unsigned int)); - - /* Send events */ - comedi_event(dev, s); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* */ - /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */ - /* { */ - /* /* buffer rollover */ */ - /* s->async->buf_int_ptr=0; */ - /* comedi_eobuf(dev,s); */ - /* } */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - } - /* i_Count++; */ - s_BoardInfos[dev->minor].i_Count++; - } - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h deleted file mode 100644 index 812a9c4..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/* Card Specific information */ -#define APCI3200_BOARD_VENDOR_ID 0x15B8 -/* #define APCI3200_ADDRESS_RANGE 264 */ - -int MODULE_NO; -struct { - int i_Gain; - int i_Polarity; - int i_OffsetRange; - int i_Coupling; - int i_SingleDiff; - int i_AutoCalibration; - unsigned int ui_ReloadValue; - unsigned int ui_TimeUnitReloadVal; - int i_Interrupt; - int i_ModuleSelection; -} Config_Parameters_Module1, Config_Parameters_Module2, - Config_Parameters_Module3, Config_Parameters_Module4; - -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3200_ai = { 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 range_apci3300_ai = { 4, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -/* Analog Input related Defines */ -#define APCI3200_AI_OFFSET_GAIN 0 -#define APCI3200_AI_SC_TEST 4 -#define APCI3200_AI_IRQ 8 -#define APCI3200_AI_AUTOCAL 12 -#define APCI3200_RELOAD_CONV_TIME_VAL 32 -#define APCI3200_CONV_TIME_TIME_BASE 36 -#define APCI3200_RELOAD_DELAY_TIME_VAL 40 -#define APCI3200_DELAY_TIME_TIME_BASE 44 -#define APCI3200_AI_MODULE1 0 -#define APCI3200_AI_MODULE2 64 -#define APCI3200_AI_MODULE3 128 -#define APCI3200_AI_MODULE4 192 -#define TRUE 1 -#define FALSE 0 -#define APCI3200_AI_EOSIRQ 16 -#define APCI3200_AI_EOS 20 -#define APCI3200_AI_CHAN_ID 24 -#define APCI3200_AI_CHAN_VAL 28 -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define APCI3200_MAXVOLT 2.5 -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -/* BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ -#define MAX_MODULE 4 -/* END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - -struct str_ADDIDATA_RTDStruct { - unsigned int ul_NumberOfValue; - unsigned int *pul_ResistanceValue; - unsigned int *pul_TemperatureValue; -}; - -/* BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ -struct str_Module { - - /* Begin JK 05/08/2003 change for Linux */ - unsigned long ul_CurrentSourceCJC; - unsigned long ul_CurrentSource[5]; - /* End JK 05/08/2003 change for Linux */ - - /* Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1 */ - unsigned long ul_GainFactor[8]; /* Gain Factor */ - unsigned int w_GainValue[10]; - /* End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1 */ -}; - -/* END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - -/* BEGIN JK 06.07.04: Management of sevrals boards */ -struct str_BoardInfos { - - int i_CJCAvailable; - int i_CJCPolarity; - int i_CJCGain; - int i_InterruptFlag; - int i_ADDIDATAPolarity; - int i_ADDIDATAGain; - int i_AutoCalibration; - int i_ADDIDATAConversionTime; - int i_ADDIDATAConversionTimeUnit; - int i_ADDIDATAType; - int i_ChannelNo; - int i_ChannelCount; - int i_ScanType; - int i_FirstChannel; - int i_LastChannel; - int i_Sum; - int i_Offset; - unsigned int ui_Channel_num; - int i_Count; - int i_Initialised; - /* UINT ui_InterruptChannelValue[96]; //Buffer */ - unsigned int ui_InterruptChannelValue[144]; /* Buffer */ - unsigned char b_StructInitialized; - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - unsigned int ui_ScanValueArray[7 + 12]; /* 7 is the maximal number of channels */ - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - int i_ConnectionType; - int i_NbrOfModule; - struct str_Module s_Module[MAX_MODULE]; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ -}; - -/* END JK 06.07.04: Management of sevrals boards */ - -/* Hardware Layer functions for Apci3200 */ - -/* AI */ - -int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s); -int i_APCI3200_InterruptHandleEos(struct comedi_device *dev); -int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s); -int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/* Interrupt */ -void v_APCI3200_Interrupt(int irq, void *d); -int i_APCI3200_InterruptHandleEos(struct comedi_device *dev); -/* Reset functions */ -int i_APCI3200_Reset(struct comedi_device *dev); - -int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index acaceb0..7a18ce7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -46,229 +46,75 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci3501.h" - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_ReadDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ +/* Card Specific information */ +#define APCI3501_ADDRESS_RANGE 255 + +#define APCI3501_DIGITAL_IP 0x50 +#define APCI3501_DIGITAL_OP 0x40 +#define APCI3501_ANALOG_OUTPUT 0x00 + +/* Analog Output related Defines */ +#define APCI3501_AO_VOLT_MODE 0 +#define APCI3501_AO_PROG 4 +#define APCI3501_AO_TRIG_SCS 8 +#define UNIPOLAR 0 +#define BIPOLAR 1 +#define MODE0 0 +#define MODE1 1 + +/* Watchdog Related Defines */ + +#define APCI3501_WATCHDOG 0x20 +#define APCI3501_TCW_SYNC_ENABLEDISABLE 0 +#define APCI3501_TCW_RELOAD_VALUE 4 +#define APCI3501_TCW_TIMEBASE 8 +#define APCI3501_TCW_PROG 12 +#define APCI3501_TCW_TRIG_STATUS 16 +#define APCI3501_TCW_IRQ 20 +#define APCI3501_TCW_WARN_TIMEVAL 24 +#define APCI3501_TCW_WARN_TIMEBASE 28 +#define ADDIDATA_TIMER 0 +#define ADDIDATA_WATCHDOG 2 + +/* ANALOG OUTPUT RANGE */ +static struct comedi_lrange range_apci3501_ao = { + 2, { + BIP_RANGE(10), + UNI_RANGE(10) + } +}; -int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int apci3501_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - - *data = *data & 0x3; - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif (ui_Temp==1) */ - } /* elseif (ui_Temp==0) */ - return insn->n; -} + struct addi_private *devpriv = dev->private; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_ConfigDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -| data[1] : 1 Enable VCC Interrupt | -| 0 Disable VCC Interrupt | -| data[2] : 1 Enable CC Interrupt | -| 0 Disable CC Interrupt | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ + data[1] = inl(devpriv->iobase + APCI3501_DIGITAL_IP) & 0x3; - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } /* if ( (data[0]!=0) && (data[0]!=1) ) */ - if (data[0]) { - devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0]) */ - else { - devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0]) */ return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : writes To the digital Output Subdevice | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s : Subdevice Pointer | -| struct comedi_insn *insn : Insn Structure Pointer | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int apci3501_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - data[0] = (data[0] << (2 * data[2])) | ui_Temp; - outl(data[0], - devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - (data[0] << ui_NoOfChannel) ^ - 0xffffffff; - data[0] = data[0] & ui_Temp; - outl(data[0], - devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data[2])) ^ - 0xffffffff) & ui_Temp; - outl(data[0], - devpriv->iobase + - APCI3501_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} + struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; + + s->state = inl(devpriv->iobase + APCI3501_DIGITAL_OP); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outl(s->state, devpriv->iobase + APCI3501_DIGITAL_OP); + } + + data[1] = s->state; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->iobase + APCI3501_DIGITAL_OP); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - *data = *data & 0x3; - - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* else if (ui_Temp==0) */ return insn->n; } @@ -298,9 +144,13 @@ int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; + outl(data[0], devpriv->iobase + APCI3501_ANALOG_OUTPUT + APCI3501_AO_VOLT_MODE); @@ -336,9 +186,12 @@ int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0; ul_Channel_no = CR_CHAN(insn->chanspec); @@ -410,10 +263,14 @@ int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; + devpriv->tsk_Current = current; if (data[0] == ADDIDATA_WATCHDOG) { @@ -511,11 +368,15 @@ int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; int i_Temp; + if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { if (data[1] == 1) { @@ -613,9 +474,12 @@ int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct addi_private *devpriv = dev->private; if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { data[0] = @@ -654,10 +518,12 @@ int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3501_Reset(struct comedi_device *dev) +static int i_APCI3501_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int i_Count = 0, i_temp = 0; unsigned int ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0; + outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP); outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT + APCI3501_AO_VOLT_MODE); @@ -705,12 +571,14 @@ int i_APCI3501_Reset(struct comedi_device *dev) | | +----------------------------------------------------------------------------+ */ -void v_APCI3501_Interrupt(int irq, void *d) +static void v_APCI3501_Interrupt(int irq, void *d) { int i_temp; struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_Timer_AOWatchdog; unsigned long ul_Command1; + /* Disable Interrupt */ ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h deleted file mode 100644 index 63df635..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 - * - * 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. - */ - -/* Card Specific information */ -#define APCI3501_BOARD_VENDOR_ID 0x15B8 -#define APCI3501_ADDRESS_RANGE 255 - -#define APCI3501_DIGITAL_IP 0x50 -#define APCI3501_DIGITAL_OP 0x40 -#define APCI3501_ANALOG_OUTPUT 0x00 - -/* Analog Output related Defines */ -#define APCI3501_AO_VOLT_MODE 0 -#define APCI3501_AO_PROG 4 -#define APCI3501_AO_TRIG_SCS 8 -#define UNIPOLAR 0 -#define BIPOLAR 1 -#define MODE0 0 -#define MODE1 1 -/* ANALOG OUTPUT RANGE */ -static struct comedi_lrange range_apci3501_ao = { 2, { - BIP_RANGE(10), - UNI_RANGE(10) - } -}; - -/* Watchdog Related Defines */ - -#define APCI3501_WATCHDOG 0x20 -#define APCI3501_TCW_SYNC_ENABLEDISABLE 0 -#define APCI3501_TCW_RELOAD_VALUE 4 -#define APCI3501_TCW_TIMEBASE 8 -#define APCI3501_TCW_PROG 12 -#define APCI3501_TCW_TRIG_STATUS 16 -#define APCI3501_TCW_IRQ 20 -#define APCI3501_TCW_WARN_TIMEVAL 24 -#define APCI3501_TCW_WARN_TIMEBASE 28 -#define ADDIDATA_TIMER 0 -#define ADDIDATA_WATCHDOG 2 - -/* Hardware Layer functions for Apci3501 */ - -/* AO */ -int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* DI for di read INT i_APCI3501_ReadDigitalInput(struct -* comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn -* *insn,unsigned int *data); -*/ - -int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* DO */ -int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* TIMER - * timer value is passed as u seconds - */ - -int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/* Interrupt */ -void v_APCI3501_Interrupt(int irq, void *d); - -/* Reset functions */ -int i_APCI3501_Reset(struct comedi_device *dev); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index fff99df..a45a2a2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -44,7 +44,35 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_apci3xxx.h" +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif + +#define APCI3XXX_SINGLE 0 +#define APCI3XXX_DIFF 1 +#define APCI3XXX_CONFIGURATION 0 + +#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0 + +static const struct comedi_lrange range_apci3XXX_ai = { + 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 range_apci3XXX_ao = { + 2, { + BIP_RANGE(10), + UNI_RANGE(10) + } +}; /* +----------------------------------------------------------------------------+ @@ -69,6 +97,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour */ static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL) return 1; else @@ -108,6 +138,8 @@ static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_TimeBase = 0; unsigned char b_SingleDiff = 0; @@ -358,6 +390,8 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec); unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); @@ -571,6 +605,7 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, static void v_APCI3XXX_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned char b_CopyCpt = 0; unsigned int dw_Status = 0; @@ -651,6 +686,7 @@ static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec); unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); unsigned int dw_Status = 0; @@ -755,6 +791,7 @@ static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; @@ -884,6 +921,7 @@ static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_ChannelCpt = 0; unsigned int dw_ChannelMask = 0; @@ -1040,6 +1078,7 @@ static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); int i_ReturnValue = insn->n; unsigned int *pls_ReadData = data; @@ -1154,6 +1193,7 @@ static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); unsigned char b_State = 0; @@ -1236,367 +1276,38 @@ static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, return i_ReturnValue; } -/* -+----------------------------------------------------------------------------+ -| DIGITAL INPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnReadDigitalInput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the specified Digital input channel | -+----------------------------------------------------------------------------+ -| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) | -+----------------------------------------------------------------------------+ -| Output Parameters : data[0] : Channel value | -+----------------------------------------------------------------------------+ -| Return Value : 0 : No error | -| -3 : Channel selection error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - int i_ReturnValue = insn->n; - unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); - unsigned int dw_Temp = 0; - - /***************************/ - /* Test the channel number */ - /***************************/ - - if (b_Channel <= devpriv->s_EeParameters.i_NbrDiChannel) { - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 1) { - dw_Temp = inl(devpriv->iobase + 32); - *data = (dw_Temp >> b_Channel) & 1; - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } - } else { - /***************************/ - /* Channel selection error */ - /***************************/ - - printk("Channel selection error\n"); - i_ReturnValue = -3; - } - - return i_ReturnValue; -} - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnBitsDigitalInput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the Digital input Port i.e.4channels| -+----------------------------------------------------------------------------+ -| Input Parameters : - | -+----------------------------------------------------------------------------+ -| Output Parameters : data[0] : Port value | -+----------------------------------------------------------------------------+ -| Return Value :>0: No error | -| .... | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - int i_ReturnValue = insn->n; - unsigned int dw_Temp = 0; - - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 1) { - dw_Temp = inl(devpriv->iobase + 32); - *data = dw_Temp & 0xf; - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } - - return i_ReturnValue; -} - -/* -+----------------------------------------------------------------------------+ -| DIGITAL OUTPUT SUBDEVICE | -+----------------------------------------------------------------------------+ - -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnBitsDigitalOutput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Write the selected output mask and read the status from| -| all digital output channles | -+----------------------------------------------------------------------------+ -| Input Parameters : dw_ChannelMask = data [0]; | -| dw_BitMask = data [1]; | -+----------------------------------------------------------------------------+ -| Output Parameters : data[1] : All digital output channles states | -+----------------------------------------------------------------------------+ -| Return Value : >0 : No error | -| -4 : Channel mask error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3xxx_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - int i_ReturnValue = insn->n; - unsigned char b_ChannelCpt = 0; - unsigned int dw_ChannelMask = 0; - unsigned int dw_BitMask = 0; - unsigned int dw_Status = 0; - - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 2) { - /*******************************/ - /* Get the channe and bit mask */ - /*******************************/ - - dw_ChannelMask = data[0]; - dw_BitMask = data[1]; - - /*************************/ - /* Test the channel mask */ - /*************************/ - - if ((dw_ChannelMask & 0XFFFFFFF0) == 0) { - /*********************************/ - /* Test if set/reset any channel */ - /*********************************/ - - if (dw_ChannelMask & 0xF) { - /********************************/ - /* Read the digital output port */ - /********************************/ - - dw_Status = inl(devpriv->iobase + 48); + struct addi_private *devpriv = dev->private; - for (b_ChannelCpt = 0; b_ChannelCpt < 4; - b_ChannelCpt++) { - if ((dw_ChannelMask >> b_ChannelCpt) & - 1) { - dw_Status = - (dw_Status & (0xF - - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); - } - } - - outl(dw_Status, devpriv->iobase + 48); - } - - /********************************/ - /* Read the digital output port */ - /********************************/ - - data[1] = inl(devpriv->iobase + 48); - } else { - /************************/ - /* Config command error */ - /************************/ - - printk("Channel mask error\n"); - i_ReturnValue = -4; - } - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } + data[1] = inl(devpriv->iobase + 32) & 0xf; - return i_ReturnValue; + return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnWriteDigitalOutput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Set the state from digital output channel | -+----------------------------------------------------------------------------+ -| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | -| b_State = data [0] | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : >0 : No error | -| -3 : Channel selection error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3xxx_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - int i_ReturnValue = insn->n; - unsigned char b_Channel = CR_CHAN(insn->chanspec); - unsigned char b_State = 0; - unsigned int dw_Status = 0; - - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 1) { - /***************************/ - /* Test the channel number */ - /***************************/ - - if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) { - /*******************/ - /* Get the command */ - /*******************/ - - b_State = (unsigned char) data[0]; - - /********************************/ - /* Read the digital output port */ - /********************************/ - - dw_Status = inl(devpriv->iobase + 48); - - dw_Status = - (dw_Status & (0xF - - (1 << b_Channel))) | ((b_State & 1) << - b_Channel); - outl(dw_Status, devpriv->iobase + 48); - } else { - /***************************/ - /* Channel selection error */ - /***************************/ + struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; - printk("Channel selection error\n"); - i_ReturnValue = -3; - } - } else { - /*******************/ - /* Data size error */ - /*******************/ + s->state = inl(devpriv->iobase + 48) & 0xf; + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); - printk("Buffer size error\n"); - i_ReturnValue = -101; + outl(s->state, devpriv->iobase + 48); } - return i_ReturnValue; -} - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnReadDigitalOutput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read the state from digital output channel | -+----------------------------------------------------------------------------+ -| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | -+----------------------------------------------------------------------------+ -| Output Parameters : b_State = data [0] | -+----------------------------------------------------------------------------+ -| Return Value : >0 : No error | -| -3 : Channel selection error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ + data[1] = s->state; -static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - int i_ReturnValue = insn->n; - unsigned char b_Channel = CR_CHAN(insn->chanspec); - unsigned int dw_Status = 0; - - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 1) { - /***************************/ - /* Test the channel number */ - /***************************/ - - if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) { - /********************************/ - /* Read the digital output port */ - /********************************/ - - dw_Status = inl(devpriv->iobase + 48); - - dw_Status = (dw_Status >> b_Channel) & 1; - *data = dw_Status; - } else { - /***************************/ - /* Channel selection error */ - /***************************/ - - printk("Channel selection error\n"); - i_ReturnValue = -3; - } - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } - - return i_ReturnValue; + return insn->n; } /* @@ -1614,6 +1325,7 @@ static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, static int i_APCI3XXX_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; unsigned char b_Cpt = 0; /*************************/ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h deleted file mode 100644 index e10b7e5..0000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 - * - * 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. - */ - -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - -#ifndef ADDIDATA_ENABLE -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -#endif - -#define APCI3XXX_SINGLE 0 -#define APCI3XXX_DIFF 1 -#define APCI3XXX_CONFIGURATION 0 - -#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0 - -#ifdef __KERNEL__ - -static const struct comedi_lrange range_apci3XXX_ai = { 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 range_apci3XXX_ao = { 2, {BIP_RANGE(10), - UNI_RANGE(10)} -}; -#endif diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 4c00df4..c981d4b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -1,11 +1,77 @@ -#define CONFIG_APCI_035 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ +#include "addi-data/addi_common.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_035" +#define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci035.c" #include "addi-data/addi_common.c" +static const struct addi_board apci035_boardtypes[] = { + { + .pc_DriverName = "apci035", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x0300, + .i_IorangeBase0 = 127, + .i_IorangeBase1 = APCI035_ADDRESS_RANGE, + .i_PCIEeprom = 1, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0xff, + .pr_AiRangelist = &range_apci035_ai, + .i_Timer = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI035_Interrupt, + .reset = i_APCI035_Reset, + .ai_config = i_APCI035_ConfigAnalogInput, + .ai_read = i_APCI035_ReadAnalogInput, + .timer_config = i_APCI035_ConfigTimerWatchdog, + .timer_write = i_APCI035_StartStopWriteTimerWatchdog, + .timer_read = i_APCI035_ReadTimerWatchdog, + }, +}; + +static struct comedi_driver apci035_driver = { + .driver_name = "addi_apci_035", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci035_boardtypes), + .board_name = &apci035_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci035_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci035_driver); +} + +static void apci035_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci035_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, apci035_pci_table); + +static struct pci_driver apci035_pci_driver = { + .name = "addi_apci_035", + .id_table = apci035_pci_table, + .probe = apci035_pci_probe, + .remove = apci035_pci_remove, +}; +module_comedi_pci_driver(apci035_driver, apci035_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 7831ce3..7f94242 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -1,8 +1,398 @@ -#define CONFIG_APCI_1032 1 +/* + * 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 + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + * You should also find the complete GPL in the COPYING file accompanying this + * source code. + */ -#define ADDIDATA_DRIVER_NAME "addi_apci_1032" +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#include "addi-data/addi_common.c" +/* + * 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_OR (0 << 1) +#define APCI1032_CTRL_INT_AND (1 << 1) +#define APCI1032_CTRL_INT_ENA (1 << 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; +} + +/* + * 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 + * 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 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; + + switch (data[0]) { + case INSN_CONFIG_DIGITAL_TRIG: + if (data[1] != 0) + return -EINVAL; + shift = data[3]; + oldmask = (1U << shift) - 1; + 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 |= data[4] << shift; + devpriv->mode2 |= data[5] << shift; + 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 |= data[4] << shift; + devpriv->mode2 |= data[5] << shift; + 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 |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_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 */ + + if (err) + return 2; + + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + + if (err) + return 3; + + /* step 4: ignored */ + + if (err) + return 4; + + 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; + + /* 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; + comedi_buf_put(s->async, s->state); + s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_event(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; + + dev->board_name = dev->driver->driver_name; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + 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 | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE; + 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->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) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (dev->iobase) + apci1032_reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + +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 *ent) +{ + return comedi_pci_auto_config(dev, &apci1032_driver); +} + +static void apci1032_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(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 = apci1032_pci_remove, +}; +module_comedi_pci_driver(apci1032_driver, apci1032_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index bfd84f6..8e686a9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -1,9 +1,77 @@ -#define CONFIG_APCI_1500 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_1500" +#include "addi-data/addi_common.h" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci1500.c" #include "addi-data/addi_common.c" +static const struct addi_board apci1500_boardtypes[] = { + { + .pc_DriverName = "apci1500", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = 0x80fc, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, + .i_IorangeBase2 = 4, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrDiChannel = 16, + .i_NbrDoChannel = 16, + .i_DoMaxdata = 0xffff, + .i_Timer = 1, + .interrupt = v_APCI1500_Interrupt, + .reset = i_APCI1500_Reset, + .di_config = i_APCI1500_ConfigDigitalInputEvent, + .di_read = i_APCI1500_Initialisation, + .di_write = i_APCI1500_StartStopInputEvent, + .di_bits = apci1500_di_insn_bits, + .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt, + .do_write = i_APCI1500_WriteDigitalOutput, + .do_bits = i_APCI1500_ConfigureInterrupt, + .timer_config = i_APCI1500_ConfigCounterTimerWatchdog, + .timer_write = i_APCI1500_StartStopTriggerTimerCounterWatchdog, + .timer_read = i_APCI1500_ReadInterruptMask, + .timer_bits = i_APCI1500_ReadCounterTimerWatchdog, + }, +}; + +static struct comedi_driver apci1500_driver = { + .driver_name = "addi_apci_1500", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1500_boardtypes), + .board_name = &apci1500_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci1500_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1500_driver); +} + +static void apci1500_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1500_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 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 = apci1500_pci_remove, +}; +module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index a12e2f4..8fef04b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -1,9 +1,349 @@ -#define CONFIG_APCI_1516 1 +/* + * 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 + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * You should also find the complete GPL in the COPYING file accompanying + * this source code. + */ -#define ADDIDATA_DRIVER_NAME "addi_apci_1516" +#include "../comedidev.h" +#include "comedi_fc.h" -#include "addi-data/addi_common.c" +/* + * PCI device ids supported by this driver + */ +#define PCI_DEVICE_ID_APCI1016 0x1000 +#define PCI_DEVICE_ID_APCI1516 0x1001 +#define PCI_DEVICE_ID_APCI2016 0x1002 +/* + * 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 +#define APCI1516_WDOG_RELOAD_REG 0x04 +#define APCI1516_WDOG_CTRL_REG 0x0c +#define APCI1516_WDOG_CTRL_ENABLE (1 << 0) +#define APCI1516_WDOG_CTRL_SW_TRIG (1 << 9) +#define APCI1516_WDOG_STATUS_REG 0x10 +#define APCI1516_WDOG_STATUS_ENABLED (1 << 0) +#define APCI1516_WDOG_STATUS_SW_TRIG (1 << 1) + +struct apci1516_boardinfo { + const char *name; + unsigned short device; + int di_nchan; + int do_nchan; + int has_wdog; +}; + +static const struct apci1516_boardinfo apci1516_boardtypes[] = { + { + .name = "apci1016", + .device = PCI_DEVICE_ID_APCI1016, + .di_nchan = 16, + }, { + .name = "apci1516", + .device = PCI_DEVICE_ID_APCI1516, + .di_nchan = 8, + .do_nchan = 8, + .has_wdog = 1, + }, { + .name = "apci2016", + .device = PCI_DEVICE_ID_APCI2016, + .do_nchan = 16, + .has_wdog = 1, + }, +}; + +struct apci1516_private { + unsigned long wdog_iobase; + unsigned int ctrl; +}; + +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) +{ + unsigned int mask = data[0]; + unsigned int bits = data[1]; + + s->state = inw(dev->iobase + APCI1516_DO_REG); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outw(s->state, dev->iobase + APCI1516_DO_REG); + } + + data[1] = s->state; + + return insn->n; +} + +/* + * 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 apci1516_wdog_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1516_private *devpriv = dev->private; + unsigned int reload; + + switch (data[0]) { + case INSN_CONFIG_ARM: + devpriv->ctrl = APCI1516_WDOG_CTRL_ENABLE; + reload = data[1] & s->maxdata; + outw(reload, devpriv->wdog_iobase + APCI1516_WDOG_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: + devpriv->ctrl = 0; + break; + default: + return -EINVAL; + } + + outw(devpriv->ctrl, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + + return insn->n; +} + +static int apci1516_wdog_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1516_private *devpriv = dev->private; + int i; + + if (devpriv->ctrl == 0) { + dev_warn(dev->class_dev, "watchdog is disabled\n"); + return -EINVAL; + } + + /* "ping" the watchdog */ + for (i = 0; i < insn->n; i++) { + outw(devpriv->ctrl | APCI1516_WDOG_CTRL_SW_TRIG, + devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + } + + return insn->n; +} + +static int apci1516_wdog_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1516_private *devpriv = dev->private; + int i; + + for (i = 0; i < insn->n; i++) + data[i] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG); + + return insn->n; +} + +static int apci1516_reset(struct comedi_device *dev) +{ + const struct apci1516_boardinfo *this_board = comedi_board(dev); + struct apci1516_private *devpriv = dev->private; + + if (!this_board->has_wdog) + return 0; + + outw(0x0, dev->iobase + APCI1516_DO_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG); + + return 0; +} + +static const void *apci1516_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct apci1516_boardinfo *this_board; + int i; + + for (i = 0; i < dev->driver->num_names; i++) { + this_board = &apci1516_boardtypes[i]; + if (this_board->device == pcidev->device) + return this_board; + } + return NULL; +} + +static int apci1516_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct apci1516_boardinfo *this_board; + struct apci1516_private *devpriv; + struct comedi_subdevice *s; + int ret; + + this_board = apci1516_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->name; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + 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 (this_board->di_nchan) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = this_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 (this_board->do_nchan) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITEABLE; + s->n_chan = this_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 (this_board->has_wdog) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE; + s->n_chan = 1; + s->maxdata = 0xff; + s->insn_write = apci1516_wdog_insn_write; + s->insn_read = apci1516_wdog_insn_read; + s->insn_config = apci1516_wdog_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + apci1516_reset(dev); + return 0; +} + +static void apci1516_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (dev->iobase) { + apci1516_reset(dev); + comedi_pci_disable(pcidev); + } +} + +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 *ent) +{ + return comedi_pci_auto_config(dev, &apci1516_driver); +} + +static void apci1516_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1016) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1516) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_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 = apci1516_pci_remove, +}; +module_comedi_pci_driver(apci1516_driver, apci1516_pci_driver); + +MODULE_DESCRIPTION("ADDI-DATA APCI-1016/1516/2016, 16 channel DIO boards"); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 1b9d598..513e536 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -1,9 +1,74 @@ -#define CONFIG_APCI_1564 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_1564" +#include "addi-data/addi_common.h" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci1564.c" #include "addi-data/addi_common.c" +static const struct addi_board apci1564_boardtypes[] = { + { + .pc_DriverName = "apci1564", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1006, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1564_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 32, + .i_NbrDoChannel = 32, + .i_DoMaxdata = 0xffffffff, + .i_Timer = 1, + .interrupt = v_APCI1564_Interrupt, + .reset = i_APCI1564_Reset, + .di_config = i_APCI1564_ConfigDigitalInput, + .di_bits = apci1564_di_insn_bits, + .do_config = i_APCI1564_ConfigDigitalOutput, + .do_bits = apci1564_do_insn_bits, + .do_read = i_APCI1564_ReadInterruptStatus, + .timer_config = i_APCI1564_ConfigTimerCounterWatchdog, + .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog, + .timer_read = i_APCI1564_ReadTimerCounterWatchdog, + }, +}; + +static struct comedi_driver apci1564_driver = { + .driver_name = "addi_apci_1564", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1564_boardtypes), + .board_name = &apci1564_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci1564_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1564_driver); +} + +static void apci1564_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(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 = apci1564_pci_remove, +}; +module_comedi_pci_driver(apci1564_driver, apci1564_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index d54218d..ab9a96a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -1,9 +1,77 @@ -#define CONFIG_APCI_16XX 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_16xx" +#include "addi-data/addi_common.h" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci16xx.c" #include "addi-data/addi_common.c" +static const struct addi_board apci16xx_boardtypes[] = { + { + .pc_DriverName = "apci1648", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1009, + .i_IorangeBase0 = 128, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrTTLChannel = 48, + .reset = i_APCI16XX_Reset, + .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, + .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, + .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, + }, { + .pc_DriverName = "apci1696", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x100A, + .i_IorangeBase0 = 128, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrTTLChannel = 96, + .reset = i_APCI16XX_Reset, + .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, + .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, + .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, + }, +}; + +static struct comedi_driver apci16xx_driver = { + .driver_name = "addi_apci_16xx", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci16xx_boardtypes), + .board_name = &apci16xx_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci16xx_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci16xx_driver); +} + +static void apci16xx_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100a) }, + { 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 = apci16xx_pci_remove, +}; +module_comedi_pci_driver(apci16xx_driver, apci16xx_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index df6ba8c..152e7ef 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -1,5 +1,152 @@ -#define CONFIG_APCI_1710 1 +#include <asm/i387.h> -#define ADDIDATA_DRIVER_NAME "addi_apci_1710" +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#include "addi-data/addi_common.c" +#include "addi-data/addi_common.h" + +static void fpu_begin(void) +{ + kernel_fpu_begin(); +} + +static void fpu_end(void) +{ + kernel_fpu_end(); +} + +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_APCI1710.c" + +static const struct addi_board apci1710_boardtypes[] = { + { + .pc_DriverName = "apci1710", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = APCI1710_BOARD_DEVICE_ID, + .interrupt = v_APCI1710_Interrupt, + }, +}; + +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} + +static const void *apci1710_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct addi_board *this_board; + int i; + + for (i = 0; i < ARRAY_SIZE(apci1710_boardtypes); i++) { + this_board = &apci1710_boardtypes[i]; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + } + return NULL; +} + +static int apci1710_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct addi_board *this_board; + struct addi_private *devpriv; + struct comedi_subdevice *s; + int ret; + + this_board = apci1710_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + i_ADDI_AttachPCI1710(dev); + + devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); + + i_APCI1710_Reset(dev); + return 0; +} + +static void apci1710_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (dev->iobase) + i_APCI1710_Reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + +static struct comedi_driver apci1710_driver = { + .driver_name = "addi_apci_1710", + .module = THIS_MODULE, + .auto_attach = apci1710_auto_attach, + .detach = apci1710_detach, +}; + +static int apci1710_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1710_driver); +} + +static void apci1710_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1710_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, apci1710_pci_table); + +static struct pci_driver apci1710_pci_driver = { + .name = "addi_apci_1710", + .id_table = apci1710_pci_table, + .probe = apci1710_pci_probe, + .remove = apci1710_pci_remove, +}; +module_comedi_pci_driver(apci1710_driver, apci1710_pci_driver); + +MODULE_AUTHOR("Comedi http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c deleted file mode 100644 index fa50c7b..0000000 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ /dev/null @@ -1,9 +0,0 @@ -#define CONFIG_APCI_2016 1 - -#define ADDIDATA_DRIVER_NAME "addi_apci_2016" - -#include "addi-data/addi_common.c" - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 073a8a5..8f8d3e9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -1,8 +1,383 @@ -#define CONFIG_APCI_2032 1 +/* + * 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 + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * You should also find the complete GPL in the COPYING file accompanying + * this source code. + */ -#define ADDIDATA_DRIVER_NAME "addi_apci_2032" +#include "../comedidev.h" +#include "comedi_fc.h" -#include "addi-data/addi_common.c" +/* + * PCI bar 1 I/O Register map + */ +#define APCI2032_DO_REG 0x00 +#define APCI2032_INT_CTRL_REG 0x04 +#define APCI2032_INT_CTRL_VCC_ENA (1 << 0) +#define APCI2032_INT_CTRL_CC_ENA (1 << 1) +#define APCI2032_INT_STATUS_REG 0x08 +#define APCI2032_INT_STATUS_VCC (1 << 0) +#define APCI2032_INT_STATUS_CC (1 << 1) +#define APCI2032_STATUS_REG 0x0c +#define APCI2032_STATUS_IRQ (1 << 0) +#define APCI2032_WDOG_REG 0x10 +#define APCI2032_WDOG_RELOAD_REG 0x14 +#define APCI2032_WDOG_TIMEBASE 0x18 +#define APCI2032_WDOG_CTRL_REG 0x1c +#define APCI2032_WDOG_CTRL_ENABLE (1 << 0) +#define APCI2032_WDOG_CTRL_SW_TRIG (1 << 9) +#define APCI2032_WDOG_STATUS_REG 0x20 +#define APCI2032_WDOG_STATUS_ENABLED (1 << 0) +#define APCI2032_WDOG_STATUS_SW_TRIG (1 << 1) + +struct apci2032_private { + unsigned int wdog_ctrl; +}; + +static int apci2032_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int mask = data[0]; + unsigned int bits = data[1]; + + s->state = inl(dev->iobase + APCI2032_DO_REG); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outl(s->state, dev->iobase + APCI2032_DO_REG); + } + + data[1] = s->state; + + return insn->n; +} + +/* + * 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 apci2032_wdog_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci2032_private *devpriv = dev->private; + unsigned int reload; + + switch (data[0]) { + case INSN_CONFIG_ARM: + devpriv->wdog_ctrl = APCI2032_WDOG_CTRL_ENABLE; + reload = data[1] & s->maxdata; + outw(reload, dev->iobase + APCI2032_WDOG_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: + devpriv->wdog_ctrl = 0; + break; + default: + return -EINVAL; + } + + outw(devpriv->wdog_ctrl, dev->iobase + APCI2032_WDOG_CTRL_REG); + + return insn->n; +} + +static int apci2032_wdog_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci2032_private *devpriv = dev->private; + int i; + + if (devpriv->wdog_ctrl == 0) { + dev_warn(dev->class_dev, "watchdog is disabled\n"); + return -EINVAL; + } + + /* "ping" the watchdog */ + for (i = 0; i < insn->n; i++) { + outw(devpriv->wdog_ctrl | APCI2032_WDOG_CTRL_SW_TRIG, + dev->iobase + APCI2032_WDOG_CTRL_REG); + } + + return insn->n; +} + +static int apci2032_wdog_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] = inl(dev->iobase + APCI2032_WDOG_STATUS_REG); + + 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] = s->state; + return insn->n; +} + +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 |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_OTHER); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_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 */ + + if (err) + return 2; + + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + /* + * 0 == no trigger + * 1 == trigger on VCC interrupt + * 2 == trigger on CC interrupt + * 3 == trigger on either VCC or CC interrupt + */ + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 3); + + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + + if (err) + return 3; + + /* step 4: ignored */ + + if (err) + return 4; + + return 0; +} + +static int apci2032_int_cmd(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct comedi_cmd *cmd = &s->async->cmd; + + outl(cmd->scan_begin_arg, dev->iobase + APCI2032_INT_CTRL_REG); + + return 0; +} + +static int apci2032_int_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG); + + return 0; +} + +static irqreturn_t apci2032_interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; + unsigned int val; + + /* Check if VCC OR CC interrupt has occurred */ + val = inl(dev->iobase + APCI2032_STATUS_REG) & APCI2032_STATUS_IRQ; + if (!val) + return IRQ_NONE; + + s->state = inl(dev->iobase + APCI2032_INT_STATUS_REG); + outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG); + + comedi_buf_put(s->async, s->state); + s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_event(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); + outl(0x0, dev->iobase + APCI2032_WDOG_CTRL_REG); + outl(0x0, dev->iobase + APCI2032_WDOG_RELOAD_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 apci2032_private *devpriv; + struct comedi_subdevice *s; + int ret; + + dev->board_name = dev->driver->driver_name; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev->iobase = pci_resource_start(pcidev, 1); + + 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_WRITEABLE; + 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]; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE; + s->n_chan = 1; + s->maxdata = 0xff; + s->insn_write = apci2032_wdog_insn_write; + s->insn_read = apci2032_wdog_insn_read; + s->insn_config = apci2032_wdog_insn_config; + + /* Initialize the interrupt subdevice */ + s = &dev->subdevices[2]; + if (dev->irq) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_DI | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE; + s->n_chan = 1; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = apci2032_int_insn_bits; + s->do_cmdtest = apci2032_int_cmdtest; + s->do_cmd = apci2032_int_cmd; + s->cancel = apci2032_int_cancel; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + apci2032_reset(dev); + return 0; +} + +static void apci2032_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (dev->iobase) + apci2032_reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + +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 *ent) +{ + return comedi_pci_auto_config(dev, &apci2032_driver); +} + +static void apci2032_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(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 = apci2032_pci_remove, +}; +module_comedi_pci_driver(apci2032_driver, apci2032_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index adfbb5d..7c2c5db 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -1,9 +1,69 @@ -#define CONFIG_APCI_2200 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_2200" +#include "addi-data/addi_common.h" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci2200.c" #include "addi-data/addi_common.c" +static const struct addi_board apci2200_boardtypes[] = { + { + .pc_DriverName = "apci2200", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1005, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI2200_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 8, + .i_NbrDoChannel = 16, + .i_Timer = 1, + .reset = i_APCI2200_Reset, + .di_bits = apci2200_di_insn_bits, + .do_bits = apci2200_do_insn_bits, + .timer_config = i_APCI2200_ConfigWatchdog, + .timer_write = i_APCI2200_StartStopWriteWatchdog, + .timer_read = i_APCI2200_ReadWatchdog, + }, +}; + +static struct comedi_driver apci2200_driver = { + .driver_name = "addi_apci_2200", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci2200_boardtypes), + .board_name = &apci2200_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci2200_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci2200_driver); +} + +static void apci2200_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(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 = apci2200_pci_remove, +}; +module_comedi_pci_driver(apci2200_driver, apci2200_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c deleted file mode 100644 index 00ac762..0000000 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ /dev/null @@ -1,9 +0,0 @@ -#define CONFIG_APCI_3001 1 - -#define ADDIDATA_DRIVER_NAME "addi_apci_3001" - -#include "addi-data/addi_common.c" - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index c355158..fec2962 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1,8 +1,275 @@ -#define CONFIG_APCI_3120 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_3120" +#include "addi-data/addi_common.h" -#include "addi-data/addi_common.c" +#include "addi-data/hwdrv_apci3120.c" + +static const struct addi_board apci3120_boardtypes[] = { + { + .pc_DriverName = "apci3120", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = 0x818D, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 8, + .i_AiMaxdata = 0xffff, + .i_AoMaxdata = 0x3fff, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 0x0f, + .interrupt = v_APCI3120_Interrupt, + }, { + .pc_DriverName = "apci3001", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = 0x828D, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0xfff, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 0x0f, + .interrupt = v_APCI3120_Interrupt, + }, +}; + +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} + +static const void *apci3120_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct addi_board *this_board; + int i; + + for (i = 0; i < ARRAY_SIZE(apci3120_boardtypes); i++) { + this_board = &apci3120_boardtypes[i]; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + } + return NULL; +} + +static int apci3120_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct addi_board *this_board; + struct addi_private *devpriv; + struct comedi_subdevice *s; + int ret, pages, i; + + this_board = apci3120_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + pci_set_master(pcidev); + + dev->iobase = pci_resource_start(pcidev, 1); + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + devpriv->us_UseDma = ADDI_ENABLE; + + /* Allocate DMA buffers */ + devpriv->b_DmaDoubleBuffer = 0; + for (i = 0; i < 2; i++) { + for (pages = 4; pages >= 0; pages--) { + devpriv->ul_DmaBufferVirtual[i] = + (void *) __get_free_pages(GFP_KERNEL, pages); + + if (devpriv->ul_DmaBufferVirtual[i]) + break; + } + if (devpriv->ul_DmaBufferVirtual[i]) { + devpriv->ui_DmaBufferPages[i] = pages; + devpriv->ui_DmaBufferSize[i] = PAGE_SIZE * pages; + devpriv->ui_DmaBufferSamples[i] = + devpriv->ui_DmaBufferSize[i] >> 1; + devpriv->ul_DmaBufferHw[i] = + virt_to_bus((void *)devpriv-> + ul_DmaBufferVirtual[i]); + } + } + if (!devpriv->ul_DmaBufferVirtual[0]) + devpriv->us_UseDma = ADDI_DISABLE; + + if (devpriv->ul_DmaBufferVirtual[1]) + devpriv->b_DmaDoubleBuffer = 1; + + ret = comedi_alloc_subdevices(dev, 5); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (this_board->i_NbrAiChannel) { + s->n_chan = this_board->i_NbrAiChannel; + devpriv->b_SingelDiff = 0; + } else { + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; + } + s->maxdata = this_board->i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = &range_apci3120_ai; + + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; + + s->insn_config = i_APCI3120_InsnConfigAnalogInput; + s->insn_read = i_APCI3120_InsnReadAnalogInput; + s->do_cmdtest = i_APCI3120_CommandTestAnalogInput; + s->do_cmd = i_APCI3120_CommandAnalogInput; + s->cancel = i_APCI3120_StopCyclicAcquisition; + + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (this_board->i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrAoChannel; + s->maxdata = this_board->i_AoMaxdata; + s->len_chanlist = this_board->i_NbrAoChannel; + s->range_table = &range_apci3120_ao; + s->insn_write = i_APCI3120_InsnWriteAnalogOutput; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = this_board->i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_bits = apci3120_di_insn_bits; + + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrDoChannel; + s->maxdata = this_board->i_DoMaxdata; + s->len_chanlist = this_board->i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ + s->insn_bits = apci3120_do_insn_bits; + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = i_APCI3120_InsnWriteTimer; + s->insn_read = i_APCI3120_InsnReadTimer; + s->insn_config = i_APCI3120_InsnConfigTimer; + + i_APCI3120_Reset(dev); + return 0; +} + +static void apci3120_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct addi_private *devpriv = dev->private; + + if (devpriv) { + if (dev->iobase) + i_APCI3120_Reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv->ul_DmaBufferVirtual[0]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[0], + devpriv->ui_DmaBufferPages[0]); + } + if (devpriv->ul_DmaBufferVirtual[1]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[1], + devpriv->ui_DmaBufferPages[1]); + } + } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + +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 *ent) +{ + return comedi_pci_auto_config(dev, &apci3120_driver); +} + +static void apci3120_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) }, + { 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 = apci3120_pci_remove, +}; +module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 1593139..9085b77 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -1,5 +1,120 @@ -#define CONFIG_APCI_3200 1 +#include <asm/i387.h> -#define ADDIDATA_DRIVER_NAME "addi_apci_3200" +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" +#include "addi-data/addi_common.h" + +static void fpu_begin(void) +{ + kernel_fpu_begin(); +} + +static void fpu_end(void) +{ + kernel_fpu_end(); +} + +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3200.c" #include "addi-data/addi_common.c" + +static const struct addi_board apci3200_boardtypes[] = { + { + .pc_DriverName = "apci3200", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3000, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 4, + .i_IorangeBase3 = 4, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0x3ffff, + .pr_AiRangelist = &range_apci3200_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3200_Interrupt, + .reset = i_APCI3200_Reset, + .ai_config = i_APCI3200_ConfigAnalogInput, + .ai_read = i_APCI3200_ReadAnalogInput, + .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, + .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, + .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, + .ai_cmd = i_APCI3200_CommandAnalogInput, + .ai_cancel = i_APCI3200_StopCyclicAcquisition, + .di_bits = apci3200_di_insn_bits, + .do_bits = apci3200_do_insn_bits, + }, { + .pc_DriverName = "apci3300", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3007, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 4, + .i_IorangeBase3 = 4, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 8, + .i_AiMaxdata = 0x3ffff, + .pr_AiRangelist = &range_apci3300_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3200_Interrupt, + .reset = i_APCI3200_Reset, + .ai_config = i_APCI3200_ConfigAnalogInput, + .ai_read = i_APCI3200_ReadAnalogInput, + .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, + .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, + .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, + .ai_cmd = i_APCI3200_CommandAnalogInput, + .ai_cancel = i_APCI3200_StopCyclicAcquisition, + .di_bits = apci3200_di_insn_bits, + .do_bits = apci3200_do_insn_bits, + }, +}; + +static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, apci3200_pci_table); + +static struct comedi_driver apci3200_driver = { + .driver_name = "addi_apci_3200", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3200_boardtypes), + .board_name = &apci3200_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci3200_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3200_driver); +} + +static void apci3200_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver apci3200_pci_driver = { + .name = "addi_apci_3200", + .id_table = apci3200_pci_table, + .probe = apci3200_pci_probe, + .remove = apci3200_pci_remove, +}; +module_comedi_pci_driver(apci3200_driver, apci3200_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c deleted file mode 100644 index 733c69a..0000000 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ /dev/null @@ -1,5 +0,0 @@ -#define CONFIG_APCI_3300 1 - -#define ADDIDATA_DRIVER_NAME "addi_apci_3300" - -#include "addi-data/addi_common.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index dd2c1d3..ed297de 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -1,9 +1,75 @@ -#define CONFIG_APCI_3501 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_3501" +#include "addi-data/addi_common.h" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3501.c" #include "addi-data/addi_common.c" +static const struct addi_board apci3501_boardtypes[] = { + { + .pc_DriverName = "apci3501", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3001, + .i_IorangeBase0 = 64, + .i_IorangeBase1 = APCI3501_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5933, + .i_AoMaxdata = 16383, + .pr_AoRangelist = &range_apci3501_ao, + .i_NbrDiChannel = 2, + .i_NbrDoChannel = 2, + .i_DoMaxdata = 0x3, + .i_Timer = 1, + .interrupt = v_APCI3501_Interrupt, + .reset = i_APCI3501_Reset, + .ao_config = i_APCI3501_ConfigAnalogOutput, + .ao_write = i_APCI3501_WriteAnalogOutput, + .di_bits = apci3501_di_insn_bits, + .do_bits = apci3501_do_insn_bits, + .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, + .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog, + .timer_read = i_APCI3501_ReadTimerCounterWatchdog, + }, +}; + +static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, apci3501_pci_table); + +static struct comedi_driver apci3501_driver = { + .driver_name = "addi_apci_3501", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3501_boardtypes), + .board_name = &apci3501_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci3501_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3501_driver); +} + +static void apci3501_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver apci3501_pci_driver = { + .name = "addi_apci_3501", + .id_table = apci3501_pci_table, + .probe = apci3501_pci_probe, + .remove = apci3501_pci_remove, +}; +module_comedi_pci_driver(apci3501_driver, apci3501_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 03161c8..1562347 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -1,9 +1,799 @@ -#define CONFIG_APCI_3XXX 1 +#include "../comedidev.h" +#include "comedi_fc.h" +#include "amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_3xxx" +#include "addi-data/addi_common.h" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3xxx.c" #include "addi-data/addi_common.c" +static const struct addi_board apci3xxx_boardtypes[] = { + { + .pc_DriverName = "apci3000-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3010, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3000-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300F, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3000-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300E, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3013, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3014, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3015, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3016, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3017, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3018, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3019, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301A, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301B, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3100-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301C, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3100-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301D, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3106-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301E, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3106-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301F, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3110-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3020, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3110-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3021, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3116-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3022, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3116-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3023, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3003", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300B, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 7, + .ui_MinAcquisitiontimeNs = 2500, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + }, { + .pc_DriverName = "apci3002-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3002, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 16, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + }, { + .pc_DriverName = "apci3002-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3003, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + }, { + .pc_DriverName = "apci3002-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3004, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_bits = apci3xxx_di_insn_bits, + .do_bits = apci3xxx_do_insn_bits, + }, { + .pc_DriverName = "apci3500", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3024, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAoChannel = 4, + .i_AoMaxdata = 4095, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, +}; + +static struct comedi_driver apci3xxx_driver = { + .driver_name = "addi_apci_3xxx", + .module = THIS_MODULE, + .auto_attach = addi_auto_attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3xxx_boardtypes), + .board_name = &apci3xxx_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int apci3xxx_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3xxx_driver); +} + +static void apci3xxx_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300f) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300e) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301a) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301b) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301c) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301d) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301e) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301f) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024) }, + { 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 = apci3xxx_pci_remove, +}; +module_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 3492ce1..9a56eed 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -174,27 +174,26 @@ static const void *pci6208_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci6208_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int pci6208_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci6208_board *boardinfo; struct pci6208_private *devpriv; struct comedi_subdevice *s; unsigned int val; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - boardinfo = pci6208_find_boardinfo(dev, pcidev); if (!boardinfo) return -ENODEV; dev->board_ptr = boardinfo; dev->board_name = boardinfo->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -261,17 +260,17 @@ static void pci6208_detach(struct comedi_device *dev) static struct comedi_driver adl_pci6208_driver = { .driver_name = "adl_pci6208", .module = THIS_MODULE, - .attach_pci = pci6208_attach_pci, + .auto_attach = pci6208_auto_attach, .detach = pci6208_detach, }; -static int __devinit adl_pci6208_pci_probe(struct pci_dev *dev, +static int adl_pci6208_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci6208_driver); } -static void __devexit adl_pci6208_pci_remove(struct pci_dev *dev) +static void adl_pci6208_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -287,7 +286,7 @@ static struct pci_driver adl_pci6208_pci_driver = { .name = "adl_pci6208", .id_table = adl_pci6208_pci_table, .probe = adl_pci6208_pci_probe, - .remove = __devexit_p(adl_pci6208_pci_remove), + .remove = adl_pci6208_pci_remove, }; module_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 599714e..772edc0 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -168,17 +168,16 @@ static const void *adl_pci7x3x_find_boardinfo(struct comedi_device *dev, return NULL; } -static int adl_pci7x3x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int adl_pci7x3x_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct adl_pci7x3x_boardinfo *board; struct comedi_subdevice *s; int subdev; int nchan; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - board = adl_pci7x3x_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; @@ -293,17 +292,17 @@ static void adl_pci7x3x_detach(struct comedi_device *dev) static struct comedi_driver adl_pci7x3x_driver = { .driver_name = "adl_pci7x3x", .module = THIS_MODULE, - .attach_pci = adl_pci7x3x_attach_pci, + .auto_attach = adl_pci7x3x_auto_attach, .detach = adl_pci7x3x_detach, }; -static int __devinit adl_pci7x3x_pci_probe(struct pci_dev *dev, +static int adl_pci7x3x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci7x3x_driver); } -static void __devexit adl_pci7x3x_pci_remove(struct pci_dev *dev) +static void adl_pci7x3x_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -323,7 +322,7 @@ static struct pci_driver adl_pci7x3x_pci_driver = { .name = "adl_pci7x3x", .id_table = adl_pci7x3x_pci_table, .probe = adl_pci7x3x_pci_probe, - .remove = __devexit_p(adl_pci7x3x_pci_remove), + .remove = adl_pci7x3x_pci_remove, }; module_comedi_pci_driver(adl_pci7x3x_driver, adl_pci7x3x_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 05e06e7..4dd9d70 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -89,9 +89,9 @@ static void adl_pci8164_insn_read(struct comedi_device *dev, } data[0] = inw(dev->iobase + axis_reg + offset); - printk(KERN_DEBUG "comedi: pci8164 %s read -> " - "%04X:%04X on axis %s\n", - action, data[0], data[1], axisname); + dev_dbg(dev->class_dev, + "pci8164 %s read -> %04X:%04X on axis %s\n", + action, data[0], data[1], axisname); } static int adl_pci8164_insn_read_msts(struct comedi_device *dev, @@ -170,9 +170,9 @@ static void adl_pci8164_insn_out(struct comedi_device *dev, outw(data[0], dev->iobase + axis_reg + offset); - printk(KERN_DEBUG "comedi: pci8164 %s write -> " - "%04X:%04X on axis %s\n", - action, data[0], data[1], axisname); + dev_dbg(dev->class_dev, + "pci8164 %s write -> %04X:%04X on axis %s\n", + action, data[0], data[1], axisname); } @@ -212,14 +212,13 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, return 2; } -static int adl_pci8164_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +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; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); @@ -289,17 +288,17 @@ static void adl_pci8164_detach(struct comedi_device *dev) static struct comedi_driver adl_pci8164_driver = { .driver_name = "adl_pci8164", .module = THIS_MODULE, - .attach_pci = adl_pci8164_attach_pci, + .auto_attach = adl_pci8164_auto_attach, .detach = adl_pci8164_detach, }; -static int __devinit adl_pci8164_pci_probe(struct pci_dev *dev, +static int adl_pci8164_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci8164_driver); } -static void __devexit adl_pci8164_pci_remove(struct pci_dev *dev) +static void adl_pci8164_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -314,7 +313,7 @@ static struct pci_driver adl_pci8164_pci_driver = { .name = "adl_pci8164", .id_table = adl_pci8164_pci_table, .probe = adl_pci8164_pci_probe, - .remove = __devexit_p(adl_pci8164_pci_remove), + .remove = adl_pci8164_pci_remove, }; module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index a87192a..a339b9d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -366,52 +366,29 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, if (error) return 2; - /* Step 3 : make sure arguments are trivialy compatible */ + /* Step 3: check if arguments are trivially valid */ - if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { - cmd->start_arg = 0; - error++; - } + error |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if ((cmd->convert_src == TRIG_TIMER) && - (cmd->convert_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { - cmd->convert_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; - error++; - } - if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { - cmd->convert_arg = 0; - error++; - } + if (cmd->convert_src == TRIG_TIMER) + error |= cfc_check_trigger_arg_min(&cmd->convert_arg, + PCI9111_AI_ACQUISITION_PERIOD_MIN_NS); + else /* TRIG_EXT */ + error |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if ((cmd->scan_begin_src == TRIG_TIMER) && - (cmd->scan_begin_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { - cmd->scan_begin_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; - error++; - } - if ((cmd->scan_begin_src == TRIG_FOLLOW) - && (cmd->scan_begin_arg != 0)) { - cmd->scan_begin_arg = 0; - error++; - } - if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) { - cmd->scan_begin_arg = 0; - error++; - } + if (cmd->scan_begin_src == TRIG_TIMER) + error |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + PCI9111_AI_ACQUISITION_PERIOD_MIN_NS); + else /* TRIG_FOLLOW || TRIG_EXT */ + error |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if ((cmd->scan_end_src == TRIG_COUNT) && - (cmd->scan_end_arg != cmd->chanlist_len)) { - cmd->scan_end_arg = cmd->chanlist_len; - error++; - } + error |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, + cmd->chanlist_len); - if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) { - cmd->stop_arg = 1; - error++; - } - if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) { - cmd->stop_arg = 0; - error++; - } + if (cmd->stop_src == TRIG_COUNT) + error |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + error |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (error) return 3; @@ -879,20 +856,20 @@ static int pci9111_reset(struct comedi_device *dev) return 0; } -static int pci9111_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +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; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*dev_private)); - if (ret) - return ret; - dev_private = dev->private; + dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL); + if (!dev_private) + return -ENOMEM; + dev->private = dev_private; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -976,17 +953,17 @@ static void pci9111_detach(struct comedi_device *dev) static struct comedi_driver adl_pci9111_driver = { .driver_name = "adl_pci9111", .module = THIS_MODULE, - .attach_pci = pci9111_attach_pci, + .auto_attach = pci9111_auto_attach, .detach = pci9111_detach, }; -static int __devinit pci9111_pci_probe(struct pci_dev *dev, +static int pci9111_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci9111_driver); } -static void __devexit pci9111_pci_remove(struct pci_dev *dev) +static void pci9111_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1002,7 +979,7 @@ static struct pci_driver adl_pci9111_pci_driver = { .name = "adl_pci9111", .id_table = pci9111_pci_table, .probe = pci9111_pci_probe, - .remove = __devexit_p(pci9111_pci_remove), + .remove = pci9111_pci_remove, }; module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 06ff65c..b6dda80 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -62,6 +62,20 @@ Configuration options: 256|=ignore nFull - A/D FIFO Full status */ + +/* + * 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 "../comedidev.h" #include <linux/delay.h> @@ -73,8 +87,6 @@ Configuration options: #include "8253.h" #include "comedi_fc.h" -#define PCI_VENDOR_ID_AMCC 0x10e8 - /* paranoid checks are broken */ #undef PCI9118_PARANOIDCHECK /* * if defined, then is used code which control @@ -210,8 +222,7 @@ static const struct comedi_lrange range_pci9118hg = { 8, { struct boardtype { const char *name; /* board name */ - int vendor_id; /* PCI vendor a device ID of card */ - int device_id; + int device_id; /* PCI device ID of card */ int iorange_amcc; /* iorange for own S5933 region */ int iorange_9118; /* pass thru card region size */ int n_aichan; /* num of A/D chans */ @@ -235,6 +246,61 @@ struct boardtype { }; +static const struct boardtype boardtypes[] = { + { + .name = "pci9118dg", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hg", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118hg, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hr", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0xffff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 10000, + .ai_pacer_min = 40, + .half_fifo_size = 512, + }, +}; + struct pci9118_private { unsigned long iobase_a; /* base+size for AMCC chip */ unsigned int master; /* master capable */ @@ -358,10 +424,8 @@ static int check_channel_list(struct comedi_device *dev, return 0; } if ((frontadd + n_chan + backadd) > s->len_chanlist) { - printk - ("comedi%d: range/channel list is too long for " - "actual configuration (%d>%d)!", - dev->minor, n_chan, s->len_chanlist - frontadd - backadd); + comedi_error(dev, + "range/channel list is too long for actual configuration!\n"); return 0; } @@ -892,11 +956,10 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, if (devpriv->ai16bits == 0) { if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { /* data dropout! */ - printk - ("comedi: A/D SAMPL - data dropout: " - "received channel %d, expected %d!\n", - sampl & 0x000f, - devpriv->chanlist[s->async->cur_chan]); + dev_info(dev->class_dev, + "A/D SAMPL - data dropout: received channel %d, expected %d!\n", + sampl & 0x000f, + devpriv->chanlist[s->async->cur_chan]); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; pci9118_ai_cancel(dev, s); comedi_event(dev, s); @@ -1153,19 +1216,13 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->start_src & (TRIG_NOW | TRIG_EXT)) - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT)) - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_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)) { @@ -1175,64 +1232,40 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, } if (cmd->scan_begin_src == TRIG_TIMER) - if (cmd->scan_begin_arg < this_board->ai_ns_min) { - cmd->scan_begin_arg = this_board->ai_ns_min; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + this_board->ai_ns_min); if (cmd->scan_begin_src == TRIG_EXT) if (cmd->scan_begin_arg) { cmd->scan_begin_arg = 0; - err++; - if (cmd->scan_end_arg > 65535) { - cmd->scan_end_arg = 65535; - err++; - } + err |= -EINVAL; + err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, + 65535); } if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) - if (cmd->convert_arg < this_board->ai_ns_min) { - cmd->convert_arg = this_board->ai_ns_min; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + this_board->ai_ns_min); if (cmd->convert_src == TRIG_EXT) - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, + this_board->n_aichanlist); - if (cmd->chanlist_len > this_board->n_aichanlist) { - cmd->chanlist_len = this_board->n_aichanlist; - err++; - } - - if (cmd->scan_end_arg < cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_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++; + err |= -EINVAL; } if (err) @@ -1318,21 +1351,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev) if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); - printk - ("comedi%d: WAR: DMA0 buf too short, can't " - "support TRIG_WAKE_EOS (%d<%d)\n", - dev->minor, dmalen0, - devpriv->ai_n_realscanlen << 1); + dev_info(dev->class_dev, + "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n", + dmalen0, devpriv->ai_n_realscanlen << 1); } else { /* short first DMA buffer to one scan */ dmalen0 = devpriv->ai_n_realscanlen << 1; if (devpriv->useeoshandle) dmalen0 += 2; if (dmalen0 < 4) { - printk - ("comedi%d: ERR: DMA0 buf len bug? " - "(%d<4)\n", - dev->minor, dmalen0); + dev_info(dev->class_dev, + "ERR: DMA0 buf len bug? (%d<4)\n", + dmalen0); dmalen0 = 4; } } @@ -1341,21 +1371,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev) if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); - printk - ("comedi%d: WAR: DMA1 buf too short, " - "can't support TRIG_WAKE_EOS (%d<%d)\n", - dev->minor, dmalen1, - devpriv->ai_n_realscanlen << 1); + dev_info(dev->class_dev, + "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n", + dmalen1, devpriv->ai_n_realscanlen << 1); } else { /* short second DMA buffer to one scan */ dmalen1 = devpriv->ai_n_realscanlen << 1; if (devpriv->useeoshandle) dmalen1 -= 2; if (dmalen1 < 4) { - printk - ("comedi%d: ERR: DMA1 buf len bug? " - "(%d<4)\n", - dev->minor, dmalen1); + dev_info(dev->class_dev, + "ERR: DMA1 buf len bug? (%d<4)\n", + dmalen1); dmalen1 = 4; } } @@ -1865,6 +1892,20 @@ static int pci9118_reset(struct comedi_device *dev) return 0; } +/* + * FIXME - this is pretty ineffective because all the supported board types + * have the same device ID! + */ +static const struct boardtype *pci9118_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(boardtypes); i++) + if (pcidev->device == boardtypes[i].device_id) + return &boardtypes[i]; + return NULL; +} + static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1884,85 +1925,63 @@ static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, PCI_SLOT(pcidev->devfn) != slot) continue; } - /* - * Look for device that isn't in use. - * Enable PCI device and request regions. - */ - if (comedi_pci_enable(pcidev, "adl_pci9118")) - continue; - printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", - pcidev->bus->number, - PCI_SLOT(pcidev->devfn), - PCI_FUNC(pcidev->devfn), - (unsigned long)pci_resource_start(pcidev, 2), - (unsigned long)pci_resource_start(pcidev, 0)); return pcidev; } - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); + dev_err(dev->class_dev, + "no supported board found! (req. bus/slot : %d/%d)\n", + bus, slot); return NULL; } -static int pci9118_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9118_private *devpriv = dev->private; + char irqbuf[30]; + char muxbuf[30]; + + if (irq) + snprintf(irqbuf, sizeof(irqbuf), "irq %u%s", irq, + (dev->irq ? "" : " UNAVAILABLE")); + else + snprintf(irqbuf, sizeof(irqbuf), "irq DISABLED"); + if (devpriv->usemux) + snprintf(muxbuf, sizeof(muxbuf), "ext mux %u chans", + devpriv->usemux); + else + snprintf(muxbuf, sizeof(muxbuf), "no ext mux"); + dev_info(dev->class_dev, "%s (pci %s, %s, %sbus master, %s) attached\n", + dev->board_name, pci_name(pcidev), irqbuf, + (devpriv->master ? "" : "no "), muxbuf); +} + +static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, + int master, int ext_mux, int softsshdelay, + int hw_err_mask) { const struct boardtype *this_board = comedi_board(dev); - struct pci9118_private *devpriv; - struct pci_dev *pcidev; + struct pci9118_private *devpriv = dev->private; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret, pages, i; - unsigned short master; unsigned int irq; u16 u16w; - printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name); - - if (it->options[3] & 1) - master = 0; /* user don't want use bus master */ - else - master = 1; - - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) { - printk(" - Allocation failed!\n"); - return -ENOMEM; + dev->board_name = this_board->name; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) { + dev_err(dev->class_dev, + "cannot enable PCI device %s\n", pci_name(pcidev)); + return ret; } - devpriv = dev->private; - - pcidev = pci9118_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - if (master) pci_set_master(pcidev); - irq = pcidev->irq; devpriv->iobase_a = pci_resource_start(pcidev, 0); dev->iobase = pci_resource_start(pcidev, 2); - dev->board_name = this_board->name; - pci9118_reset(dev); - if (it->options[3] & 2) - irq = 0; /* user don't want use IRQ */ - if (irq > 0) { - if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, - "ADLink PCI-9118", dev)) { - printk(", unable to allocate IRQ %d, DISABLING IT", - irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(", irq=%u", irq); - } - } else { - printk(", IRQ disabled"); - } - - dev->irq = irq; - if (master) { /* alloc DMA buffers */ devpriv->dma_doublebuf = 0; for (i = 0; i < 2; i++) { @@ -1984,47 +2003,37 @@ static int pci9118_attach(struct comedi_device *dev, } } if (!devpriv->dmabuf_virt[0]) { - printk(", Can't allocate DMA buffer, DMA disabled!"); + dev_warn(dev->class_dev, + "Can't allocate DMA buffer, DMA disabled!\n"); master = 0; } - if (devpriv->dmabuf_virt[1]) devpriv->dma_doublebuf = 1; - } - devpriv->master = master; - if (devpriv->master) - printk(", bus master"); - else - printk(", no bus master"); - - devpriv->usemux = 0; - if (it->options[2] > 0) { - devpriv->usemux = it->options[2]; - if (devpriv->usemux > 256) - devpriv->usemux = 256; /* max 256 channels! */ - if (it->options[4] > 0) - if (devpriv->usemux > 128) { - devpriv->usemux = 128; - /* max 128 channels with softare S&H! */ - } - printk(", ext. mux %d channels", devpriv->usemux); + + 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 = ext_mux; + } else { + devpriv->usemux = 0; } - devpriv->softsshdelay = it->options[4]; - if (devpriv->softsshdelay < 0) { - /* select sample&hold signal polarity */ - devpriv->softsshdelay = -devpriv->softsshdelay; + 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; } - printk(".\n"); - pci_read_config_word(pcidev, PCI_COMMAND, &u16w); pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */ @@ -2047,12 +2056,7 @@ static int pci9118_attach(struct comedi_device *dev, s->range_table = this_board->rangelist_ai; s->cancel = pci9118_ai_cancel; s->insn_read = pci9118_insn_read_ai; - if (dev->irq) { - s->subdev_flags |= SDF_CMD_READ; - s->do_cmdtest = pci9118_ai_cmdtest; - s->do_cmd = pci9118_ai_cmd; - s->munge = pci9118_ai_munge; - } + s->munge = pci9118_ai_munge; s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; @@ -2088,8 +2092,8 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->i8254_osc_base = 250; /* 250ns=4MHz */ devpriv->ai_maskharderr = 0x10a; /* default measure crash condition */ - if (it->options[5]) /* disable some requested */ - devpriv->ai_maskharderr &= ~it->options[5]; + if (hw_err_mask) /* disable some requested */ + devpriv->ai_maskharderr &= ~hw_err_mask; switch (this_board->ai_maxdata) { case 0xffff: @@ -2099,9 +2103,86 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->ai16bits = 0; break; } + + if (disable_irq) + irq = 0; + else + irq = pcidev->irq; + if (irq > 0) { + if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, + dev->board_name, dev)) { + dev_warn(dev->class_dev, + "unable to allocate IRQ %u, DISABLING IT\n", + irq); + } else { + dev->irq = irq; + /* Enable AI commands */ + s = &dev->subdevices[0]; + s->subdev_flags |= SDF_CMD_READ; + s->do_cmdtest = pci9118_ai_cmdtest; + s->do_cmd = pci9118_ai_cmd; + } + } + + pci9118_report_attach(dev, irq); return 0; } +static int pci9118_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci9118_private *devpriv; + struct pci_dev *pcidev; + int ext_mux, disable_irq, master, softsshdelay, hw_err_mask; + + ext_mux = it->options[2]; + master = ((it->options[3] & 1) == 0); + disable_irq = ((it->options[3] & 2) != 0); + softsshdelay = it->options[4]; + hw_err_mask = it->options[5]; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + pcidev = pci9118_find_pci(dev, it); + if (!pcidev) + return -EIO; + comedi_set_hw_dev(dev, &pcidev->dev); + + return pci9118_common_attach(dev, disable_irq, master, ext_mux, + softsshdelay, hw_err_mask); +} + +static int pci9118_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9118_private *devpriv; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + dev->board_ptr = pci9118_find_boardinfo(pcidev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, + "adl_pci9118: cannot determine board type for pci %s\n", + pci_name(pcidev)); + return -EINVAL; + } + /* + * 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); + /* Don't disable irq, use bus master, no external mux, + * no sample-hold delay, no error mask. */ + return pci9118_common_attach(dev, 0, 1, 0, 0, 0); +} + static void pci9118_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -2127,81 +2208,24 @@ static void pci9118_detach(struct comedi_device *dev) } } -static const struct boardtype boardtypes[] = { - { - .name = "pci9118dg", - .vendor_id = PCI_VENDOR_ID_AMCC, - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118dg_hr, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 3000, - .ai_pacer_min = 12, - .half_fifo_size = 512, - }, { - .name = "pci9118hg", - .vendor_id = PCI_VENDOR_ID_AMCC, - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118hg, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 3000, - .ai_pacer_min = 12, - .half_fifo_size = 512, - }, { - .name = "pci9118hr", - .vendor_id = PCI_VENDOR_ID_AMCC, - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0xffff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118dg_hr, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 10000, - .ai_pacer_min = 40, - .half_fifo_size = 512, - }, -}; - 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(boardtypes), .board_name = &boardtypes[0].name, .offset = sizeof(struct boardtype), }; -static int __devinit adl_pci9118_pci_probe(struct pci_dev *dev, +static int adl_pci9118_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci9118_driver); } -static void __devexit adl_pci9118_pci_remove(struct pci_dev *dev) +static void adl_pci9118_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -2216,7 +2240,7 @@ static struct pci_driver adl_pci9118_pci_driver = { .name = "adl_pci9118", .id_table = adl_pci9118_pci_table, .probe = adl_pci9118_pci_probe, - .remove = __devexit_p(adl_pci9118_pci_remove), + .remove = adl_pci9118_pci_remove, }; module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver); diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 3a2aa56..f7950df 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -116,15 +116,6 @@ static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, { } }; -struct adq12b_board { - const char *name; - int ai_se_chans; - int ai_diff_chans; - int ai_bits; - int di_chans; - int do_chans; -}; - struct adq12b_private { int unipolar; /* option 2 of comedi_config (1 is iobase) */ int differential; /* option 3 of comedi_config */ @@ -220,13 +211,14 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct adq12b_board *board = comedi_board(dev); struct adq12b_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int unipolar, differential; int ret; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; unipolar = it->options[1]; differential = it->options[2]; @@ -251,12 +243,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - dev->board_name = board->name; - - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; devpriv->unipolar = unipolar; devpriv->differential = differential; @@ -277,10 +267,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_AI; if (differential) { s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = board->ai_diff_chans; + s->n_chan = 8; } else { s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = board->ai_se_chans; + s->n_chan = 16; } if (unipolar) @@ -288,7 +278,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) else s->range_table = &range_adq12b_ai_bipolar; - s->maxdata = (1 << board->ai_bits) - 1; + s->maxdata = 0xfff; s->len_chanlist = 4; /* This is the maximum chanlist length that the board can handle */ @@ -298,7 +288,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* digital input subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; - s->n_chan = board->di_chans; + s->n_chan = 5; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = adq12b_di_insn_bits; @@ -307,7 +297,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* digital output subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = board->do_chans; + s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = adq12b_do_insn_bits; @@ -323,25 +313,11 @@ static void adq12b_detach(struct comedi_device *dev) release_region(dev->iobase, ADQ12B_SIZE); } -static const struct adq12b_board adq12b_boards[] = { - { - .name = "adq12b", - .ai_se_chans = 16, - .ai_diff_chans = 8, - .ai_bits = 12, - .di_chans = 5, - .do_chans = 8, - }, -}; - static struct comedi_driver adq12b_driver = { .driver_name = "adq12b", .module = THIS_MODULE, .attach = adq12b_attach, .detach = adq12b_detach, - .board_name = &adq12b_boards[0].name, - .offset = sizeof(struct adq12b_board), - .num_names = ARRAY_SIZE(adq12b_boards), }; module_comedi_driver(adq12b_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index def37bc..a6fd8c2 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -53,8 +53,6 @@ Configuration options: * correct channel number on every 12 bit * sample */ -#define PCI_VENDOR_ID_ADVANTECH 0x13fe - /* hardware types of the cards */ #define TYPE_PCI171X 0 #define TYPE_PCI1713 2 @@ -1068,45 +1066,23 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + this_board->ai_ns_min); + else /* TRIG_FOLLOW */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_ns_min) { - cmd->convert_arg = this_board->ai_ns_min; - err++; - } - } else { /* TRIG_FOLLOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1257,26 +1233,25 @@ static const void *pci1710_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci1710_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int pci1710_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct boardtype *this_board; struct pci1710_private *devpriv; struct comedi_subdevice *s; int ret, subdev, n_subdevices; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = pci1710_find_boardinfo(dev, pcidev); if (!this_board) return -ENODEV; dev->board_ptr = this_board; dev->board_name = this_board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -1417,17 +1392,17 @@ static void pci1710_detach(struct comedi_device *dev) static struct comedi_driver adv_pci1710_driver = { .driver_name = "adv_pci1710", .module = THIS_MODULE, - .attach_pci = pci1710_attach_pci, + .auto_attach = pci1710_auto_attach, .detach = pci1710_detach, }; -static int __devinit adv_pci1710_pci_probe(struct pci_dev *dev, +static int adv_pci1710_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adv_pci1710_driver); } -static void __devexit adv_pci1710_pci_remove(struct pci_dev *dev) +static void adv_pci1710_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1446,7 +1421,7 @@ static struct pci_driver adv_pci1710_pci_driver = { .name = "adv_pci1710", .id_table = adv_pci1710_pci_table, .probe = adv_pci1710_pci_probe, - .remove = __devexit_p(adv_pci1710_pci_remove), + .remove = adv_pci1710_pci_remove, }; module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index df4efc0..5af7314 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -50,8 +50,6 @@ TODO: #include "../comedidev.h" -#define PCI_VENDOR_ID_ADVANTECH 0x13fe /* Advantech PCI vendor ID */ - /* all the registers for the pci1723 board */ #define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */ @@ -234,20 +232,20 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, return insn->n; } -static int pci1723_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int pci1723_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pci1723_private *devpriv; struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -319,17 +317,17 @@ static void pci1723_detach(struct comedi_device *dev) static struct comedi_driver adv_pci1723_driver = { .driver_name = "adv_pci1723", .module = THIS_MODULE, - .attach_pci = pci1723_attach_pci, + .auto_attach = pci1723_auto_attach, .detach = pci1723_detach, }; -static int __devinit adv_pci1723_pci_probe(struct pci_dev *dev, +static int adv_pci1723_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adv_pci1723_driver); } -static void __devexit adv_pci1723_pci_remove(struct pci_dev *dev) +static void adv_pci1723_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -344,7 +342,7 @@ static struct pci_driver adv_pci1723_pci_driver = { .name = "adv_pci1723", .id_table = adv_pci1723_pci_table, .probe = adv_pci1723_pci_probe, - .remove = __devexit_p(adv_pci1723_pci_remove), + .remove = adv_pci1723_pci_remove, }; module_comedi_pci_driver(adv_pci1723_driver, adv_pci1723_pci_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index a3c2241..05a663e 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -36,8 +36,6 @@ Configuration options: #include "8255.h" #include "8253.h" -#define PCI_VENDOR_ID_ADVANTECH 0x13fe - /* hardware types of the cards */ enum hw_cards_id { TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736, @@ -1092,26 +1090,25 @@ static const void *pci_dio_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci_dio_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int pci_dio_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct dio_boardtype *this_board; struct pci_dio_private *devpriv; struct comedi_subdevice *s; int ret, subdev, i, j; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = pci_dio_find_boardinfo(dev, pcidev); if (!this_board) return -ENODEV; dev->board_ptr = this_board; dev->board_name = this_board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -1199,17 +1196,17 @@ static void pci_dio_detach(struct comedi_device *dev) static struct comedi_driver adv_pci_dio_driver = { .driver_name = "adv_pci_dio", .module = THIS_MODULE, - .attach_pci = pci_dio_attach_pci, + .auto_attach = pci_dio_auto_attach, .detach = pci_dio_detach, }; -static int __devinit adv_pci_dio_pci_probe(struct pci_dev *dev, +static int adv_pci_dio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adv_pci_dio_driver); } -static void __devexit adv_pci_dio_pci_remove(struct pci_dev *dev) +static void adv_pci_dio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1237,7 +1234,7 @@ 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 = __devexit_p(adv_pci_dio_pci_remove), + .remove = adv_pci_dio_pci_remove, }; module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver); diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 8acf60d..601f03d 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -212,10 +212,10 @@ static int aio_aio12_8_attach(struct comedi_device *dev, } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index b2cb8b0..64c1ae5 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -44,19 +44,6 @@ Configuration Options: #define AIO_IIRO_16_RELAY_8_15 0x04 #define AIO_IIRO_16_INPUT_8_15 0x05 -struct aio_iiro_16_board { - const char *name; - int do_; - int di; -}; - -static const struct aio_iiro_16_board aio_iiro_16_boards[] = { - { - .name = "aio_iiro_16", - .di = 16, - .do_ = 16}, -}; - static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -90,14 +77,13 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, static int aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct aio_iiro_16_board *board = comedi_board(dev); int iobase; struct comedi_subdevice *s; int ret; printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor); - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; iobase = it->options[0]; @@ -144,9 +130,6 @@ static struct comedi_driver aio_iiro_16_driver = { .module = THIS_MODULE, .attach = aio_iiro_16_attach, .detach = aio_iiro_16_detach, - .board_name = &aio_iiro_16_boards[0].name, - .offset = sizeof(struct aio_iiro_16_board), - .num_names = ARRAY_SIZE(aio_iiro_16_boards), }; module_comedi_driver(aio_iiro_16_driver); diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 29eb52d..5f309ba 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -25,185 +25,238 @@ */ /* -Driver: amplc_dio200 -Description: Amplicon 200 Series Digital I/O -Author: Ian Abbott <abbotti@mev.co.uk> -Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e), - PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e), - PCI272 (pci272 or amplc_dio200) -Updated: Wed, 22 Oct 2008 13:36:02 +0100 -Status: works - -Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E: - [0] - I/O port base address - [1] - IRQ (optional, but commands won't work without it) - -Configuration options - PCI215, PCI272: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first available PCI device will - be used. - -Passing a zero for an option is the same as leaving it unspecified. - -SUBDEVICES - - PC218E PC212E PC215E/PCI215 - ------------- ------------- ------------- - Subdevices 7 6 5 - 0 CTR-X1 PPI-X PPI-X - 1 CTR-X2 CTR-Y1 PPI-Y - 2 CTR-Y1 CTR-Y2 CTR-Z1 - 3 CTR-Y2 CTR-Z1 CTR-Z2 - 4 CTR-Z1 CTR-Z2 INTERRUPT - 5 CTR-Z2 INTERRUPT - 6 INTERRUPT - - PC214E PC272E/PCI272 - ------------- ------------- - Subdevices 4 4 - 0 PPI-X PPI-X - 1 PPI-Y PPI-Y - 2 CTR-Z1* PPI-Z - 3 INTERRUPT* 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 - - PC218E PC212E PC215E/PCI215 - ------------- ------------- ------------- - Sources 6 6 6 - 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0 - 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3 - 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0 - 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3 - 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT - 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT - - PC214E PC272E/PCI272 - ------------- ------------- - Sources 1 6 - 0 JUMPER-J5 PPI-X-C0 - 1 PPI-X-C3 - 2 PPI-Y-C0 - 3 PPI-Y-C3 - 4 PPI-Z-C0 - 5 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. For level-triggered hardware interrupts (PCI -card), the interrupt will remain asserted until the interrupt status -register is cleared to zero. For edge-triggered hardware interrupts -(ISA card), 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. -*/ + * Driver: amplc_dio200 + * Description: Amplicon 200 Series Digital I/O + * Author: Ian Abbott <abbotti@mev.co.uk> + * Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e), + * PCI215 (pci215), PCIe215 (pcie215), PC218E (pc218e), PCIe236 (pcie236), + * PC272E (pc272e), PCI272 (pci272), PCIe296 (pcie296) + * Updated: Wed, 24 Oct 2012 16:22:34 +0100 + * Status: works + * + * Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E: + * [0] - I/O port base address + * [1] - IRQ (optional, but commands won't work without it) + * + * Manual configuration of PCI(e) cards is not supported; they are configured + * automatically. + * + * Passing a zero for an option is the same as leaving it unspecified. + * + * SUBDEVICES + * + * PC212E PC214E PC215E/PCI215 + * ------------- ------------- ------------- + * 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 + * + * PCIe215 PC218E PCIe236 + * ------------- ------------- ------------- + * Subdevices 8 7 8 + * 0 PPI-X CTR-X1 PPI-X + * 1 UNUSED CTR-X2 UNUSED + * 2 PPI-Y CTR-Y1 UNUSED + * 3 UNUSED CTR-Y2 UNUSED + * 4 CTR-Z1 CTR-Z1 CTR-Z1 + * 5 CTR-Z2 CTR-Z2 CTR-Z2 + * 6 TIMER INTERRUPT TIMER + * 7 INTERRUPT INTERRUPT + * + * PC272E/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 + * + * PC212E PC214E PC215E/PCI215 + * ------------- ------------- ------------- + * 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 + * + * PCIe215 PC218E PCIe236 + * ------------- ------------- ------------- + * Sources 6 6 6 + * 0 PPI-X-C0 CTR-X1-OUT1 PPI-X-C0 + * 1 PPI-X-C3 CTR-X2-OUT1 PPI-X-C3 + * 2 PPI-Y-C0 CTR-Y1-OUT1 unused + * 3 PPI-Y-C3 CTR-Y2-OUT1 unused + * 4 CTR-Z1-OUT1 CTR-Z1-OUT1 CTR-Z1-OUT1 + * 5 CTR-Z2-OUT1 CTR-Z2-OUT1 CTR-Z2-OUT1 + * + * PC272E/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. For level-triggered hardware interrupts (PCI + * card), the interrupt will remain asserted until the interrupt status + * register is cleared to zero. For edge-triggered hardware interrupts + * (ISA card), 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/interrupt.h> #include <linux/slab.h> @@ -211,7 +264,6 @@ order they appear in the channel list. #include "../comedidev.h" #include "comedi_fc.h" -#include "8255.h" #include "8253.h" #define DIO200_DRIVER_NAME "amplc_dio200" @@ -220,13 +272,24 @@ order they appear in the channel list. #define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) /* PCI IDs */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b -#define PCI_DEVICE_ID_INVALID 0xffff +#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011 +#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012 +#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014 + +/* 8255 control register bits */ +#define CR_C_LO_IO 0x01 +#define CR_B_IO 0x02 +#define CR_B_MODE 0x04 +#define CR_C_HI_IO 0x08 +#define CR_A_IO 0x10 +#define CR_A_MODE(a) ((a)<<5) +#define CR_CW 0x80 /* 200 series registers */ #define DIO200_IO_SIZE 0x20 +#define DIO200_PCIE_IO_SIZE 0x4000 #define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */ #define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */ #define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */ @@ -234,30 +297,78 @@ order they appear in the channel list. #define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */ #define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */ #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 */ /* - * Macros for constructing value for DIO_200_?CLK_SCE and + * 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. + * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards. */ -#define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source)) -#define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source)) +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); +} + +static unsigned char clk_sce(unsigned int which, unsigned int chan, + unsigned int source) +{ + return clk_gat_sce(which, chan, source); +} + +static unsigned char gat_sce(unsigned int which, unsigned int chan, + unsigned int source) +{ + return clk_gat_sce(which, chan, source); +} /* * Periods of the internal clock sources in nanoseconds. */ -static const unsigned clock_period[8] = { - 0, /* dedicated clock input/output pin */ - 100, /* 10 MHz */ - 1000, /* 1 MHz */ - 10000, /* 100 kHz */ - 100000, /* 10 kHz */ - 1000000, /* 1 kHz */ - 0, /* OUT N-1 */ - 0 /* group clock input pin */ +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. */ +}; + +/* + * Register region. + */ +enum dio200_regtype { no_regtype = 0, io_regtype, mmio_regtype }; +struct dio200_region { + union { + unsigned long iobase; /* I/O base address */ + unsigned char __iomem *membase; /* mapped MMIO base address */ + } u; + enum dio200_regtype regtype; }; /* @@ -269,13 +380,14 @@ enum dio200_bustype { isa_bustype, pci_bustype }; enum dio200_model { pc212e_model, pc214e_model, - pc215e_model, pci215_model, + pc215e_model, pci215_model, pcie215_model, pc218e_model, + pcie236_model, pc272e_model, pci272_model, - anypci_model + pcie296_model, }; -enum dio200_layout { +enum dio200_layout_idx { #if DO_ISA pc212_layout, pc214_layout, @@ -284,7 +396,12 @@ enum dio200_layout { #if DO_ISA pc218_layout, #endif - pc272_layout + pc272_layout, +#if DO_PCI + pcie215_layout, + pcie236_layout, + pcie296_layout, +#endif }; struct dio200_board { @@ -292,7 +409,10 @@ struct dio200_board { unsigned short devid; enum dio200_bustype bustype; enum dio200_model model; - enum dio200_layout layout; + enum dio200_layout_idx layout; + unsigned char mainbar; + unsigned char mainshift; + unsigned int mainsize; }; static const struct dio200_board dio200_boards[] = { @@ -302,30 +422,35 @@ static const struct dio200_board dio200_boards[] = { .bustype = isa_bustype, .model = pc212e_model, .layout = pc212_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc214e", .bustype = isa_bustype, .model = pc214e_model, .layout = pc214_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc215e", .bustype = isa_bustype, .model = pc215e_model, .layout = pc215_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc218e", .bustype = isa_bustype, .model = pc218e_model, .layout = pc218_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc272e", .bustype = isa_bustype, .model = pc272e_model, .layout = pc272_layout, + .mainsize = DIO200_IO_SIZE, }, #endif #if DO_PCI @@ -335,6 +460,8 @@ static const struct dio200_board dio200_boards[] = { .bustype = pci_bustype, .model = pci215_model, .layout = pc215_layout, + .mainbar = 2, + .mainsize = DIO200_IO_SIZE, }, { .name = "pci272", @@ -342,12 +469,38 @@ static const struct dio200_board dio200_boards[] = { .bustype = pci_bustype, .model = pci272_model, .layout = pc272_layout, + .mainbar = 2, + .mainsize = DIO200_IO_SIZE, + }, + { + .name = "pcie215", + .devid = PCI_DEVICE_ID_AMPLICON_PCIE215, + .bustype = pci_bustype, + .model = pcie215_model, + .layout = pcie215_layout, + .mainbar = 1, + .mainshift = 3, + .mainsize = DIO200_PCIE_IO_SIZE, }, { - .name = DIO200_DRIVER_NAME, - .devid = PCI_DEVICE_ID_INVALID, + .name = "pcie236", + .devid = PCI_DEVICE_ID_AMPLICON_PCIE236, .bustype = pci_bustype, - .model = anypci_model, /* wildcard */ + .model = pcie236_model, + .layout = pcie236_layout, + .mainbar = 1, + .mainshift = 3, + .mainsize = DIO200_PCIE_IO_SIZE, + }, + { + .name = "pcie296", + .devid = PCI_DEVICE_ID_AMPLICON_PCIE296, + .bustype = pci_bustype, + .model = pcie296_model, + .layout = pcie296_layout, + .mainbar = 1, + .mainshift = 3, + .mainsize = DIO200_PCIE_IO_SIZE, }, #endif }; @@ -357,20 +510,21 @@ static const struct dio200_board dio200_boards[] = { * layout. */ -enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 }; +enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer }; -#define DIO200_MAX_SUBDEVS 7 +#define DIO200_MAX_SUBDEVS 8 #define DIO200_MAX_ISNS 6 -struct dio200_layout_struct { +struct dio200_layout { 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 */ char has_int_sce; /* has interrupt enable/status register */ char has_clk_gat_sce; /* has clock/gate selection registers */ + char has_enhancements; /* has enhanced features */ }; -static const struct dio200_layout_struct dio200_layouts[] = { +static const struct dio200_layout dio200_layouts[] = { #if DO_ISA [pc212_layout] = { .n_subdevs = 6, @@ -421,6 +575,38 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 0, }, +#if DO_PCI + [pcie215_layout] = { + .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 = 1, + .has_clk_gat_sce = 1, + .has_enhancements = 1, + }, + [pcie236_layout] = { + .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 = 1, + .has_clk_gat_sce = 1, + .has_enhancements = 1, + }, + [pcie296_layout] = { + .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 = 1, + .has_clk_gat_sce = 1, + .has_enhancements = 1, + }, +#endif }; /* this structure is for data unique to this hardware driver. If @@ -428,31 +614,46 @@ static const struct dio200_layout_struct dio200_layouts[] = { feel free to suggest moving the variable to the struct comedi_device struct. */ struct dio200_private { + struct dio200_region io; /* Register region */ int intr_sd; }; struct dio200_subdev_8254 { - unsigned long iobase; /* Counter base address */ - unsigned long clk_sce_iobase; /* CLK_SCE base address */ - unsigned long gat_sce_iobase; /* GAT_SCE base address */ - int which; /* Bit 5 of CLK_SCE or GAT_SCE */ - int has_clk_gat_sce; - unsigned clock_src[3]; /* Current clock sources */ - unsigned gate_src[3]; /* Current gate sources */ + unsigned int ofs; /* Counter base offset */ + unsigned int clk_sce_ofs; /* CLK_SCE base address */ + unsigned int gat_sce_ofs; /* GAT_SCE base address */ + int which; /* Bit 5 of CLK_SCE or GAT_SCE */ + unsigned int clock_src[3]; /* Current clock sources */ + unsigned int gate_src[3]; /* Current gate sources */ spinlock_t spinlock; }; +struct dio200_subdev_8255 { + unsigned int ofs; /* DIO base offset */ +}; + struct dio200_subdev_intr { - unsigned long iobase; + unsigned int ofs; spinlock_t spinlock; int active; - int has_int_sce; unsigned int valid_isns; unsigned int enabled_isns; unsigned int stopcount; int continuous; }; +static inline const struct dio200_layout * +dio200_board_layout(const struct dio200_board *board) +{ + return &dio200_layouts[board->layout]; +} + +static inline const struct dio200_layout * +dio200_dev_layout(struct comedi_device *dev) +{ + return dio200_board_layout(comedi_board(dev)); +} + static inline bool is_pci_board(const struct dio200_board *board) { return DO_PCI && board->bustype == pci_bustype; @@ -464,6 +665,70 @@ static inline bool is_isa_board(const struct dio200_board *board) } /* + * Read 8-bit register. + */ +static unsigned char dio200_read8(struct comedi_device *dev, + unsigned int offset) +{ + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; + + offset <<= thisboard->mainshift; + if (devpriv->io.regtype == io_regtype) + return inb(devpriv->io.u.iobase + offset); + else + return readb(devpriv->io.u.membase + offset); +} + +/* + * Write 8-bit register. + */ +static void dio200_write8(struct comedi_device *dev, unsigned int offset, + unsigned char val) +{ + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; + + offset <<= thisboard->mainshift; + if (devpriv->io.regtype == io_regtype) + outb(val, devpriv->io.u.iobase + offset); + else + writeb(val, devpriv->io.u.membase + offset); +} + +/* + * Read 32-bit register. + */ +static unsigned int dio200_read32(struct comedi_device *dev, + unsigned int offset) +{ + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; + + offset <<= thisboard->mainshift; + if (devpriv->io.regtype == io_regtype) + return inl(devpriv->io.u.iobase + offset); + else + return readl(devpriv->io.u.membase + offset); +} + +/* + * Write 32-bit register. + */ +static void dio200_write32(struct comedi_device *dev, unsigned int offset, + unsigned int val) +{ + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; + + offset <<= thisboard->mainshift; + if (devpriv->io.regtype == io_regtype) + outl(val, devpriv->io.u.iobase + offset); + else + writel(val, devpriv->io.u.membase + offset); +} + +/* * This function looks for a board matching the supplied PCI device. */ static const struct dio200_board * @@ -479,49 +744,6 @@ dio200_find_pci_board(struct pci_dev *pci_dev) } /* - * This function looks for a PCI device matching the requested board name, - * bus and slot. - */ -static struct pci_dev *dio200_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - const struct dio200_board *thisboard = comedi_board(dev); - struct pci_dev *pci_dev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pci_dev) { - if (bus || slot) { - if (bus != pci_dev->bus->number || - slot != PCI_SLOT(pci_dev->devfn)) - continue; - } - if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON) - continue; - - if (thisboard->model == anypci_model) { - /* Wildcard board matches any supported PCI board. */ - const struct dio200_board *foundboard; - - foundboard = dio200_find_pci_board(pci_dev); - if (foundboard == NULL) - continue; - /* Replace wildcard board_ptr. */ - dev->board_ptr = foundboard; - } else { - /* Match specific model name. */ - if (pci_dev->device != thisboard->devid) - continue; - } - return pci_dev; - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - -/* * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ @@ -545,11 +767,12 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; - if (subpriv->has_int_sce) { + if (layout->has_int_sce) { /* Just read the interrupt status register. */ - data[1] = inb(subpriv->iobase) & subpriv->valid_isns; + data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns; } else { /* No interrupt status register. */ data[0] = 0; @@ -564,12 +787,13 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; subpriv->active = 0; subpriv->enabled_isns = 0; - if (subpriv->has_int_sce) - outb(0, subpriv->iobase); + if (layout->has_int_sce) + dio200_write8(dev, subpriv->ofs, 0); } /* @@ -580,6 +804,7 @@ static int dio200_start_intr(struct comedi_device *dev, { unsigned int n; unsigned isn_bits; + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; struct comedi_cmd *cmd = &s->async->cmd; int retval = 0; @@ -599,8 +824,8 @@ static int dio200_start_intr(struct comedi_device *dev, isn_bits &= subpriv->valid_isns; /* Enable interrupt sources. */ subpriv->enabled_isns = isn_bits; - if (subpriv->has_int_sce) - outb(isn_bits, subpriv->iobase); + if (layout->has_int_sce) + dio200_write8(dev, subpriv->ofs, isn_bits); } return retval; @@ -642,6 +867,7 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; unsigned triggered; unsigned intstat; @@ -653,7 +879,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, spin_lock_irqsave(&subpriv->spinlock, flags); oldevents = s->async->events; - if (subpriv->has_int_sce) { + if (layout->has_int_sce) { /* * Collect interrupt sources that have triggered and disable * them temporarily. Loop around until no extra interrupt @@ -665,11 +891,11 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * loop in case of misconfiguration. */ cur_enabled = subpriv->enabled_isns; - while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns - & ~triggered)) != 0) { + while ((intstat = (dio200_read8(dev, subpriv->ofs) & + subpriv->valid_isns & ~triggered)) != 0) { triggered |= intstat; cur_enabled &= ~triggered; - outb(cur_enabled, subpriv->iobase); + dio200_write8(dev, subpriv->ofs, cur_enabled); } } else { /* @@ -687,8 +913,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * Reenable them NOW to minimize the time they are disabled. */ cur_enabled = subpriv->enabled_isns; - if (subpriv->has_int_sce) - outb(cur_enabled, subpriv->iobase); + if (layout->has_int_sce) + dio200_write8(dev, subpriv->ofs, cur_enabled); if (subpriv->active) { /* @@ -794,41 +1020,19 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - - /* cmd->scan_begin_src == TRIG_EXT */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - - /* cmd->convert_src == TRIG_NOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - /* cmd->scan_end_src == TRIG_COUNT */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: /* any count allowed */ break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; @@ -894,9 +1098,9 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, */ static int dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned long iobase, unsigned valid_isns, - int has_int_sce) + unsigned int offset, unsigned valid_isns) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv; subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); @@ -904,18 +1108,18 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, dev_err(dev->class_dev, "error! out of memory!\n"); return -ENOMEM; } - subpriv->iobase = iobase; - subpriv->has_int_sce = has_int_sce; + subpriv->ofs = offset; subpriv->valid_isns = valid_isns; spin_lock_init(&subpriv->spinlock); - if (has_int_sce) - outb(0, subpriv->iobase); /* Disable interrupt sources. */ + if (layout->has_int_sce) + /* Disable interrupt sources. */ + dio200_write8(dev, subpriv->ofs, 0); s->private = subpriv; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; - if (has_int_sce) { + if (layout->has_int_sce) { s->n_chan = DIO200_MAX_ISNS; s->len_chanlist = DIO200_MAX_ISNS; } else { @@ -968,6 +1172,73 @@ static irqreturn_t dio200_interrupt(int irq, void *d) } /* + * Read an '8254' counter subdevice channel. + */ +static unsigned int +dio200_subdev_8254_read_chan(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan) +{ + struct dio200_subdev_8254 *subpriv = s->private; + unsigned int val; + + /* latch counter */ + val = chan << 6; + dio200_write8(dev, subpriv->ofs + i8254_control_reg, val); + /* read lsb, msb */ + val = dio200_read8(dev, subpriv->ofs + chan); + val += dio200_read8(dev, subpriv->ofs + chan) << 8; + return val; +} + +/* + * Write an '8254' subdevice channel. + */ +static void +dio200_subdev_8254_write_chan(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan, + unsigned int count) +{ + struct dio200_subdev_8254 *subpriv = s->private; + + /* write lsb, msb */ + dio200_write8(dev, subpriv->ofs + chan, count & 0xff); + dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff); +} + +/* + * Set mode of an '8254' subdevice channel. + */ +static void +dio200_subdev_8254_set_mode(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan, + unsigned int mode) +{ + struct dio200_subdev_8254 *subpriv = s->private; + unsigned int byte; + + byte = chan << 6; + byte |= 0x30; /* access order: lsb, msb */ + byte |= (mode & 0xf); /* counter mode and BCD|binary */ + dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte); +} + +/* + * Read status byte of an '8254' counter subdevice channel. + */ +static unsigned int +dio200_subdev_8254_status(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan) +{ + struct dio200_subdev_8254 *subpriv = s->private; + + /* latch status */ + dio200_write8(dev, subpriv->ofs + i8254_control_reg, + 0xe0 | (2 << chan)); + /* read status */ + return dio200_read8(dev, subpriv->ofs + chan); +} + +/* * Handle 'insn_read' for an '8254' counter subdevice. */ static int @@ -976,13 +1247,15 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s, { struct dio200_subdev_8254 *subpriv = s->private; int chan = CR_CHAN(insn->chanspec); + unsigned int n; unsigned long flags; - spin_lock_irqsave(&subpriv->spinlock, flags); - data[0] = i8254_read(subpriv->iobase, 0, chan); - spin_unlock_irqrestore(&subpriv->spinlock, flags); - - return 1; + for (n = 0; n < insn->n; n++) { + spin_lock_irqsave(&subpriv->spinlock, flags); + data[n] = dio200_subdev_8254_read_chan(dev, s, chan); + spin_unlock_irqrestore(&subpriv->spinlock, flags); + } + return insn->n; } /* @@ -994,34 +1267,40 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, { struct dio200_subdev_8254 *subpriv = s->private; int chan = CR_CHAN(insn->chanspec); + unsigned int n; unsigned long flags; - spin_lock_irqsave(&subpriv->spinlock, flags); - i8254_write(subpriv->iobase, 0, chan, data[0]); - spin_unlock_irqrestore(&subpriv->spinlock, flags); - - return 1; + for (n = 0; n < insn->n; n++) { + spin_lock_irqsave(&subpriv->spinlock, flags); + dio200_subdev_8254_write_chan(dev, s, chan, data[n]); + spin_unlock_irqrestore(&subpriv->spinlock, flags); + } + return insn->n; } /* * Set gate source for an '8254' counter subdevice channel. */ static int -dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number, unsigned int gate_src) +dio200_subdev_8254_set_gate_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int gate_src) { + const struct dio200_layout *layout = dio200_dev_layout(dev); + struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; - if (!subpriv->has_clk_gat_sce) + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; - if (gate_src > 7) + if (gate_src > (layout->has_enhancements ? 31 : 7)) return -1; subpriv->gate_src[counter_number] = gate_src; - byte = GAT_SCE(subpriv->which, counter_number, gate_src); - outb(byte, subpriv->gat_sce_iobase); + byte = gat_sce(subpriv->which, counter_number, gate_src); + dio200_write8(dev, subpriv->gat_sce_ofs, byte); return 0; } @@ -1030,10 +1309,14 @@ dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, * Get gate source for an '8254' counter subdevice channel. */ static int -dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number) +dio200_subdev_8254_get_gate_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number) { - if (!subpriv->has_clk_gat_sce) + const struct dio200_layout *layout = dio200_dev_layout(dev); + struct dio200_subdev_8254 *subpriv = s->private; + + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -1045,21 +1328,25 @@ dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, * Set clock source for an '8254' counter subdevice channel. */ static int -dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number, unsigned int clock_src) +dio200_subdev_8254_set_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int clock_src) { + const struct dio200_layout *layout = dio200_dev_layout(dev); + struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; - if (!subpriv->has_clk_gat_sce) + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; - if (clock_src > 7) + if (clock_src > (layout->has_enhancements ? 31 : 7)) return -1; subpriv->clock_src[counter_number] = clock_src; - byte = CLK_SCE(subpriv->which, counter_number, clock_src); - outb(byte, subpriv->clk_sce_iobase); + byte = clk_sce(subpriv->which, counter_number, clock_src); + dio200_write8(dev, subpriv->clk_sce_ofs, byte); return 0; } @@ -1068,12 +1355,16 @@ dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, * Get clock source for an '8254' counter subdevice channel. */ static int -dio200_get_clock_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number, unsigned int *period_ns) +dio200_subdev_8254_get_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int *period_ns) { + const struct dio200_layout *layout = dio200_dev_layout(dev); + struct dio200_subdev_8254 *subpriv = s->private; unsigned clock_src; - if (!subpriv->has_clk_gat_sce) + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -1098,20 +1389,21 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_irqsave(&subpriv->spinlock, flags); switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: - ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]); - if (ret < 0) + if (data[1] > (I8254_MODE5 | I8254_BINARY)) ret = -EINVAL; + else + dio200_subdev_8254_set_mode(dev, s, chan, data[1]); break; case INSN_CONFIG_8254_READ_STATUS: - data[1] = i8254_status(subpriv->iobase, 0, chan); + data[1] = dio200_subdev_8254_status(dev, s, chan); break; case INSN_CONFIG_SET_GATE_SRC: - ret = dio200_set_gate_src(subpriv, chan, data[2]); + ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]); if (ret < 0) ret = -EINVAL; break; case INSN_CONFIG_GET_GATE_SRC: - ret = dio200_get_gate_src(subpriv, chan); + ret = dio200_subdev_8254_get_gate_src(dev, s, chan); if (ret < 0) { ret = -EINVAL; break; @@ -1119,12 +1411,12 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, data[2] = ret; break; case INSN_CONFIG_SET_CLOCK_SRC: - ret = dio200_set_clock_src(subpriv, chan, data[1]); + ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]); if (ret < 0) ret = -EINVAL; break; case INSN_CONFIG_GET_CLOCK_SRC: - ret = dio200_get_clock_src(subpriv, chan, &data[2]); + ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]); if (ret < 0) { ret = -EINVAL; break; @@ -1141,15 +1433,12 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, /* * This function initializes an '8254' counter subdevice. - * - * Note: iobase is the base address of the board, not the subdevice; - * offset is the offset to the 8254 chip. */ static int dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned long iobase, unsigned offset, - int has_clk_gat_sce) + unsigned int offset) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_8254 *subpriv; unsigned int chan; @@ -1169,27 +1458,24 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, s->insn_config = dio200_subdev_8254_config; spin_lock_init(&subpriv->spinlock); - subpriv->iobase = offset + iobase; - subpriv->has_clk_gat_sce = has_clk_gat_sce; - if (has_clk_gat_sce) { + subpriv->ofs = offset; + if (layout->has_clk_gat_sce) { /* Derive CLK_SCE and GAT_SCE register offsets from * 8254 offset. */ - subpriv->clk_sce_iobase = - DIO200_XCLK_SCE + (offset >> 3) + iobase; - subpriv->gat_sce_iobase = - DIO200_XGAT_SCE + (offset >> 3) + iobase; + subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3); + subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3); subpriv->which = (offset >> 2) & 1; } /* Initialize channels. */ for (chan = 0; chan < 3; chan++) { - i8254_set_mode(subpriv->iobase, 0, chan, - I8254_MODE0 | I8254_BINARY); - if (subpriv->has_clk_gat_sce) { + dio200_subdev_8254_set_mode(dev, s, chan, + I8254_MODE0 | I8254_BINARY); + if (layout->has_clk_gat_sce) { /* Gate source 0 is VCC (logic 1). */ - dio200_set_gate_src(subpriv, chan, 0); + dio200_subdev_8254_set_gate_src(dev, s, chan, 0); /* Clock source 0 is the dedicated clock input. */ - dio200_set_clock_src(subpriv, chan, 0); + dio200_subdev_8254_set_clock_src(dev, s, chan, 0); } } @@ -1207,16 +1493,294 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev, kfree(subpriv); } +/* + * This function sets I/O directions for an '8255' DIO subdevice. + */ +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 = CR_CW; + /* 1 in io_bits indicates output, 1 in config indicates input */ + if (!(s->io_bits & 0x0000ff)) + config |= CR_A_IO; + if (!(s->io_bits & 0x00ff00)) + config |= CR_B_IO; + if (!(s->io_bits & 0x0f0000)) + config |= CR_C_LO_IO; + if (!(s->io_bits & 0xf00000)) + config |= CR_C_HI_IO; + dio200_write8(dev, subpriv->ofs + 3, config); +} + +/* + * Handle 'insn_bits' for an '8255' DIO subdevice. + */ +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; + + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + if (data[0] & 0xff) + dio200_write8(dev, subpriv->ofs, s->state & 0xff); + if (data[0] & 0xff00) + dio200_write8(dev, subpriv->ofs + 1, + (s->state >> 8) & 0xff); + if (data[0] & 0xff0000) + dio200_write8(dev, subpriv->ofs + 2, + (s->state >> 16) & 0xff); + } + data[1] = dio200_read8(dev, subpriv->ofs); + data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8; + data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16; + return 2; +} + +/* + * Handle 'insn_config' for an '8255' DIO subdevice. + */ +static int dio200_subdev_8255_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int mask; + unsigned int bits; + + mask = 1 << CR_CHAN(insn->chanspec); + if (mask & 0x0000ff) + bits = 0x0000ff; + else if (mask & 0x00ff00) + bits = 0x00ff00; + else if (mask & 0x0f0000) + bits = 0x0f0000; + else + bits = 0xf00000; + switch (data[0]) { + case INSN_CONFIG_DIO_INPUT: + s->io_bits &= ~bits; + break; + case INSN_CONFIG_DIO_OUTPUT: + s->io_bits |= bits; + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT; + return insn->n; + break; + default: + return -EINVAL; + } + dio200_subdev_8255_set_dir(dev, s); + return 1; +} + +/* + * This function initializes an '8255' DIO subdevice. + * + * offset is the offset to the 8255 chip. + */ +static int dio200_subdev_8255_init(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int offset) +{ + struct dio200_subdev_8255 *subpriv; + + subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); + if (!subpriv) + return -ENOMEM; + subpriv->ofs = offset; + s->private = subpriv; + 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; + s->state = 0; + s->io_bits = 0; + dio200_subdev_8255_set_dir(dev, s); + return 0; +} + +/* + * This function cleans up an '8255' DIO subdevice. + */ +static void dio200_subdev_8255_cleanup(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct dio200_subdev_8255 *subpriv = s->private; + + kfree(subpriv); +} + +/* + * Handle 'insn_read' for a timer subdevice. + */ +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; +} + +/* + * Reset timer subdevice. + */ +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); +} + +/* + * Get timer subdevice clock source and period. + */ +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; +} + +/* + * Set timer subdevice clock source. + */ +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; +} + +/* + * Handle 'insn_config' for a timer subdevice. + */ +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; +} + +/* + * This function initializes a timer subdevice. + * + * Uses the timestamp timer registers. There is only one timestamp timer. + */ +static int dio200_subdev_timer_init(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + 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; + return 0; +} + +/* + * This function cleans up a timer subdevice. + */ +static void dio200_subdev_timer_cleanup(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + /* Nothing to do. */ +} + +/* + * 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; + resource_size_t brlen; + + /* + * 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. + */ + brlen = pci_resource_len(pcidev, 0); + if (brlen < 0x4000 || + !(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) { + dev_err(dev->class_dev, "error! bad PCI region!\n"); + return -EINVAL; + } + brbase = ioremap_nocache(pci_resource_start(pcidev, 0), brlen); + 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. */ + dio200_write8(dev, DIO200_ENHANCE, 1); + return 0; +} + static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) { const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); char tmpbuf[60]; int tmplen; if (is_isa_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), - "(base %#lx) ", dev->iobase); + "(base %#lx) ", devpriv->io.u.iobase); else if (is_pci_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", pci_name(pcidev)); @@ -1232,20 +1796,18 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf); } -static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, - unsigned int irq, unsigned long req_irq_flags) +static int dio200_common_attach(struct comedi_device *dev, unsigned int irq, + unsigned long req_irq_flags) { const struct dio200_board *thisboard = comedi_board(dev); struct dio200_private *devpriv = dev->private; - const struct dio200_layout_struct *layout = - &dio200_layouts[thisboard->layout]; + const struct dio200_layout *layout = dio200_board_layout(thisboard); struct comedi_subdevice *s; int sdx; unsigned int n; int ret; devpriv->intr_sd = -1; - dev->iobase = iobase; dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, layout->n_subdevs); @@ -1257,16 +1819,15 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, switch (layout->sdtype[n]) { case sd_8254: /* counter subdevice (8254) */ - ret = dio200_subdev_8254_init(dev, s, iobase, - layout->sdinfo[n], - layout->has_clk_gat_sce); + ret = dio200_subdev_8254_init(dev, s, + layout->sdinfo[n]); if (ret < 0) return ret; break; case sd_8255: /* digital i/o subdevice (8255) */ - ret = subdev_8255_init(dev, s, NULL, - iobase + layout->sdinfo[n]); + ret = dio200_subdev_8255_init(dev, s, + layout->sdinfo[n]); if (ret < 0) return ret; break; @@ -1274,11 +1835,9 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, /* 'INTERRUPT' subdevice */ if (irq) { ret = dio200_subdev_intr_init(dev, s, - iobase + DIO200_INT_SCE, - layout->sdinfo[n], - layout-> - has_int_sce); + layout->sdinfo[n] + ); if (ret < 0) return ret; devpriv->intr_sd = n; @@ -1286,6 +1845,16 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, s->type = COMEDI_SUBD_UNUSED; } break; + case sd_timer: + /* Only on PCIe boards. */ + if (DO_PCI) { + ret = dio200_subdev_timer_init(dev, s); + if (ret < 0) + return ret; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + break; default: s->type = COMEDI_SUBD_UNUSED; break; @@ -1307,24 +1876,6 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, return 1; } -static int dio200_pci_common_attach(struct comedi_device *dev, - struct pci_dev *pci_dev) -{ - unsigned long iobase; - int ret; - - comedi_set_hw_dev(dev, &pci_dev->dev); - - ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); - return ret; - } - iobase = pci_resource_start(pci_dev, 2); - return dio200_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); -} - /* * Attach is called by the Comedi core to configure the driver * for a particular board. If you specified a board_name array @@ -1334,15 +1885,15 @@ static int dio200_pci_common_attach(struct comedi_device *dev, static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv; int ret; dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct dio200_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* Process options and reserve resources according to bus type. */ if (is_isa_board(thisboard)) { @@ -1351,17 +1902,17 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = it->options[0]; irq = it->options[1]; - ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE); + ret = dio200_request_region(dev, iobase, thisboard->mainsize); if (ret < 0) return ret; - return dio200_common_attach(dev, iobase, irq, 0); + devpriv->io.u.iobase = iobase; + devpriv->io.regtype = io_regtype; + return dio200_common_attach(dev, irq, 0); } else if (is_pci_board(thisboard)) { - struct pci_dev *pci_dev; - - pci_dev = dio200_find_pci_dev(dev, it); - if (!pci_dev) - return -EIO; - return dio200_pci_common_attach(dev, pci_dev); + dev_err(dev->class_dev, + "Manual configuration of PCI board '%s' is not supported\n", + thisboard->name); + return -EIO; } else { dev_err(dev->class_dev, DIO200_DRIVER_NAME ": BUG! cannot determine board type!\n"); @@ -1370,13 +1921,18 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* - * The attach_pci hook (if non-NULL) is called at PCI probe time in preference - * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should - * be a board entry matching the supplied PCI device. + * The auto_attach hook is called at PCI probe time via + * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. + * There should be a board entry matching the supplied PCI device. */ -static int __devinit dio200_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int dio200_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); + const struct dio200_board *thisboard; + struct dio200_private *devpriv; + resource_size_t base, len; + unsigned int bar; int ret; if (!DO_PCI) @@ -1384,38 +1940,71 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(struct dio200_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + dev->board_ptr = dio200_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } - /* - * Need to 'get' the PCI device to match the 'put' in dio200_detach(). - * TODO: Remove the pci_dev_get() and matching pci_dev_put() once - * support for manual attachment of PCI devices via dio200_attach() - * has been removed. - */ - pci_dev_get(pci_dev); - return dio200_pci_common_attach(dev, pci_dev); + thisboard = comedi_board(dev); + ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); + if (ret < 0) { + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); + return ret; + } + bar = thisboard->mainbar; + base = pci_resource_start(pci_dev, bar); + len = pci_resource_len(pci_dev, bar); + if (len < thisboard->mainsize) { + dev_err(dev->class_dev, "error! PCI region size too small!\n"); + return -EINVAL; + } + if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) { + devpriv->io.u.membase = ioremap_nocache(base, len); + if (!devpriv->io.u.membase) { + dev_err(dev->class_dev, + "error! cannot remap registers\n"); + return -ENOMEM; + } + devpriv->io.regtype = mmio_regtype; + } else { + devpriv->io.u.iobase = (unsigned long)base; + devpriv->io.regtype = io_regtype; + } + switch (thisboard->model) + { + case pcie215_model: + case pcie236_model: + case pcie296_model: + ret = dio200_pcie_board_setup(dev); + if (ret < 0) + return ret; + break; + default: + break; + } + return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED); } static void dio200_detach(struct comedi_device *dev) { const struct dio200_board *thisboard = comedi_board(dev); - const struct dio200_layout_struct *layout; + struct dio200_private *devpriv = dev->private; + const struct dio200_layout *layout; unsigned n; - if (!thisboard) + if (!thisboard || !devpriv) return; if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) { - layout = &dio200_layouts[thisboard->layout]; + layout = dio200_board_layout(thisboard); for (n = 0; n < dev->n_subdevices; n++) { struct comedi_subdevice *s = &dev->subdevices[n]; switch (layout->sdtype[n]) { @@ -1423,25 +2012,33 @@ static void dio200_detach(struct comedi_device *dev) dio200_subdev_8254_cleanup(dev, s); break; case sd_8255: - subdev_8255_cleanup(dev, s); + dio200_subdev_8255_cleanup(dev, s); break; case sd_intr: dio200_subdev_intr_cleanup(dev, s); break; + case sd_timer: + /* Only on PCIe boards. */ + if (DO_PCI) + dio200_subdev_timer_cleanup(dev, s); + break; default: break; } } } if (is_isa_board(thisboard)) { - if (dev->iobase) - release_region(dev->iobase, DIO200_IO_SIZE); + if (devpriv->io.regtype == io_regtype) + release_region(devpriv->io.u.iobase, + thisboard->mainsize); } else if (is_pci_board(thisboard)) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (pcidev) { - if (dev->iobase) + if (devpriv->io.regtype != no_regtype) { + if (devpriv->io.regtype == mmio_regtype) + iounmap(devpriv->io.u.membase); comedi_pci_disable(pcidev); - pci_dev_put(pcidev); + } } } } @@ -1456,7 +2053,7 @@ static struct comedi_driver amplc_dio200_driver = { .driver_name = DIO200_DRIVER_NAME, .module = THIS_MODULE, .attach = dio200_attach, - .attach_pci = dio200_attach_pci, + .auto_attach = dio200_auto_attach, .detach = dio200_detach, .board_name = &dio200_boards[0].name, .offset = sizeof(struct dio200_board), @@ -1467,19 +2064,22 @@ static struct comedi_driver amplc_dio200_driver = { static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296) }, {0} }; MODULE_DEVICE_TABLE(pci, dio200_pci_table); -static int __devinit amplc_dio200_pci_probe(struct pci_dev *dev, +static int amplc_dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &lc_dio200_driver); } -static void __devexit amplc_dio200_pci_remove(struct pci_dev *dev) +static void amplc_dio200_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1488,7 +2088,7 @@ static struct pci_driver amplc_dio200_pci_driver = { .name = DIO200_DRIVER_NAME, .id_table = dio200_pci_table, .probe = &lc_dio200_pci_probe, - .remove = __devexit_p(&lc_dio200_pci_remove) + .remove = &lc_dio200_pci_remove }; module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver); #else diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 4e4f3c1..2898354 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -66,7 +66,6 @@ unused. #define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) /* PCI236 PCI configuration register information */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009 #define PCI_DEVICE_ID_INVALID 0xffff @@ -332,28 +331,13 @@ static int pc236_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: */ + /* Step 3: check it arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -505,14 +489,16 @@ static int pc236_pci_common_attach(struct comedi_device *dev, static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pc236_board *thisboard = comedi_board(dev); + struct pc236_private *devpriv; int ret; dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct pc236_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + /* Process options according to bus type. */ if (is_isa_board(thisboard)) { unsigned long iobase = it->options[0]; @@ -536,25 +522,27 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* - * The attach_pci hook (if non-NULL) is called at PCI probe time in preference - * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should - * be a board entry matching the supplied PCI device. + * The auto_attach hook is called at PCI probe time via + * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. + * There should be a board entry matching the supplied PCI device. */ -static int __devinit pc236_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int pc236_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { - int ret; + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); + struct pc236_private *devpriv; if (!DO_PCI) return -EINVAL; dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(struct pc236_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + dev->board_ptr = pc236_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); @@ -605,7 +593,7 @@ static struct comedi_driver amplc_pc236_driver = { .driver_name = PC236_DRIVER_NAME, .module = THIS_MODULE, .attach = pc236_attach, - .attach_pci = pc236_attach_pci, + .auto_attach = pc236_auto_attach, .detach = pc236_detach, .board_name = &pc236_boards[0].name, .offset = sizeof(struct pc236_board), @@ -620,13 +608,13 @@ static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { MODULE_DEVICE_TABLE(pci, pc236_pci_table); -static int __devinit amplc_pc236_pci_probe(struct pci_dev *dev, +static int amplc_pc236_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &lc_pc236_driver); } -static void __devexit amplc_pc236_pci_remove(struct pci_dev *dev) +static void amplc_pc236_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -635,7 +623,7 @@ static struct pci_driver amplc_pc236_pci_driver = { .name = PC236_DRIVER_NAME, .id_table = pc236_pci_table, .probe = &lc_pc236_pci_probe, - .remove = __devexit_p(&lc_pc236_pci_remove) + .remove = &lc_pc236_pci_remove }; module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver); diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index d0a4c44..dfbff77 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -52,7 +52,6 @@ The state of the outputs can be read. #define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) /* PCI263 PCI configuration register information */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c #define PCI_DEVICE_ID_INVALID 0xffff @@ -291,17 +290,21 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EINVAL; } } + /* - * The attach_pci hook (if non-NULL) is called at PCI probe time in preference - * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should - * be a board entry matching the supplied PCI device. + * The auto_attach hook is called at PCI probe time via + * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. + * There should be a board entry matching the supplied PCI device. */ -static int __devinit pc263_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int pc263_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pci_dev; + if (!DO_PCI) return -EINVAL; + pci_dev = comedi_to_pci_dev(dev); dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); dev->board_ptr = pc263_find_pci_board(pci_dev); @@ -348,7 +351,7 @@ static struct comedi_driver amplc_pc263_driver = { .driver_name = PC263_DRIVER_NAME, .module = THIS_MODULE, .attach = pc263_attach, - .attach_pci = pc263_attach_pci, + .auto_attach = pc263_auto_attach, .detach = pc263_detach, .board_name = &pc263_boards[0].name, .offset = sizeof(struct pc263_board), @@ -362,14 +365,14 @@ static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { }; MODULE_DEVICE_TABLE(pci, pc263_pci_table); -static int __devinit amplc_pc263_pci_probe(struct pci_dev *dev, +static int amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &lc_pc263_driver); } -static void __devexit amplc_pc263_pci_remove(struct pci_dev *dev) +static void amplc_pc263_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -378,7 +381,7 @@ static struct pci_driver amplc_pc263_pci_driver = { .name = PC263_DRIVER_NAME, .id_table = pc263_pci_table, .probe = &lc_pc263_pci_probe, - .remove = __devexit_p(&lc_pc263_pci_remove) + .remove = &lc_pc263_pci_remove }; module_comedi_pci_driver(amplc_pc263_driver, amplc_pc263_pci_driver); #else diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 1f65ec4..6e2566a 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -116,7 +116,6 @@ Caveats: /* * PCI IDs. */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008 #define PCI_DEVICE_ID_INVALID 0xffff @@ -758,76 +757,58 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* Step 3: make sure arguments are trivially compatible. */ + /* Step 3: check if arguments are trivially valid */ switch (cmd->start_src) { case TRIG_INT: - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); break; case TRIG_EXT: /* Force to external trigger 0. */ if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) { cmd->start_arg = COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { cmd->start_arg = COMBINE(cmd->start_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); - err++; + err |= -EINVAL; } break; } switch (cmd->scan_begin_src) { case TRIG_TIMER: - if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) { - cmd->scan_begin_arg = MAX_SCAN_PERIOD; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MAX_SCAN_PERIOD); + tmp = cmd->chanlist_len * CONVERT_PERIOD; if (tmp < MIN_SCAN_PERIOD) tmp = MIN_SCAN_PERIOD; - - if (cmd->scan_begin_arg < tmp) { - cmd->scan_begin_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, tmp); break; case TRIG_EXT: /* Force to external trigger 0. */ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); - err++; + 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)) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, - CR_FLAGS_MASK & ~(CR_EDGE - | - CR_INVERT)); - err++; + CR_FLAGS_MASK & + ~(CR_EDGE | CR_INVERT)); + err |= -EINVAL; } break; } - /* cmd->convert_src == TRIG_NOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - /* cmd->scan_end_arg == TRIG_COUNT */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: @@ -838,7 +819,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) { cmd->stop_arg = COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { @@ -847,10 +828,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; } @@ -1287,7 +1265,7 @@ static void pci224_report_attach(struct comedi_device *dev, unsigned int irq) } /* - * Common part of attach and attach_pci. + * Common part of attach and auto_attach. */ static int pci224_attach_common(struct comedi_device *dev, struct pci_dev *pci_dev, int *options) @@ -1443,16 +1421,15 @@ static int pci224_attach_common(struct comedi_device *dev, static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pci224_private *devpriv; struct pci_dev *pci_dev; - int ret; dev_info(dev->class_dev, DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct pci224_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; pci_dev = pci224_find_pci_dev(dev, it); if (!pci_dev) @@ -1461,19 +1438,19 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) return pci224_attach_common(dev, pci_dev, it->options); } -static int __devinit -pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) +static int +pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused) { - int ret; + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); + struct pci224_private *devpriv; - dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n", + dev_info(dev->class_dev, DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(struct pci224_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return ret; - } + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = pci224_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { @@ -1522,20 +1499,20 @@ static struct comedi_driver amplc_pci224_driver = { .module = THIS_MODULE, .attach = pci224_attach, .detach = pci224_detach, - .attach_pci = pci224_attach_pci, + .auto_attach = pci224_auto_attach, .board_name = &pci224_boards[0].name, .offset = sizeof(struct pci224_board), .num_names = ARRAY_SIZE(pci224_boards), }; -static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev, +static int amplc_pci224_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &lc_pci224_driver); } -static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev) +static void amplc_pci224_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1551,7 +1528,7 @@ static struct pci_driver amplc_pci224_pci_driver = { .name = "amplc_pci224", .id_table = amplc_pci224_pci_table, .probe = amplc_pci224_pci_probe, - .remove = __devexit_p(amplc_pci224_pci_remove), + .remove = amplc_pci224_pci_remove, }; module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver); diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index bd8fb87..366c68b 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -198,7 +198,6 @@ for (or detection of) various hardware problems added by Ian Abbott. #include "8255.h" /* PCI230 PCI configuration register information */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_PCI230 0x0000 #define PCI_DEVICE_ID_PCI260 0x0006 #define PCI_DEVICE_ID_INVALID 0xffff @@ -1000,14 +999,10 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* Step 3: make sure arguments are trivially compatible. - * "invalid argument" returned by comedilib to user mode process - * if this fails. */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */ #define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */ /*- Comedi limit due to unsigned int cmd. Driver limit @@ -1016,14 +1011,10 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, switch (cmd->scan_begin_src) { case TRIG_TIMER: - if (cmd->scan_begin_arg < MAX_SPEED_AO) { - cmd->scan_begin_arg = MAX_SPEED_AO; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED_AO) { - cmd->scan_begin_arg = MIN_SPEED_AO; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED_AO); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED_AO); break; case TRIG_EXT: /* External trigger - for PCI230+ hardware version 2 onwards. */ @@ -1031,37 +1022,27 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); - err++; + 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))) != 0) { - cmd->scan_begin_arg = - COMBINE(cmd->scan_begin_arg, 0, - CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); - err++; + cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, + CR_FLAGS_MASK & + ~(CR_EDGE | CR_INVERT)); + err |= -EINVAL; } break; default: - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); break; } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_NONE) { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1619,14 +1600,10 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* Step 3: make sure arguments are trivially compatible. - * "invalid argument" returned by comedilib to user mode process - * if this fails. */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #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 */ @@ -1657,14 +1634,10 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, max_speed_ai = MAX_SPEED_AI_PLUS; } - if (cmd->convert_arg < max_speed_ai) { - cmd->convert_arg = max_speed_ai; - err++; - } - if (cmd->convert_arg > MIN_SPEED_AI) { - cmd->convert_arg = MIN_SPEED_AI; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + max_speed_ai); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + MIN_SPEED_AI); } else if (cmd->convert_src == TRIG_EXT) { /* * external trigger @@ -1679,46 +1652,33 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) { cmd->convert_arg = COMBINE(cmd->convert_arg, 0, ~CR_FLAGS_MASK); - err++; + 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++; + 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. */ - if (cmd->convert_arg > 1) { - /* Default to trigger on +ve edge. */ - cmd->convert_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1); } } else { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (cmd->scan_begin_src == TRIG_EXT) { /* external "trigger" to begin each scan @@ -1727,24 +1687,21 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); - err++; + 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++; + err |= -EINVAL; } else { - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } if (err) @@ -2660,15 +2617,12 @@ static struct pci_dev *pci230_find_pci_dev(struct comedi_device *dev, static int pci230_alloc_private(struct comedi_device *dev) { struct pci230_private *devpriv; - int err; - /* sets dev->private to allocated memory */ - err = alloc_private(dev, sizeof(struct pci230_private)); - if (err) { - dev_err(dev->class_dev, "error! out of memory!\n"); - return err; - } - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + spin_lock_init(&devpriv->isr_spinlock); spin_lock_init(&devpriv->res_spinlock); spin_lock_init(&devpriv->ai_stop_spinlock); @@ -2676,7 +2630,7 @@ static int pci230_alloc_private(struct comedi_device *dev) return 0; } -/* Common part of attach and attach_pci. */ +/* Common part of attach and auto_attach. */ static int pci230_attach_common(struct comedi_device *dev, struct pci_dev *pci_dev) { @@ -2836,25 +2790,30 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n", thisboard->name, it->options[0], it->options[1]); - rc = pci230_alloc_private(dev); /* sets dev->private */ + + rc = pci230_alloc_private(dev); if (rc) return rc; + pci_dev = pci230_find_pci_dev(dev, it); if (!pci_dev) return -EIO; return pci230_attach_common(dev, pci_dev); } -static int __devinit pci230_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int pci230_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); int rc; dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n", pci_name(pci_dev)); - rc = pci230_alloc_private(dev); /* sets dev->private */ + + rc = pci230_alloc_private(dev); if (rc) return rc; + dev->board_ptr = pci230_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { dev_err(dev->class_dev, @@ -2891,20 +2850,20 @@ static struct comedi_driver amplc_pci230_driver = { .driver_name = "amplc_pci230", .module = THIS_MODULE, .attach = pci230_attach, - .attach_pci = pci230_attach_pci, + .auto_attach = pci230_auto_attach, .detach = pci230_detach, .board_name = &pci230_boards[0].name, .offset = sizeof(pci230_boards[0]), .num_names = ARRAY_SIZE(pci230_boards), }; -static int __devinit amplc_pci230_pci_probe(struct pci_dev *dev, +static int amplc_pci230_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &lc_pci230_driver); } -static void __devexit amplc_pci230_pci_remove(struct pci_dev *dev) +static void amplc_pci230_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -2920,7 +2879,7 @@ static struct pci_driver amplc_pci230_pci_driver = { .name = "amplc_pci230", .id_table = amplc_pci230_pci_table, .probe = amplc_pci230_pci_probe, - .remove = __devexit_p(amplc_pci230_pci_remove) + .remove = amplc_pci230_pci_remove }; module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 6d81d8b..93731de 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -194,67 +194,41 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED 10000 /* in nanoseconds */ #define MIN_SPEED 1000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + MIN_SPEED); } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -428,6 +402,7 @@ static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16cs_board *thisboard; + struct das16cs_private *devpriv; struct pcmcia_device *link; struct comedi_subdevice *s; int ret; @@ -451,8 +426,10 @@ static int das16cs_attach(struct comedi_device *dev, return ret; dev->irq = link->irq; - if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 3); if (ret) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index de21a26..aed6863 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -76,9 +76,6 @@ analog triggering on 1602 series #include "amcc_s5933.h" #include "comedi_fc.h" -/* PCI vendor number of ComputerBoards/MeasurementComputing */ -#define PCI_VENDOR_ID_CB 0x1307 - #define TIMER_BASE 100 /* 10MHz master clock */ #define AI_BUFFER_SIZE 1024 /* max ai fifo size */ #define AO_BUFFER_SIZE 1024 /* max ao fifo size */ @@ -843,49 +840,32 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, /* 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++; + cmd->start_arg &= ~(CR_FLAGS_MASK & + ~(CR_EDGE | CR_INVERT)); + err |= -EINVAL; } if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) { cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT); - err++; + err |= -EINVAL; } break; default: - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); break; } - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < - thisboard->ai_speed * cmd->chanlist_len) { - cmd->scan_begin_arg = - thisboard->ai_speed * cmd->chanlist_len; - err++; - } - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->ai_speed * cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_NONE) { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1078,31 +1058,18 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { - cmd->scan_begin_arg = thisboard->ao_scan_speed; - err++; - } - } + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->ao_scan_speed); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_NONE) { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1469,27 +1436,26 @@ static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev, return NULL; } -static int cb_pcidas_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int cb_pcidas_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct cb_pcidas_board *thisboard; struct cb_pcidas_private *devpriv; struct comedi_subdevice *s; int i; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = cb_pcidas_find_boardinfo(dev, pcidev); if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; dev->board_name = thisboard->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -1656,17 +1622,17 @@ static void cb_pcidas_detach(struct comedi_device *dev) static struct comedi_driver cb_pcidas_driver = { .driver_name = "cb_pcidas", .module = THIS_MODULE, - .attach_pci = cb_pcidas_attach_pci, + .auto_attach = cb_pcidas_auto_attach, .detach = cb_pcidas_detach, }; -static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev, +static int cb_pcidas_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcidas_driver); } -static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev) +static void cb_pcidas_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1688,7 +1654,7 @@ static struct pci_driver cb_pcidas_pci_driver = { .name = "cb_pcidas", .id_table = cb_pcidas_pci_table, .probe = cb_pcidas_pci_probe, - .remove = __devexit_p(cb_pcidas_pci_remove) + .remove = cb_pcidas_pci_remove }; module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 0472a90..d72b46c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -36,53 +36,57 @@ ************************************************************************/ /* - -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: 2002-10-09 -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: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - -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 file a bug report at -https://bugs.comedi.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 + 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?) + 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 */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include <linux/delay.h> #include <linux/interrupt.h> @@ -96,17 +100,17 @@ TODO: /* #define PCIDAS64_DEBUG enable debugging code */ #ifdef PCIDAS64_DEBUG -#define DEBUG_PRINT(format, args...) printk(format , ## args) +#define DEBUG_PRINT(format, args...) pr_debug(format, ## args) #else -#define DEBUG_PRINT(format, args...) +#define DEBUG_PRINT(format, args...) no_printk(format, ## args) #endif #define TIMER_BASE 25 /* 40MHz master clock */ -#define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow acquisition, maybe I'll support this someday */ +/* 100kHz 'prescaled' clock for slow acquisition, + * maybe I'll support this someday */ +#define PRESCALED_TIMER_BASE 10000 #define DMA_BUFFER_SIZE 0x1000 -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 - /* maximum value that can be loaded into board's 24-bit counters*/ static const int max_counter_value = 0xffffff; @@ -119,7 +123,7 @@ enum base_address_regions { DIO_COUNTER_BADDRINDEX = 3, }; -/* priv(dev)->main_iobase registers */ +/* devpriv->main_iobase registers */ enum write_only_registers { INTR_ENABLE_REG = 0x0, /* interrupt enable register */ HW_CONFIG_REG = 0x2, /* hardware config register */ @@ -128,26 +132,36 @@ enum write_only_registers { ADC_CONTROL0_REG = 0x10, /* adc control register 0 */ ADC_CONTROL1_REG = 0x12, /* adc control register 1 */ CALIBRATION_REG = 0x14, - ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, /* lower 16 bits of adc sample interval counter */ - ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, /* upper 8 bits of adc sample interval counter */ - ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, /* lower 16 bits of delay interval counter */ - ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, /* upper 8 bits of delay interval counter */ - ADC_COUNT_LOWER_REG = 0x1e, /* lower 16 bits of hardware conversion/scan counter */ - ADC_COUNT_UPPER_REG = 0x20, /* upper 8 bits of hardware conversion/scan counter */ + /* 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, - ADC_QUEUE_HIGH_REG = 0x2c, /* high channel for internal queue, use adc_chan_bits() inline above */ + /* 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 */ - DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, /* lower 16 bits of dac sample interval counter */ - DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, /* upper 8 bits of dac sample interval counter */ + /* 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)); @@ -164,7 +178,9 @@ static inline unsigned int dac_msb_4020_reg(unsigned int channel) } enum read_only_registers { - HW_STATUS_REG = 0x0, /* hardware status register, reading this apparently clears pending interrupts as well */ + /* 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, @@ -174,12 +190,14 @@ enum read_only_registers { enum read_write_registers { I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */ - ADC_QUEUE_FIFO_REG = 0x100, /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */ + /* 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_FIFO_REG = 0x300, /* dac data fifo, has weird interactions with external channel queue */ + /* dac data fifo, has weird interactions with external channel queue */ + DAC_FIFO_REG = 0x300, }; -/* priv(dev)->dio_counter_iobase registers */ +/* devpriv->dio_counter_iobase registers */ enum dio_counter_registers { DIO_8255_OFFSET = 0x0, DO_REG = 0x20, @@ -191,13 +209,13 @@ enum dio_counter_registers { /* bit definitions for write-only registers */ enum intr_enable_contents { - ADC_INTR_SRC_MASK = 0x3, /* bits that set adc interrupt source */ - ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quater full */ + 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 (probably wont use this it's pretty fancy) */ + 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 interrupt */ + 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, @@ -211,25 +229,33 @@ enum intr_enable_contents { }; enum hw_config_contents { - MASTER_CLOCK_4020_MASK = 0x3, /* bits that specify master clock source for 4020 */ - INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock for 4020 */ + 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 (more versatile than internal queue) */ - SLOW_DAC_BIT = 0x400, /* use 225 nanosec strobe when loading dac instead of 50 nanosec */ - HW_CONFIG_DUMMY_BITS = 0x2000, /* bit with unknown function yet given as default value in pci-das64 manual */ - DMA_CH_SELECT_BIT = 0x8000, /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */ - FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */ + 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 */ + DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */ }; #define DAC_FIFO_SIZE 0x2000 enum daq_atrig_low_4020_contents { - EXT_AGATE_BNC_BIT = 0x8000, /* use trig/ext clk bnc input for analog gate signal */ - EXT_STOP_TRIG_BNC_BIT = 0x4000, /* use trig/ext clk bnc input for external stop trigger signal */ - EXT_START_TRIG_BNC_BIT = 0x2000, /* use trig/ext clk bnc input for external start trigger signal */ + /* 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, }; + static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold) { return threshold & 0xfff; @@ -247,14 +273,17 @@ enum adc_control0_contents { ADC_START_TRIG_ANALOG_BITS = 0x30, ADC_START_TRIG_MASK = 0x30, ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */ - ADC_EXT_CONV_FALLING_BIT = 0x800, /* external pacing uses falling edge */ - ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, /* enable hardware scan counter */ + /* 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 { - ADC_QUEUE_CONFIG_BIT = 0x1, /* should be set for boards with > 16 channels */ + /* 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 */ @@ -263,10 +292,11 @@ enum adc_control1_contents { 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 */ + FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */ CHANNEL_MODE_4020_MASK = 0x3000, ADC_MODE_MASK = 0xf000, }; + static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel) { return (channel & 0x3) << 8; @@ -289,9 +319,10 @@ enum calibration_contents { 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_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */ CAL_GAIN_BIT = 0x800, }; + /* calibration sources for 6025 are: * 0 : ground * 1 : 10V @@ -302,6 +333,7 @@ enum calibration_contents { * 6 : dac channel 0 * 7 : dac channel 1 */ + static inline uint16_t adc_src_bits(unsigned int source) { return (source & 0xf) << 3; @@ -315,10 +347,12 @@ static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel) enum adc_queue_load_contents { UNIP_BIT = 0x800, /* unipolar/bipolar bit */ ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */ - ADC_COMMON_BIT = 0x2000, /* non-referenced single-ended (common-mode input) */ + /* 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 uint16_t adc_chan_bits(unsigned int channel) { return channel & 0x3f; @@ -365,6 +399,7 @@ enum hw_status_contents { EXT_INTR_PENDING_BIT = 0x100, ADC_STOP_BIT = 0x200, }; + static inline uint16_t pipe_full_bits(uint16_t hw_status_bits) { return (hw_status_bits >> 10) & 0x3; @@ -393,9 +428,12 @@ enum i2c_addresses { }; enum range_cal_i2c_contents { - ADC_SRC_4020_MASK = 0x70, /* bits that set what source the adc converter measures */ - BNC_TRIG_THRESHOLD_0V_BIT = 0x80, /* make bnc trig/ext clock threshold 0V instead of 2.5V */ + /* 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 uint8_t adc_src_4020_bits(unsigned int source) { return (source << 4) & ADC_SRC_4020_MASK; @@ -562,11 +600,12 @@ struct pcidas64_board { const struct comedi_lrange *ai_range_table; int ao_nchan; /* number of analog out channels */ int ao_bits; /* analog output resolution */ - int ao_scan_speed; /* analog output speed (for a scan, not conversion) */ + 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; - enum register_layout layout; /* different board families have slightly different registers */ + /* different board families have slightly different registers */ + enum register_layout layout; unsigned has_8255:1; }; @@ -596,7 +635,7 @@ static const struct hw_fifo_info ai_fifo_60xx = { #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(struct pcidas64_board *board) +static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board) { if (board->layout == LAYOUT_4020) return MAX_AI_DMA_RING_COUNT; @@ -1025,24 +1064,23 @@ static const struct pcidas64_board pcidas64_boards[] = { #endif }; -static inline struct pcidas64_board *board(const struct comedi_device *dev) -{ - return (struct pcidas64_board *)dev->board_ptr; -} - static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev, int use_differential) { - if ((board(dev)->layout == LAYOUT_64XX && !use_differential) || - (board(dev)->layout == LAYOUT_60XX && use_differential)) + const struct pcidas64_board *thisboard = comedi_board(dev); + + if ((thisboard->layout == LAYOUT_64XX && !use_differential) || + (thisboard->layout == LAYOUT_60XX && use_differential)) return ADC_SE_DIFF_BIT; else return 0; }; struct ext_clock_info { - unsigned int divisor; /* master clock divisor to use for scans with external master clock */ - unsigned int chanspec; /* chanspec for master clock input when used as scan begin src */ + /* 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. */ @@ -1058,30 +1096,52 @@ struct pcidas64_private { /* local address (used by dma controller) */ uint32_t local0_iobase; uint32_t local1_iobase; - volatile unsigned int ai_count; /* number of analog input samples remaining */ - uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; /* dma buffers for analog input */ - dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; /* physical addresses of ai dma buffers */ - struct plx_dma_desc *ai_dma_desc; /* array of ai dma descriptors read by plx9080, allocated to get proper alignment */ - dma_addr_t ai_dma_desc_bus_addr; /* physical address of ai dma descriptor array */ - volatile unsigned int ai_dma_index; /* index of the ai dma descriptor/buffer that is currently being used */ - uint16_t *ao_buffer[AO_DMA_RING_COUNT]; /* dma buffers for analog output */ - dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; /* physical addresses of ao dma buffers */ + /* number of analog input samples remaining */ + volatile unsigned int ai_count; + /* dma buffers for analog input */ + uint16_t *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 */ + volatile unsigned int ai_dma_index; + /* dma buffers for analog output */ + uint16_t *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; - volatile unsigned int ao_dma_index; /* keeps track of buffer where the next ao sample should go */ - volatile unsigned long ao_count; /* number of analog output samples remaining */ - volatile unsigned int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */ + /* keeps track of buffer where the next ao sample should go */ + volatile unsigned int ao_dma_index; + /* number of analog output samples remaining */ + volatile unsigned long ao_count; + /* remember what the analog outputs are set to, to allow readback */ + volatile unsigned int ao_value[2]; unsigned int hw_revision; /* stc chip hardware revision number */ - volatile unsigned int intr_enable_bits; /* last bits sent to INTR_ENABLE_REG register */ - volatile uint16_t adc_control1_bits; /* last bits sent to ADC_CONTROL1_REG register */ - volatile uint16_t fifo_size_bits; /* last bits sent to FIFO_SIZE_REG register */ - volatile uint16_t hw_config_bits; /* last bits sent to HW_CONFIG_REG register */ + /* last bits sent to INTR_ENABLE_REG register */ + volatile unsigned int intr_enable_bits; + /* last bits sent to ADC_CONTROL1_REG register */ + volatile uint16_t adc_control1_bits; + /* last bits sent to FIFO_SIZE_REG register */ + volatile uint16_t fifo_size_bits; + /* last bits sent to HW_CONFIG_REG register */ + volatile uint16_t hw_config_bits; volatile uint16_t dac_control1_bits; - volatile uint32_t plx_control_bits; /* last bits written to plx9080 control register */ - volatile uint32_t plx_intcsr_bits; /* last bits written to plx interrupt control and status register */ - volatile int calibration_source; /* index of calibration source readable through ai ch0 */ - volatile uint8_t i2c_cal_range_bits; /* bits written to i2c calibration/range register */ - volatile unsigned int ext_trig_falling; /* configure digital triggers to trigger on falling edge */ + /* last bits written to plx9080 control register */ + volatile uint32_t plx_control_bits; + /* last bits written to plx interrupt control and status register */ + volatile uint32_t plx_intcsr_bits; + /* index of calibration source readable through ai ch0 */ + volatile int calibration_source; + /* bits written to i2c calibration/range register */ + volatile uint8_t i2c_cal_range_bits; + /* configure digital triggers to trigger on falling edge */ + volatile unsigned int ext_trig_falling; /* states of various devices stored to enable read-back */ unsigned int ad8402_state[2]; unsigned int caldac_state[8]; @@ -1091,93 +1151,12 @@ struct pcidas64_private { short ao_bounce_buffer[DAC_FIFO_SIZE]; }; -/* inline function that makes it easier to - * access the private structure. - */ -static inline struct pcidas64_private *priv(struct comedi_device *dev) -{ - return dev->private; -} - -static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ao_readback_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int ao_inttrig(struct comedi_device *dev, - struct comedi_subdevice *subdev, unsigned int trig_num); -static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static irqreturn_t handle_interrupt(int irq, void *d); -static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int dio_callback(int dir, int port, int data, unsigned long arg); -static int dio_callback_4020(int dir, int port, int data, unsigned long arg); -static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dio_60xx_config_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int calib_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int calib_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ad8402_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static void ad8402_write(struct comedi_device *dev, unsigned int channel, - unsigned int value); -static int ad8402_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int eeprom_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); -static unsigned int get_divisor(unsigned int ns, unsigned int flags); -static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t *data, unsigned int length); -static void caldac_write(struct comedi_device *dev, unsigned int channel, - unsigned int value); -static int caldac_8800_write(struct comedi_device *dev, unsigned int address, - uint8_t value); -/* static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, unsigned int dac_b); */ -static int caldac_i2c_write(struct comedi_device *dev, - unsigned int caldac_channel, unsigned int value); -static void abort_dma(struct comedi_device *dev, unsigned int channel); -static void disable_plx_interrupts(struct comedi_device *dev); -static int set_ai_fifo_size(struct comedi_device *dev, - unsigned int num_samples); -static unsigned int ai_fifo_size(struct comedi_device *dev); -static int set_ai_fifo_segment_length(struct comedi_device *dev, - unsigned int num_entries); -static void disable_ai_pacing(struct comedi_device *dev); -static void disable_ai_interrupts(struct comedi_device *dev); -static void enable_ai_interrupts(struct comedi_device *dev, - const struct comedi_cmd *cmd); -static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags); -static void load_ao_dma(struct comedi_device *dev, - const struct comedi_cmd *cmd); - static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, unsigned int range_index) { + const struct pcidas64_board *thisboard = comedi_board(dev); const struct comedi_krange *range = - &board(dev)->ai_range_table->range[range_index]; + &thisboard->ai_range_table->range[range_index]; unsigned int bits = 0; switch (range->max) { @@ -1220,7 +1199,9 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, static unsigned int hw_revision(const struct comedi_device *dev, uint16_t hw_status_bits) { - if (board(dev)->layout == LAYOUT_4020) + const struct pcidas64_board *thisboard = comedi_board(dev); + + if (thisboard->layout == LAYOUT_4020) return (hw_status_bits >> 13) & 0x7; return (hw_status_bits >> 12) & 0xf; @@ -1230,7 +1211,8 @@ static void set_dac_range_bits(struct comedi_device *dev, volatile uint16_t *bits, unsigned int channel, unsigned int range) { - unsigned int code = board(dev)->ao_range_code[range]; + const struct pcidas64_board *thisboard = comedi_board(dev); + unsigned int code = thisboard->ao_range_code[range]; if (channel > 1) comedi_error(dev, "bug! bad channel?"); @@ -1246,20 +1228,86 @@ 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_INTRCS_REG); +} + +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); + + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); +} + +static void enable_ai_interrupts(struct comedi_device *dev, + const struct comedi_cmd *cmd) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + uint32_t 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 TRIG_WAKE_EOS flag is set. */ + if (cmd->flags & TRIG_WAKE_EOS) { + /* 4020 doesn't support pio transfers except for fifo dregs */ + if (thisboard->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); + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); + spin_unlock_irqrestore(&dev->spinlock, flags); +} + /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; uint32_t bits; - void __iomem *plx_iobase = priv(dev)->plx9080_iobase; + void __iomem *plx_iobase = devpriv->plx9080_iobase; - priv(dev)->plx_control_bits = - readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG); + devpriv->plx_control_bits = + readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); /* plx9080 dump */ DEBUG_PRINT(" plx interrupt status 0x%x\n", readl(plx_iobase + PLX_INTRCS_REG)); DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); - DEBUG_PRINT(" plx control reg 0x%x\n", priv(dev)->plx_control_bits); + DEBUG_PRINT(" plx control reg 0x%x\n", devpriv->plx_control_bits); DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n", readl(plx_iobase + PLX_MARB_REG)); DEBUG_PRINT(" plx region0 reg 0x%x\n", @@ -1292,7 +1340,7 @@ static void init_plx9080(struct comedi_device *dev) #else bits = 0; #endif - writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG); + writel(bits, devpriv->plx9080_iobase + PLX_BIGEND_REG); disable_plx_interrupts(dev); @@ -1307,9 +1355,11 @@ static void init_plx9080(struct comedi_device *dev) bits |= PLX_EN_BTERM_BIT; /* enable dma chaining */ bits |= PLX_EN_CHAIN_BIT; - /* enable interrupt on dma done (probably don't need this, since chain never finishes) */ + /* enable interrupt on dma done + * (probably don't need this, since chain never finishes) */ bits |= PLX_EN_DMA_DONE_INTR_BIT; - /* don't increment local address during transfers (we are transferring from a fixed fifo register) */ + /* don't increment local address during transfers + * (we are transferring from a fixed fifo register) */ bits |= PLX_LOCAL_ADDR_CONST_BIT; /* route dma interrupt to pci bus */ bits |= PLX_DMA_INTR_PCI_BIT; @@ -1318,324 +1368,235 @@ static void init_plx9080(struct comedi_device *dev) /* enable local burst mode */ bits |= PLX_DMA_LOCAL_BURST_EN_BIT; /* 4020 uses 32 bit dma */ - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) bits |= PLX_LOCAL_BUS_32_WIDE_BITS; - } else { /* localspace0 bus is 16 bits wide */ + else /* localspace0 bus is 16 bits wide */ bits |= PLX_LOCAL_BUS_16_WIDE_BITS; - } writel(bits, plx_iobase + PLX_DMA1_MODE_REG); - if (ao_cmd_is_supported(board(dev))) + if (ao_cmd_is_supported(thisboard)) writel(bits, plx_iobase + PLX_DMA0_MODE_REG); /* enable interrupts on plx 9080 */ - priv(dev)->plx_intcsr_bits |= + devpriv->plx_intcsr_bits |= ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE | ICS_DMA0_E | ICS_DMA1_E; - writel(priv(dev)->plx_intcsr_bits, - priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + writel(devpriv->plx_intcsr_bits, + devpriv->plx9080_iobase + PLX_INTRCS_REG); } -/* Allocate and initialize the subdevice structures. - */ -static int setup_subdevices(struct comedi_device *dev) +static void disable_ai_pacing(struct comedi_device *dev) { - struct comedi_subdevice *s; - void __iomem *dio_8255_iobase; - int i; - int ret; + struct pcidas64_private *devpriv = dev->private; + unsigned long flags; - ret = comedi_alloc_subdevices(dev, 10); - if (ret) - return ret; + disable_ai_interrupts(dev); - 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(dev)->layout == LAYOUT_60XX) - s->subdev_flags |= SDF_COMMON | SDF_DIFF; - else if (board(dev)->layout == LAYOUT_64XX) - s->subdev_flags |= SDF_DIFF; - /* XXX Number of inputs in differential mode is ignored */ - s->n_chan = board(dev)->ai_se_chans; - s->len_chanlist = 0x2000; - s->maxdata = (1 << board(dev)->ai_bits) - 1; - s->range_table = board(dev)->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(dev)->layout == LAYOUT_4020) { - uint8_t data; - /* set adc to read from inputs (not internal calibration sources) */ - priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4); - /* set channels to +-5 volt input ranges */ - for (i = 0; i < s->n_chan; i++) - priv(dev)->i2c_cal_range_bits |= attenuate_bit(i); - data = priv(dev)->i2c_cal_range_bits; - i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data)); - } + 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); - /* analog output subdevice */ - s = &dev->subdevices[1]; - if (board(dev)->ao_nchan) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; - s->n_chan = board(dev)->ao_nchan; - s->maxdata = (1 << board(dev)->ao_bits) - 1; - s->range_table = board(dev)->ao_range_table; - s->insn_read = ao_readback_insn; - s->insn_write = ao_winsn; - if (ao_cmd_is_supported(board(dev))) { - dev->write_subdev = s; - s->do_cmdtest = ao_cmdtest; - s->do_cmd = ao_cmd; - s->len_chanlist = board(dev)->ao_nchan; - s->cancel = ao_cancel; - } - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* disable pacing, triggering, etc */ + writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT, + devpriv->main_iobase + ADC_CONTROL0_REG); +} - /* digital input */ - s = &dev->subdevices[2]; - if (board(dev)->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; +static int set_ai_fifo_segment_length(struct comedi_device *dev, + unsigned int num_entries) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + static const int increment_size = 0x100; + const struct hw_fifo_info *const fifo = thisboard->ai_fifo; + unsigned int num_increments; + uint16_t bits; - /* digital output */ - if (board(dev)->layout == LAYOUT_64XX) { - s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = do_wbits; - } else - s->type = COMEDI_SUBD_UNUSED; + if (num_entries < increment_size) + num_entries = increment_size; + if (num_entries > fifo->max_segment_length) + num_entries = fifo->max_segment_length; - /* 8255 */ - s = &dev->subdevices[4]; - if (board(dev)->has_8255) { - if (board(dev)->layout == LAYOUT_4020) { - dio_8255_iobase = - priv(dev)->main_iobase + I8255_4020_REG; - subdev_8255_init(dev, s, dio_callback_4020, - (unsigned long)dio_8255_iobase); - } else { - dio_8255_iobase = - priv(dev)->dio_counter_iobase + DIO_8255_OFFSET; - subdev_8255_init(dev, s, dio_callback, - (unsigned long)dio_8255_iobase); - } - } else - s->type = COMEDI_SUBD_UNUSED; + /* 1 == 256 entries, 2 == 512 entries, etc */ + num_increments = (num_entries + increment_size / 2) / increment_size; - /* 8 channel dio for 60xx */ - s = &dev->subdevices[5]; - if (board(dev)->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; + 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); - /* 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(dev)->layout == LAYOUT_4020) - s->maxdata = 0xfff; - else - s->maxdata = 0xff; - s->insn_read = calib_read_insn; - s->insn_write = calib_write_insn; - for (i = 0; i < s->n_chan; i++) - caldac_write(dev, i, s->maxdata / 2); + devpriv->ai_fifo_segment_length = num_increments * increment_size; - /* 2 channel ad8402 potentiometer */ - s = &dev->subdevices[7]; - if (board(dev)->layout == LAYOUT_64XX) { - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = 2; - s->insn_read = ad8402_read_insn; - s->insn_write = ad8402_write_insn; - s->maxdata = 0xff; - for (i = 0; i < s->n_chan; i++) - ad8402_write(dev, i, s->maxdata / 2); - } else - s->type = COMEDI_SUBD_UNUSED; + DEBUG_PRINT("set hardware fifo segment length to %i\n", + devpriv->ai_fifo_segment_length); - /* serial EEPROM, if present */ - s = &dev->subdevices[8]; - if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { - 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; + return devpriv->ai_fifo_segment_length; +} - /* user counter subd XXX */ - s = &dev->subdevices[9]; - s->type = COMEDI_SUBD_UNUSED; +/* 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 *thisboard = comedi_board(dev); + unsigned int num_fifo_entries; + int retval; + const struct hw_fifo_info *const fifo = thisboard->ai_fifo; - return 0; + 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; + + num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; + + DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); + + return num_samples; } -static void disable_plx_interrupts(struct comedi_device *dev) +/* query length of fifo */ +static unsigned int ai_fifo_size(struct comedi_device *dev) { - priv(dev)->plx_intcsr_bits = 0; - writel(priv(dev)->plx_intcsr_bits, - priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + + return devpriv->ai_fifo_segment_length * + thisboard->ai_fifo->num_segments * + thisboard->ai_fifo->sample_packing_ratio; } static void init_stc_registers(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; uint16_t 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 */ + /* bit should be set for 6025, + * although docs say boards with <= 16 chans should be cleared XXX */ if (1) - priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT; - writew(priv(dev)->adc_control1_bits, - priv(dev)->main_iobase + ADC_CONTROL1_REG); + 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, priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); + writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) bits |= INTERNAL_CLOCK_4020_BITS; - priv(dev)->hw_config_bits |= bits; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + devpriv->hw_config_bits |= bits; + writew(devpriv->hw_config_bits, + devpriv->main_iobase + HW_CONFIG_REG); - writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG); - writew(0, priv(dev)->main_iobase + CALIBRATION_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 */ - priv(dev)->fifo_size_bits |= DAC_FIFO_BITS; + devpriv->fifo_size_bits |= DAC_FIFO_BITS; set_ai_fifo_segment_length(dev, - board(dev)->ai_fifo->max_segment_length); + thisboard->ai_fifo->max_segment_length); - priv(dev)->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT; - priv(dev)->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */ - EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT; - writew(priv(dev)->intr_enable_bits, - priv(dev)->main_iobase + INTR_ENABLE_REG); + 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 *thisboard = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pcidas64_private *devpriv = dev->private; int i; /* alocate pci dma buffers */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { - priv(dev)->ai_buffer[i] = - pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, - &priv(dev)->ai_buffer_bus_addr[i]); - if (priv(dev)->ai_buffer[i] == NULL) + for (i = 0; i < ai_dma_ring_count(thisboard); i++) { + devpriv->ai_buffer[i] = + pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, + &devpriv->ai_buffer_bus_addr[i]); + if (devpriv->ai_buffer[i] == NULL) return -ENOMEM; } for (i = 0; i < AO_DMA_RING_COUNT; i++) { - if (ao_cmd_is_supported(board(dev))) { - priv(dev)->ao_buffer[i] = - pci_alloc_consistent(pcidev, - DMA_BUFFER_SIZE, - &priv(dev)-> - ao_buffer_bus_addr[i]); - if (priv(dev)->ao_buffer[i] == NULL) + if (ao_cmd_is_supported(thisboard)) { + devpriv->ao_buffer[i] = + pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, + &devpriv-> + ao_buffer_bus_addr[i]); + if (devpriv->ao_buffer[i] == NULL) return -ENOMEM; } } /* allocate dma descriptors */ - priv(dev)->ai_dma_desc = - pci_alloc_consistent(pcidev, - sizeof(struct plx_dma_desc) * - ai_dma_ring_count(board(dev)), - &priv(dev)->ai_dma_desc_bus_addr); - if (priv(dev)->ai_dma_desc == NULL) + devpriv->ai_dma_desc = + pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * + ai_dma_ring_count(thisboard), + &devpriv->ai_dma_desc_bus_addr); + if (devpriv->ai_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n", - priv(dev)->ai_dma_desc_bus_addr); - if (ao_cmd_is_supported(board(dev))) { - priv(dev)->ao_dma_desc = - pci_alloc_consistent(pcidev, - sizeof(struct plx_dma_desc) * - AO_DMA_RING_COUNT, - &priv(dev)->ao_dma_desc_bus_addr); - if (priv(dev)->ao_dma_desc == NULL) + DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n", + (unsigned long long)devpriv->ai_dma_desc_bus_addr); + if (ao_cmd_is_supported(thisboard)) { + devpriv->ao_dma_desc = + pci_alloc_consistent(pcidev, + sizeof(struct plx_dma_desc) * + AO_DMA_RING_COUNT, + &devpriv->ao_dma_desc_bus_addr); + if (devpriv->ao_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n", - priv(dev)->ao_dma_desc_bus_addr); + DEBUG_PRINT("ao dma descriptors start at bus addr 0x%llx\n", + (unsigned long long)devpriv->ao_dma_desc_bus_addr); } /* initialize dma descriptors */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { - priv(dev)->ai_dma_desc[i].pci_start_addr = - cpu_to_le32(priv(dev)->ai_buffer_bus_addr[i]); - if (board(dev)->layout == LAYOUT_4020) - priv(dev)->ai_dma_desc[i].local_start_addr = - cpu_to_le32(priv(dev)->local1_iobase + - ADC_FIFO_REG); + for (i = 0; i < ai_dma_ring_count(thisboard); i++) { + devpriv->ai_dma_desc[i].pci_start_addr = + cpu_to_le32(devpriv->ai_buffer_bus_addr[i]); + if (thisboard->layout == LAYOUT_4020) + devpriv->ai_dma_desc[i].local_start_addr = + cpu_to_le32(devpriv->local1_iobase + + ADC_FIFO_REG); else - priv(dev)->ai_dma_desc[i].local_start_addr = - cpu_to_le32(priv(dev)->local0_iobase + - ADC_FIFO_REG); - priv(dev)->ai_dma_desc[i].transfer_size = cpu_to_le32(0); - priv(dev)->ai_dma_desc[i].next = - cpu_to_le32((priv(dev)->ai_dma_desc_bus_addr + ((i + - 1) % - ai_dma_ring_count - (board - (dev))) * - sizeof(priv(dev)->ai_dma_desc[0])) | - PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | - PLX_XFER_LOCAL_TO_PCI); + 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(thisboard)) * + sizeof(devpriv->ai_dma_desc[0])) | + PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | + PLX_XFER_LOCAL_TO_PCI); } - if (ao_cmd_is_supported(board(dev))) { + if (ao_cmd_is_supported(thisboard)) { for (i = 0; i < AO_DMA_RING_COUNT; i++) { - priv(dev)->ao_dma_desc[i].pci_start_addr = - cpu_to_le32(priv(dev)->ao_buffer_bus_addr[i]); - priv(dev)->ao_dma_desc[i].local_start_addr = - cpu_to_le32(priv(dev)->local0_iobase + - DAC_FIFO_REG); - priv(dev)->ao_dma_desc[i].transfer_size = - cpu_to_le32(0); - priv(dev)->ao_dma_desc[i].next = - cpu_to_le32((priv(dev)->ao_dma_desc_bus_addr + - ((i + 1) % (AO_DMA_RING_COUNT)) * - sizeof(priv(dev)->ao_dma_desc[0])) | - PLX_DESC_IN_PCI_BIT | - PLX_INTR_TERM_COUNT); + 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_DESC_IN_PCI_BIT | + PLX_INTR_TERM_COUNT); } } return 0; @@ -1649,216 +1610,140 @@ static inline void warn_external_queue(struct comedi_device *dev) "Use internal AI channel queue (channels must be consecutive and use same range/aref)"); } -static struct pci_dev *cb_pcidas64_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +/* 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 pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - int i; + struct pcidas64_private *devpriv = dev->private; + static const int data_bit = CTL_EE_W; + void __iomem *plx_control_addr = devpriv->plx9080_iobase + + PLX_CONTROL_REG; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) - continue; - - for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) { - if (pcidas64_boards[i].device_id != pcidev->device) - continue; - dev->board_ptr = pcidas64_boards + i; - return pcidev; - } + 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); } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; } -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. - */ -static int attach(struct comedi_device *dev, struct comedi_devconfig *it) +/* set i2c clock line high or low */ +static void i2c_set_scl(struct comedi_device *dev, int state) { - struct pci_dev *pcidev; - uint32_t local_range, local_decode; - int retval; - -/* - * Allocate the private structure area. - */ - if (alloc_private(dev, sizeof(struct pcidas64_private)) < 0) - return -ENOMEM; + struct pcidas64_private *devpriv = dev->private; + static const int clock_bit = CTL_USERO; + void __iomem *plx_control_addr = devpriv->plx9080_iobase + + PLX_CONTROL_REG; - pcidev = cb_pcidas64_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); + 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 */ - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_warn(dev->class_dev, - "failed to enable PCI device and request regions\n"); - return -EIO; + devpriv->plx_control_bits |= clock_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_low_udelay); } - pci_set_master(pcidev); - - /* Initialize dev->board_name */ - dev->board_name = board(dev)->name; +} - dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); +static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) +{ + uint8_t bit; + unsigned int num_bits = 8; - priv(dev)->plx9080_phys_iobase = - pci_resource_start(pcidev, PLX9080_BADDRINDEX); - priv(dev)->main_phys_iobase = dev->iobase; - priv(dev)->dio_counter_phys_iobase = - pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); + DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); - /* remap, won't work with 2.0 kernels but who cares */ - priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase, - pci_resource_len(pcidev, - PLX9080_BADDRINDEX)); - priv(dev)->main_iobase = - ioremap(priv(dev)->main_phys_iobase, - pci_resource_len(pcidev, MAIN_BADDRINDEX)); - priv(dev)->dio_counter_iobase = - ioremap(priv(dev)->dio_counter_phys_iobase, - pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); - - if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase - || !priv(dev)->dio_counter_iobase) { - dev_warn(dev->class_dev, "failed to remap io memory\n"); - return -ENOMEM; + 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); } +} - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase); - DEBUG_PRINT(" main remapped to 0x%p\n", priv(dev)->main_iobase); - DEBUG_PRINT(" diocounter remapped to 0x%p\n", - priv(dev)->dio_counter_iobase); - - /* figure out what local addresses are */ - local_range = - readl(priv(dev)->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK; - local_decode = - readl(priv(dev)->plx9080_iobase + - PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK; - priv(dev)->local0_iobase = - ((uint32_t) priv(dev)->main_phys_iobase & ~local_range) | - local_decode; - local_range = - readl(priv(dev)->plx9080_iobase + PLX_LAS1RNG_REG) & LRNG_MEM_MASK; - local_decode = - readl(priv(dev)->plx9080_iobase + - PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK; - priv(dev)->local1_iobase = - ((uint32_t) priv(dev)->dio_counter_phys_iobase & ~local_range) | - local_decode; - - DEBUG_PRINT(" local 0 io addr 0x%x\n", priv(dev)->local0_iobase); - DEBUG_PRINT(" local 1 io addr 0x%x\n", priv(dev)->local1_iobase); - - retval = alloc_and_init_dma_members(dev); - if (retval < 0) - return retval; - - priv(dev)->hw_revision = - hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG)); - dev_dbg(dev->class_dev, "stc hardware revision %i\n", - priv(dev)->hw_revision); - init_plx9080(dev); - init_stc_registers(dev); - /* get irq */ - if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, - "cb_pcidas64", dev)) { - dev_dbg(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); +/* 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); - retval = setup_subdevices(dev); - if (retval < 0) - return retval; + 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); +} - return 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 detach(struct comedi_device *dev) +static void i2c_write(struct comedi_device *dev, unsigned int address, + const uint8_t *data, unsigned int length) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pcidas64_private *devpriv = dev->private; unsigned int i; + uint8_t bitstream; + static const int read_bit = 0x1; - if (dev->irq) - free_irq(dev->irq, dev); - if (priv(dev)) { - if (pcidev) { - if (priv(dev)->plx9080_iobase) { - disable_plx_interrupts(dev); - iounmap(priv(dev)->plx9080_iobase); - } - if (priv(dev)->main_iobase) - iounmap(priv(dev)->main_iobase); - if (priv(dev)->dio_counter_iobase) - iounmap(priv(dev)->dio_counter_iobase); - /* free pci dma buffers */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { - if (priv(dev)->ai_buffer[i]) - pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - priv(dev)-> - ai_buffer[i], - priv - (dev)->ai_buffer_bus_addr - [i]); - } - for (i = 0; i < AO_DMA_RING_COUNT; i++) { - if (priv(dev)->ao_buffer[i]) - pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - priv(dev)-> - ao_buffer[i], - priv - (dev)->ao_buffer_bus_addr - [i]); - } - /* free dma descriptors */ - if (priv(dev)->ai_dma_desc) - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) - * - ai_dma_ring_count(board - (dev)), - priv(dev)->ai_dma_desc, - priv(dev)-> - ai_dma_desc_bus_addr); - if (priv(dev)->ao_dma_desc) - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) - * AO_DMA_RING_COUNT, - priv(dev)->ao_dma_desc, - priv(dev)-> - ao_dma_desc_bus_addr); - } - } - if (dev->subdevices) - subdev_8255_cleanup(dev, &dev->subdevices[4]); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + /* XXX need mutex to prevent simultaneous attempts to access + * eeprom and i2c bus */ + + /* make sure we dont send anything to eeprom */ + devpriv->plx_control_bits &= ~CTL_EE_CS; + + i2c_stop(dev); + i2c_start(dev); + + /* send address and write bit */ + bitstream = (address << 1) & ~read_bit; + i2c_write_byte(dev, bitstream); - pci_dev_put(pcidev); + /* get acknowledge */ + if (i2c_read_ack(dev) != 0) { + comedi_error(dev, "i2c write failed: no acknowledge"); + 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) { + comedi_error(dev, "i2c write failed: no acknowledge"); + i2c_stop(dev); + return; + } + } + i2c_stop(dev); } static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; unsigned int bits = 0, n, i; unsigned int channel, range, aref; unsigned long flags; @@ -1875,35 +1760,37 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_irqsave(&dev->spinlock, flags); if (insn->chanspec & CR_ALT_FILTER) - priv(dev)->adc_control1_bits |= ADC_DITHER_BIT; + devpriv->adc_control1_bits |= ADC_DITHER_BIT; else - priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT; - writew(priv(dev)->adc_control1_bits, - priv(dev)->main_iobase + ADC_CONTROL1_REG); + 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(dev)->layout != LAYOUT_4020) { + if (thisboard->layout != LAYOUT_4020) { /* use internal queue */ - priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + 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; DEBUG_PRINT("reading calibration source\n"); - if (board(dev)->layout == LAYOUT_60XX) + if (thisboard->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 */ + /* select internal reference source to connect + * to channel 0 */ writew(cal_en_bit | - adc_src_bits(priv(dev)->calibration_source), - priv(dev)->main_iobase + CALIBRATION_REG); + adc_src_bits(devpriv->calibration_source), + devpriv->main_iobase + CALIBRATION_REG); } else { - /* make sure internal calibration source is turned off */ - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + /* make sure internal calibration source + * is turned off */ + writew(0, devpriv->main_iobase + CALIBRATION_REG); } /* load internal queue */ bits = 0; @@ -1916,56 +1803,56 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, bits |= adc_chan_bits(channel); /* set stop channel */ writew(adc_chan_bits(channel), - priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG); + devpriv->main_iobase + ADC_QUEUE_HIGH_REG); /* set start channel, and rest of settings */ - writew(bits, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG); + writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } else { - uint8_t old_cal_range_bits = priv(dev)->i2c_cal_range_bits; + uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits; - priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; + devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; if (insn->chanspec & CR_ALT_SOURCE) { DEBUG_PRINT("reading calibration source\n"); - priv(dev)->i2c_cal_range_bits |= - adc_src_4020_bits(priv(dev)->calibration_source); + devpriv->i2c_cal_range_bits |= + adc_src_4020_bits(devpriv->calibration_source); } else { /* select BNC inputs */ - priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4); + devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4); } /* select range */ if (range == 0) - priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel); + devpriv->i2c_cal_range_bits |= attenuate_bit(channel); else - priv(dev)->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 != priv(dev)->i2c_cal_range_bits) { - uint8_t i2c_data = priv(dev)->i2c_cal_range_bits; + 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) { + uint8_t 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, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); - writew(2, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); + /* 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, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG); + 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)), - priv(dev)->main_iobase + ADC_CONVERT_REG); + devpriv->main_iobase + ADC_CONVERT_REG); /* wait for data */ for (i = 0; i < timeout; i++) { - bits = readw(priv(dev)->main_iobase + HW_STATUS_REG); + bits = readw(devpriv->main_iobase + HW_STATUS_REG); DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits)); - if (board(dev)->layout == LAYOUT_4020) { - if (readw(priv(dev)->main_iobase + + if (thisboard->layout == LAYOUT_4020) { + if (readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG)) break; } else { @@ -1977,16 +1864,14 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, DEBUG_PRINT(" looped %i times waiting for data\n", i); if (i == timeout) { comedi_error(dev, " analog input read insn timed out"); - printk(" status 0x%x\n", bits); + dev_info(dev->class_dev, "status 0x%x\n", bits); return -ETIME; } - if (board(dev)->layout == LAYOUT_4020) - data[n] = - readl(priv(dev)->dio_counter_iobase + - ADC_FIFO_REG) & 0xffff; + if (thisboard->layout == LAYOUT_4020) + data[n] = readl(devpriv->dio_counter_iobase + + ADC_FIFO_REG) & 0xffff; else - data[n] = - readw(priv(dev)->main_iobase + PIPE1_READ_REG); + data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG); } return n; @@ -1995,10 +1880,12 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int ai_config_calibration_source(struct comedi_device *dev, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; unsigned int source = data[1]; int num_calibration_sources; - if (board(dev)->layout == LAYOUT_60XX) + if (thisboard->layout == LAYOUT_60XX) num_calibration_sources = 16; else num_calibration_sources = 8; @@ -2009,23 +1896,24 @@ static int ai_config_calibration_source(struct comedi_device *dev, } DEBUG_PRINT("setting calibration source to %i\n", source); - priv(dev)->calibration_source = source; + devpriv->calibration_source = source; return 2; } static int ai_config_block_size(struct comedi_device *dev, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); int fifo_size; - const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; + const struct hw_fifo_info *const fifo = thisboard->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; + fifo_size = requested_block_size * fifo->num_segments / + bytes_in_sample; retval = set_ai_fifo_size(dev, fifo_size); if (retval < 0) @@ -2043,6 +1931,7 @@ static int ai_config_block_size(struct comedi_device *dev, unsigned int *data) 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; @@ -2053,8 +1942,8 @@ static int ai_config_master_clock_4020(struct comedi_device *dev, switch (data[1]) { case COMEDI_EV_SCAN_BEGIN: - priv(dev)->ext_clock.divisor = divisor; - priv(dev)->ext_clock.chanspec = data[2]; + devpriv->ext_clock.divisor = divisor; + devpriv->ext_clock.chanspec = data[2]; break; default: return -EINVAL; @@ -2069,8 +1958,9 @@ static int ai_config_master_clock_4020(struct comedi_device *dev, /* XXX could add support for 60xx series */ static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); - switch (board(dev)->layout) { + switch (thisboard->layout) { case LAYOUT_4020: return ai_config_master_clock_4020(dev, data); break; @@ -2104,9 +1994,84 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 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 & TRIG_ROUND_MASK) { + case TRIG_ROUND_UP: + divisor = (ns + TIMER_BASE - 1) / TIMER_BASE; + break; + case TRIG_ROUND_DOWN: + divisor = ns / TIMER_BASE; + break; + case TRIG_ROUND_NEAREST: + default: + divisor = (ns + TIMER_BASE / 2) / 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 *thisboard = comedi_board(dev); + unsigned int convert_divisor = 0, 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 (thisboard->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) { + /* XXX check for integer overflows */ + 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; + } + + return; +} + static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); int err = 0; unsigned int tmp_arg, tmp_arg2; int i; @@ -2118,22 +2083,21 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); triggers = TRIG_TIMER; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) triggers |= TRIG_OTHER; else triggers |= TRIG_FOLLOW; err |= cfc_check_trigger_src(&cmd->scan_begin_src, triggers); triggers = TRIG_TIMER; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) triggers |= TRIG_NOW; else triggers |= TRIG_EXT; err |= cfc_check_trigger_src(&cmd->convert_src, triggers); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, - TRIG_COUNT | TRIG_EXT | TRIG_NONE); + TRIG_COUNT | TRIG_EXT | TRIG_NONE); if (err) return 1; @@ -2156,55 +2120,34 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->convert_src == TRIG_TIMER) { - if (board(dev)->layout == LAYOUT_4020) { - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } + if (thisboard->layout == LAYOUT_4020) { + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } else { - if (cmd->convert_arg < board(dev)->ai_speed) { - cmd->convert_arg = board(dev)->ai_speed; - err++; - } - if (cmd->scan_begin_src == TRIG_TIMER) { - /* if scans are timed faster than conversion rate allows */ - if (cmd->convert_arg * cmd->chanlist_len > - cmd->scan_begin_arg) { - cmd->scan_begin_arg = - cmd->convert_arg * - cmd->chanlist_len; - err++; - } - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + /* if scans are timed faster than conversion rate allows */ + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min( + &cmd->scan_begin_arg, + cmd->convert_arg * + cmd->chanlist_len); } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_EXT: break; case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; @@ -2240,7 +2183,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } } /* check 4020 chanlist */ - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { unsigned int first_channel = CR_CHAN(cmd->chanlist[0]); for (i = 1; i < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i]) != @@ -2279,89 +2222,37 @@ static int use_hw_sample_counter(struct comedi_cmd *cmd) static void setup_sample_counters(struct comedi_device *dev, struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; + if (cmd->stop_src == TRIG_COUNT) { /* set software count */ - priv(dev)->ai_count = cmd->stop_arg * cmd->chanlist_len; + devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len; } /* load hardware conversion counter */ if (use_hw_sample_counter(cmd)) { writew(cmd->stop_arg & 0xffff, - priv(dev)->main_iobase + ADC_COUNT_LOWER_REG); + devpriv->main_iobase + ADC_COUNT_LOWER_REG); writew((cmd->stop_arg >> 16) & 0xff, - priv(dev)->main_iobase + ADC_COUNT_UPPER_REG); + devpriv->main_iobase + ADC_COUNT_UPPER_REG); } else { - writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG); + writew(1, devpriv->main_iobase + ADC_COUNT_LOWER_REG); } } static inline unsigned int dma_transfer_size(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; unsigned int num_samples; - num_samples = - priv(dev)->ai_fifo_segment_length * - board(dev)->ai_fifo->sample_packing_ratio; + num_samples = devpriv->ai_fifo_segment_length * + thisboard->ai_fifo->sample_packing_ratio; if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t)) num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t); return num_samples; } -static void disable_ai_pacing(struct comedi_device *dev) -{ - unsigned long flags; - - disable_ai_interrupts(dev); - - spin_lock_irqsave(&dev->spinlock, flags); - priv(dev)->adc_control1_bits &= ~ADC_SW_GATE_BIT; - writew(priv(dev)->adc_control1_bits, - priv(dev)->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, - priv(dev)->main_iobase + ADC_CONTROL0_REG); -} - -static void disable_ai_interrupts(struct comedi_device *dev) -{ - unsigned long flags; - - spin_lock_irqsave(&dev->spinlock, flags); - priv(dev)->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(priv(dev)->intr_enable_bits, - priv(dev)->main_iobase + INTR_ENABLE_REG); - spin_unlock_irqrestore(&dev->spinlock, flags); - - DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits); -} - -static void enable_ai_interrupts(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - uint32_t 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 TRIG_WAKE_EOS flag is set. */ - if (cmd->flags & TRIG_WAKE_EOS) { - /* 4020 doesn't support pio transfers except for fifo dregs */ - if (board(dev)->layout != LAYOUT_4020) - bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT; - } - spin_lock_irqsave(&dev->spinlock, flags); - priv(dev)->intr_enable_bits |= bits; - writew(priv(dev)->intr_enable_bits, - priv(dev)->main_iobase + INTR_ENABLE_REG); - DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits); - spin_unlock_irqrestore(&dev->spinlock, flags); -} - static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev, const struct comedi_cmd *cmd) { @@ -2373,12 +2264,13 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, struct comedi_cmd *cmd) { uint32_t 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; + (cmd->convert_arg * (cmd->chanlist_len - 1))) / + TIMER_BASE; break; case TRIG_FOLLOW: count = cmd->convert_arg / TIMER_BASE; @@ -2393,6 +2285,7 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, static uint32_t 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) { @@ -2400,7 +2293,7 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev, divisor = cmd->scan_begin_arg / TIMER_BASE; break; case TRIG_OTHER: - divisor = priv(dev)->ext_clock.divisor; + divisor = devpriv->ext_clock.divisor; break; default: /* should never happen */ comedi_error(dev, "bug! failed to set ai pacing!"); @@ -2415,26 +2308,30 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev, 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 */ - priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK; + devpriv->hw_config_bits &= ~MASTER_CLOCK_4020_MASK; if (cmd->scan_begin_src == TRIG_OTHER) { - int chanspec = priv(dev)->ext_clock.chanspec; + int chanspec = devpriv->ext_clock.chanspec; if (CR_CHAN(chanspec)) - priv(dev)->hw_config_bits |= BNC_CLOCK_4020_BITS; + devpriv->hw_config_bits |= BNC_CLOCK_4020_BITS; else - priv(dev)->hw_config_bits |= EXT_CLOCK_4020_BITS; + devpriv->hw_config_bits |= EXT_CLOCK_4020_BITS; } else { - priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS; + devpriv->hw_config_bits |= INTERNAL_CLOCK_4020_BITS; } - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + 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) { - switch (board(dev)->layout) { + const struct pcidas64_board *thisboard = comedi_board(dev); + + switch (thisboard->layout) { case LAYOUT_4020: select_master_clock_4020(dev, cmd); break; @@ -2446,6 +2343,7 @@ static void select_master_clock(struct comedi_device *dev, 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 */ @@ -2453,23 +2351,25 @@ static inline void dma_start_sync(struct comedi_device *dev, if (channel) writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + devpriv->plx9080_iobase + PLX_DMA1_CS_REG); else writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); } static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; uint32_t convert_counter = 0, scan_counter = 0; check_adc_timing(dev, cmd); select_master_clock(dev, cmd); - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { convert_counter = ai_convert_counter_4020(dev, cmd); } else { convert_counter = ai_convert_counter_6xxx(dev, cmd); @@ -2478,23 +2378,24 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) /* load lower 16 bits of convert interval */ writew(convert_counter & 0xffff, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); DEBUG_PRINT("convert counter 0x%x\n", convert_counter); /* load upper 8 bits of convert interval */ writew((convert_counter >> 16) & 0xff, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); /* load lower 16 bits of scan delay */ writew(scan_counter & 0xffff, - priv(dev)->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG); + devpriv->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG); /* load upper 8 bits of scan delay */ writew((scan_counter >> 16) & 0xff, - priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG); + devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG); DEBUG_PRINT("scan counter 0x%x\n", scan_counter); } 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) @@ -2511,14 +2412,16 @@ static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; unsigned short bits; int i; - if (board(dev)->layout != LAYOUT_4020) { + if (thisboard->layout != LAYOUT_4020) { if (use_internal_queue_6xxx(cmd)) { - priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + 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])); @@ -2534,30 +2437,30 @@ static int setup_channel_queue(struct comedi_device *dev, /* set stop channel */ writew(adc_chan_bits (CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])), - priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG); + devpriv->main_iobase + ADC_QUEUE_HIGH_REG); /* set start channel, and rest of settings */ writew(bits, - priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG); + 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; } - priv(dev)->hw_config_bits |= EXT_QUEUE_BIT; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + 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, - priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG); + devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); /* clear queue pointer */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); /* load external queue */ for (i = 0; i < cmd->chanlist_len; i++) { bits = 0; /* set channel */ - bits |= - adc_chan_bits(CR_CHAN(cmd->chanlist[i])); + bits |= adc_chan_bits(CR_CHAN(cmd-> + chanlist[i])); /* set gain */ bits |= ai_range_bits_6xxx(dev, CR_RANGE(cmd-> @@ -2573,42 +2476,42 @@ static int setup_channel_queue(struct comedi_device *dev, /* mark end of queue */ if (i == cmd->chanlist_len - 1) bits |= QUEUE_EOSCAN_BIT | - QUEUE_EOSEQ_BIT; + QUEUE_EOSEQ_BIT; writew(bits, - priv(dev)->main_iobase + + devpriv->main_iobase + ADC_QUEUE_FIFO_REG); - DEBUG_PRINT - ("wrote 0x%x to external channel queue\n", - bits); + DEBUG_PRINT( + "wrote 0x%x to external channel queue\n", + bits); } /* doing a queue clear is not specified in board docs, * but required for reliable operation */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); /* prime queue holding register */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } } else { - unsigned short old_cal_range_bits = - priv(dev)->i2c_cal_range_bits; + unsigned short old_cal_range_bits = devpriv->i2c_cal_range_bits; - priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; + devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; /* select BNC inputs */ - priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4); + 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) - priv(dev)->i2c_cal_range_bits |= - attenuate_bit(channel); + devpriv->i2c_cal_range_bits |= + attenuate_bit(channel); else - priv(dev)->i2c_cal_range_bits &= - ~attenuate_bit(channel); + 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 != priv(dev)->i2c_cal_range_bits) { - uint8_t i2c_data = priv(dev)->i2c_cal_range_bits; + /* update calibration/range i2c register only if necessary, + * as it is very slow */ + if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { + uint8_t i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); } @@ -2620,6 +2523,8 @@ 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 @@ -2627,25 +2532,27 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev, * block. Initializing them to zero seems to fix the problem. */ if (dma_channel) { writel(0, - priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG); writel(0, - priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG); writel(descriptor_bits, - priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG); + devpriv->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG); } else { writel(0, - priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); writel(0, - priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); writel(descriptor_bits, - priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); } } static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; uint32_t bits; @@ -2661,7 +2568,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return retval; /* make sure internal calibration source is turned off */ - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + writew(0, devpriv->main_iobase + CALIBRATION_REG); set_ai_pacing(dev, cmd); @@ -2671,50 +2578,51 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) spin_lock_irqsave(&dev->spinlock, flags); /* set mode, allow conversions through software gate */ - priv(dev)->adc_control1_bits |= ADC_SW_GATE_BIT; - priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT; - if (board(dev)->layout != LAYOUT_4020) { - priv(dev)->adc_control1_bits &= ~ADC_MODE_MASK; + devpriv->adc_control1_bits |= ADC_SW_GATE_BIT; + devpriv->adc_control1_bits &= ~ADC_DITHER_BIT; + if (thisboard->layout != LAYOUT_4020) { + devpriv->adc_control1_bits &= ~ADC_MODE_MASK; if (cmd->convert_src == TRIG_EXT) - priv(dev)->adc_control1_bits |= adc_mode_bits(13); /* good old mode 13 */ + /* good old mode 13 */ + devpriv->adc_control1_bits |= adc_mode_bits(13); else - priv(dev)->adc_control1_bits |= adc_mode_bits(8); /* mode 8. What else could you need? */ + /* mode 8. What else could you need? */ + devpriv->adc_control1_bits |= adc_mode_bits(8); } else { - priv(dev)->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK; + devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK; if (cmd->chanlist_len == 4) - priv(dev)->adc_control1_bits |= FOUR_CHANNEL_4020_BITS; + devpriv->adc_control1_bits |= FOUR_CHANNEL_4020_BITS; else if (cmd->chanlist_len == 2) - priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS; - priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK; - priv(dev)->adc_control1_bits |= - adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0])); - priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK; - priv(dev)->adc_control1_bits |= - adc_hi_chan_4020_bits(CR_CHAN - (cmd-> - chanlist[cmd->chanlist_len - 1])); + 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(priv(dev)->adc_control1_bits, - priv(dev)->main_iobase + ADC_CONTROL1_REG); - DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits); + writew(devpriv->adc_control1_bits, + devpriv->main_iobase + ADC_CONTROL1_REG); + DEBUG_PRINT("control1 bits 0x%x\n", devpriv->adc_control1_bits); spin_unlock_irqrestore(&dev->spinlock, flags); /* clear adc buffer */ - writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG); if ((cmd->flags & TRIG_WAKE_EOS) == 0 || - board(dev)->layout == LAYOUT_4020) { - priv(dev)->ai_dma_index = 0; + thisboard->layout == LAYOUT_4020) { + devpriv->ai_dma_index = 0; /* set dma transfer size */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) - priv(dev)->ai_dma_desc[i].transfer_size = - cpu_to_le32(dma_transfer_size(dev) * - sizeof(uint16_t)); + for (i = 0; i < ai_dma_ring_count(thisboard); i++) + devpriv->ai_dma_desc[i].transfer_size = + cpu_to_le32(dma_transfer_size(dev) * + sizeof(uint16_t)); /* give location of first dma descriptor */ load_first_dma_descriptor(dev, 1, - priv(dev)->ai_dma_desc_bus_addr | + devpriv->ai_dma_desc_bus_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI); @@ -2722,14 +2630,14 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) dma_start_sync(dev, 1); } - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->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, priv(dev)->main_iobase + DAQ_ATRIG_LOW_4020_REG); + writew(bits, devpriv->main_iobase + DAQ_ATRIG_LOW_4020_REG); } spin_lock_irqsave(&dev->spinlock, flags); @@ -2747,16 +2655,16 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) bits |= ADC_START_TRIG_SOFT_BITS; if (use_hw_sample_counter(cmd)) bits |= ADC_SAMPLE_COUNTER_EN_BIT; - writew(bits, priv(dev)->main_iobase + ADC_CONTROL0_REG); + writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG); DEBUG_PRINT("control0 bits 0x%x\n", bits); - priv(dev)->ai_cmd_running = 1; + devpriv->ai_cmd_running = 1; spin_unlock_irqrestore(&dev->spinlock, flags); /* start acquisition */ if (cmd->start_src == TRIG_NOW) { - writew(0, priv(dev)->main_iobase + ADC_START_REG); + writew(0, devpriv->main_iobase + ADC_START_REG); DEBUG_PRINT("soft trig\n"); } @@ -2766,6 +2674,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* 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; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -2776,18 +2685,19 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) do { /* get least significant 15 bits */ - read_index = - readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; - write_index = - readw(priv(dev)->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 + 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(priv(dev)->main_iobase + PREPOST_REG); + 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 */ + /* 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); @@ -2797,17 +2707,17 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) if (read_segment != write_segment) num_samples = - priv(dev)->ai_fifo_segment_length - read_index; + devpriv->ai_fifo_segment_length - read_index; else num_samples = write_index - read_index; if (cmd->stop_src == TRIG_COUNT) { - if (priv(dev)->ai_count == 0) + if (devpriv->ai_count == 0) break; - if (num_samples > priv(dev)->ai_count) - num_samples = priv(dev)->ai_count; + if (num_samples > devpriv->ai_count) + num_samples = devpriv->ai_count; - priv(dev)->ai_count -= num_samples; + devpriv->ai_count -= num_samples; } if (num_samples < 0) { @@ -2820,20 +2730,21 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) for (i = 0; i < num_samples; i++) { cfc_write_to_buffer(s, - readw(priv(dev)->main_iobase + + readw(devpriv->main_iobase + ADC_FIFO_REG)); } } 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). +/* 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; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -2841,33 +2752,35 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) unsigned int max_transfer = 100000; uint32_t fifo_data; int write_code = - readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; int read_code = - readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; if (cmd->stop_src == TRIG_COUNT) { - if (max_transfer > priv(dev)->ai_count) - max_transfer = priv(dev)->ai_count; + if (max_transfer > devpriv->ai_count) + max_transfer = devpriv->ai_count; } for (i = 0; read_code != write_code && i < max_transfer;) { - fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG); + fifo_data = readl(devpriv->dio_counter_iobase + ADC_FIFO_REG); cfc_write_to_buffer(s, fifo_data & 0xffff); i++; if (i < max_transfer) { cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff); i++; } - read_code = - readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & + 0x7fff; } - priv(dev)->ai_count -= i; + devpriv->ai_count -= i; } /* empty fifo */ static void pio_drain_ai_fifo(struct comedi_device *dev) { - if (board(dev)->layout == LAYOUT_4020) + const struct pcidas64_board *thisboard = comedi_board(dev); + + if (thisboard->layout == LAYOUT_4020) pio_drain_ai_fifo_32(dev); else pio_drain_ai_fifo_16(dev); @@ -2875,6 +2788,8 @@ static void pio_drain_ai_fifo(struct comedi_device *dev) static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = dev->read_subdev->async; uint32_t next_transfer_addr; int j; @@ -2883,46 +2798,47 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) if (channel) pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; else pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; /* loop until we have read all the full buffers */ for (j = 0, next_transfer_addr = readl(pci_addr_reg); (next_transfer_addr < - priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] - || next_transfer_addr >= - priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] + - DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev)); j++) { + 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(thisboard); j++) { /* transfer data from dma buffer to comedi buffer */ num_samples = dma_transfer_size(dev); if (async->cmd.stop_src == TRIG_COUNT) { - if (num_samples > priv(dev)->ai_count) - num_samples = priv(dev)->ai_count; - priv(dev)->ai_count -= num_samples; + if (num_samples > devpriv->ai_count) + num_samples = devpriv->ai_count; + devpriv->ai_count -= num_samples; } cfc_write_array_to_buffer(dev->read_subdev, - priv(dev)->ai_buffer[priv(dev)-> - ai_dma_index], + devpriv->ai_buffer[devpriv-> + ai_dma_index], num_samples * sizeof(uint16_t)); - priv(dev)->ai_dma_index = - (priv(dev)->ai_dma_index + - 1) % ai_dma_ring_count(board(dev)); + devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % + ai_dma_ring_count(thisboard); DEBUG_PRINT("next buffer addr 0x%lx\n", - (unsigned long)priv(dev)-> - ai_buffer_bus_addr[priv(dev)->ai_dma_index]); + (unsigned long)devpriv-> + ai_buffer_bus_addr[devpriv->ai_dma_index]); DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } - /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last - * unused buffer) */ + /* 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 *thisboard = comedi_board(dev); + 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; @@ -2936,10 +2852,10 @@ static void handle_ai_interrupt(struct comedi_device *dev, } /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + dma1_status = readb(devpriv->plx9080_iobase + PLX_DMA1_CS_REG); if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + devpriv->plx9080_iobase + PLX_DMA1_CS_REG); DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); if (dma1_status & PLX_DMA_EN_BIT) @@ -2956,17 +2872,17 @@ static void handle_ai_interrupt(struct comedi_device *dev, if ((status & ADC_DONE_BIT) || ((cmd->flags & TRIG_WAKE_EOS) && (status & ADC_INTR_PENDING_BIT) && - (board(dev)->layout != LAYOUT_4020))) { + (thisboard->layout != LAYOUT_4020))) { DEBUG_PRINT("pio fifo drain\n"); spin_lock_irqsave(&dev->spinlock, flags); - if (priv(dev)->ai_cmd_running) { + 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 && (int)priv(dev)->ai_count <= 0) || + if ((cmd->stop_src == TRIG_COUNT && (int)devpriv->ai_count <= 0) || (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) { async->events |= COMEDI_CB_EOA; } @@ -2976,29 +2892,31 @@ static void handle_ai_interrupt(struct comedi_device *dev, static inline unsigned int prev_ao_dma_index(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned int buffer_index; - if (priv(dev)->ao_dma_index == 0) + if (devpriv->ao_dma_index == 0) buffer_index = AO_DMA_RING_COUNT - 1; else - buffer_index = priv(dev)->ao_dma_index - 1; + 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(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + dma_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if ((dma_status & PLX_DMA_DONE_BIT) == 0) return 0; transfer_address = - readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); - if (transfer_address != priv(dev)->ao_buffer_bus_addr[buffer_index]) + readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index]) return 0; return 1; @@ -3007,10 +2925,12 @@ static int last_ao_dma_load_completed(struct comedi_device *dev) static int ao_stopped_by_error(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; + if (cmd->stop_src == TRIG_NONE) return 1; if (cmd->stop_src == TRIG_COUNT) { - if (priv(dev)->ao_count) + if (devpriv->ao_count) return 1; if (last_ao_dma_load_completed(dev) == 0) return 1; @@ -3032,10 +2952,11 @@ static inline int ao_dma_needs_restart(struct comedi_device *dev, static void restart_ao_dma(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned int dma_desc_bits; dma_desc_bits = - readl(priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT; DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits); load_first_dma_descriptor(dev, 0, dma_desc_bits); @@ -3043,9 +2964,81 @@ static void restart_ao_dma(struct comedi_device *dev) dma_start_sync(dev, 0); } +static unsigned int load_ao_dma_buffer(struct comedi_device *dev, + const struct comedi_cmd *cmd) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned int num_bytes, buffer_index, prev_buffer_index; + unsigned int next_bits; + + buffer_index = devpriv->ao_dma_index; + prev_buffer_index = prev_ao_dma_index(dev); + + DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index, + (unsigned long long)devpriv->ao_buffer_bus_addr[ + buffer_index]); + + num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); + if (num_bytes > DMA_BUFFER_SIZE) + num_bytes = DMA_BUFFER_SIZE; + if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) + num_bytes = devpriv->ao_count; + num_bytes -= num_bytes % bytes_in_sample; + + if (num_bytes == 0) + return 0; + + DEBUG_PRINT("loading %i bytes\n", num_bytes); + + num_bytes = cfc_read_array_from_buffer(dev->write_subdev, + devpriv-> + ao_buffer[buffer_index], + num_bytes); + devpriv->ao_dma_desc[buffer_index].transfer_size = + cpu_to_le32(num_bytes); + /* set end of chain bit so we catch underruns */ + next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); + next_bits |= PLX_END_OF_CHAIN_BIT; + 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_END_OF_CHAIN_BIT; + devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); + + devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; + devpriv->ao_count -= num_bytes; + + return num_bytes; +} + +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_DMA0_PCI_ADDRESS_REG; + 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; @@ -3060,15 +3053,15 @@ static void handle_ao_interrupt(struct comedi_device *dev, /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ - if ((dma0_status & PLX_DMA_EN_BIT) - && !(dma0_status & PLX_DMA_DONE_BIT)) + if ((dma0_status & PLX_DMA_EN_BIT) && + !(dma0_status & PLX_DMA_DONE_BIT)) writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); else writeb(PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) { @@ -3078,18 +3071,19 @@ static void handle_ao_interrupt(struct comedi_device *dev, restart_ao_dma(dev); } DEBUG_PRINT(" cleared dma ch0 interrupt\n"); - } else + } else { spin_unlock_irqrestore(&dev->spinlock, flags); + } if ((status & DAC_DONE_BIT)) { async->events |= COMEDI_CB_EOA; if (ao_stopped_by_error(dev, cmd)) async->events |= COMEDI_CB_ERROR; DEBUG_PRINT("plx dma0 desc reg 0x%x\n", - readl(priv(dev)->plx9080_iobase + + readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG)); DEBUG_PRINT("plx dma0 address reg 0x%x\n", - readl(priv(dev)->plx9080_iobase + + readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG)); } cfc_handle_events(dev, s); @@ -3098,22 +3092,21 @@ static void handle_ao_interrupt(struct comedi_device *dev, static irqreturn_t handle_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct pcidas64_private *devpriv = dev->private; unsigned short status; uint32_t plx_status; uint32_t plx_bits; - plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG); - status = readw(priv(dev)->main_iobase + HW_STATUS_REG); + plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); + status = readw(devpriv->main_iobase + HW_STATUS_REG); - DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status); - DEBUG_PRINT("plx status 0x%x\n", plx_status); + DEBUG_PRINT("hw status 0x%x, plx status 0x%x\n", status, plx_status); /* an interrupt before all the postconfig stuff gets done could * cause a NULL dereference if we continue through the * interrupt handler */ if (dev->attached == 0) { - DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring", - status); + DEBUG_PRINT("premature interrupt, ignoring\n"); return IRQ_HANDLED; } handle_ai_interrupt(dev, status, plx_status); @@ -3121,8 +3114,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) /* clear possible plx9080 interrupt sources */ if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ - plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); - writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); + plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); + writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } @@ -3131,28 +3124,17 @@ static irqreturn_t handle_interrupt(int irq, void *d) return IRQ_HANDLED; } -static void abort_dma(struct comedi_device *dev, unsigned int channel) -{ - unsigned long flags; - - /* spinlock for plx dma control/status reg */ - spin_lock_irqsave(&dev->spinlock, flags); - - plx9080_abort_dma(priv(dev)->plx9080_iobase, channel); - - spin_unlock_irqrestore(&dev->spinlock, flags); -} - 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 (priv(dev)->ai_cmd_running == 0) { + if (devpriv->ai_cmd_running == 0) { spin_unlock_irqrestore(&dev->spinlock, flags); return 0; } - priv(dev)->ai_cmd_running = 0; + devpriv->ai_cmd_running = 0; spin_unlock_irqrestore(&dev->spinlock, flags); disable_ai_pacing(dev); @@ -3166,29 +3148,31 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int range = CR_RANGE(insn->chanspec); /* do some initializing */ - writew(0, priv(dev)->main_iobase + DAC_CONTROL0_REG); + writew(0, devpriv->main_iobase + DAC_CONTROL0_REG); /* set range */ - set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, chan, range); - writew(priv(dev)->dac_control1_bits, - priv(dev)->main_iobase + DAC_CONTROL1_REG); + set_dac_range_bits(dev, &devpriv->dac_control1_bits, chan, range); + writew(devpriv->dac_control1_bits, + devpriv->main_iobase + DAC_CONTROL1_REG); /* write to channel */ - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { writew(data[0] & 0xff, - priv(dev)->main_iobase + dac_lsb_4020_reg(chan)); + devpriv->main_iobase + dac_lsb_4020_reg(chan)); writew((data[0] >> 8) & 0xf, - priv(dev)->main_iobase + dac_msb_4020_reg(chan)); + devpriv->main_iobase + dac_msb_4020_reg(chan)); } else { - writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan)); + writew(data[0], devpriv->main_iobase + dac_convert_reg(chan)); } /* remember output value */ - priv(dev)->ao_value[chan] = data[0]; + devpriv->ao_value[chan] = data[0]; return 1; } @@ -3197,7 +3181,9 @@ static int ao_readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - data[0] = priv(dev)->ao_value[CR_CHAN(insn->chanspec)]; + struct pcidas64_private *devpriv = dev->private; + + data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; return 1; } @@ -3205,8 +3191,9 @@ static int ao_readback_insn(struct comedi_device *dev, 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; + WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT; if (cmd->start_src == TRIG_EXT) { bits |= WAVEFORM_TRIG_EXT_BITS; @@ -3220,12 +3207,13 @@ static void set_dac_control0_reg(struct comedi_device *dev, if (cmd->scan_begin_arg & CR_INVERT) bits |= DAC_EXT_UPDATE_FALLING_BIT; } - writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG); + 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++) { @@ -3233,17 +3221,18 @@ static void set_dac_control1_reg(struct comedi_device *dev, channel = CR_CHAN(cmd->chanlist[i]); range = CR_RANGE(cmd->chanlist[i]); - set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel, + set_dac_range_bits(dev, &devpriv->dac_control1_bits, channel, range); } - priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT; - writew(priv(dev)->dac_control1_bits, - priv(dev)->main_iobase + DAC_CONTROL1_REG); + 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; uint16_t bits; unsigned int first_channel, last_channel; @@ -3254,12 +3243,18 @@ static void set_dac_select_reg(struct comedi_device *dev, bits = (first_channel & 0x7) | (last_channel & 0x7) << 3; - writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG); + 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) @@ -3271,102 +3266,35 @@ static void set_dac_interval_regs(struct comedi_device *dev, divisor = max_counter_value; } writew(divisor & 0xffff, - priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG); + devpriv->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG); writew((divisor >> 16) & 0xff, - priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG); -} - -static unsigned int load_ao_dma_buffer(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - unsigned int num_bytes, buffer_index, prev_buffer_index; - unsigned int next_bits; - - buffer_index = priv(dev)->ao_dma_index; - prev_buffer_index = prev_ao_dma_index(dev); - - DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index, - priv(dev)->ao_buffer_bus_addr[buffer_index]); - - num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); - if (num_bytes > DMA_BUFFER_SIZE) - num_bytes = DMA_BUFFER_SIZE; - if (cmd->stop_src == TRIG_COUNT && num_bytes > priv(dev)->ao_count) - num_bytes = priv(dev)->ao_count; - num_bytes -= num_bytes % bytes_in_sample; - - if (num_bytes == 0) - return 0; - - DEBUG_PRINT("loading %i bytes\n", num_bytes); - - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - priv(dev)-> - ao_buffer[buffer_index], - num_bytes); - priv(dev)->ao_dma_desc[buffer_index].transfer_size = - cpu_to_le32(num_bytes); - /* set end of chain bit so we catch underruns */ - next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[buffer_index].next); - next_bits |= PLX_END_OF_CHAIN_BIT; - priv(dev)->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(priv(dev)->ao_dma_desc[prev_buffer_index].next); - next_bits &= ~PLX_END_OF_CHAIN_BIT; - priv(dev)->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); - - priv(dev)->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; - priv(dev)->ao_count -= num_bytes; - - return num_bytes; -} - -static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) -{ - unsigned int num_bytes; - unsigned int next_transfer_addr; - void __iomem *pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; - unsigned int buffer_index; - - do { - buffer_index = priv(dev)->ao_dma_index; - /* don't overwrite data that hasn't been transferred yet */ - next_transfer_addr = readl(pci_addr_reg); - if (next_transfer_addr >= - priv(dev)->ao_buffer_bus_addr[buffer_index] - && next_transfer_addr < - priv(dev)->ao_buffer_bus_addr[buffer_index] + - DMA_BUFFER_SIZE) - return; - num_bytes = load_ao_dma_buffer(dev, cmd); - } while (num_bytes >= DMA_BUFFER_SIZE); + 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; unsigned int num_bytes; int i; /* clear queue pointer too, since external queue has * weird interactions with ao fifo */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); - writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); + writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample; if (cmd->stop_src == TRIG_COUNT && - num_bytes / bytes_in_sample > priv(dev)->ao_count) - num_bytes = priv(dev)->ao_count * bytes_in_sample; + num_bytes / bytes_in_sample > devpriv->ao_count) + num_bytes = devpriv->ao_count * bytes_in_sample; num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - priv(dev)->ao_bounce_buffer, + devpriv->ao_bounce_buffer, num_bytes); for (i = 0; i < num_bytes / bytes_in_sample; i++) { - writew(priv(dev)->ao_bounce_buffer[i], - priv(dev)->main_iobase + DAC_FIFO_REG); + writew(devpriv->ao_bounce_buffer[i], + devpriv->main_iobase + DAC_FIFO_REG); } - priv(dev)->ao_count -= num_bytes / bytes_in_sample; - if (cmd->stop_src == TRIG_COUNT && priv(dev)->ao_count == 0) + devpriv->ao_count -= num_bytes / bytes_in_sample; + if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0) return 0; num_bytes = load_ao_dma_buffer(dev, cmd); if (num_bytes == 0) @@ -3381,43 +3309,21 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) static inline int external_ai_queue_in_use(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); + if (dev->read_subdev->busy) return 0; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) return 0; else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd)) return 0; return 1; } -static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) -{ - 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, priv(dev)->main_iobase + DAC_CONTROL0_REG); - - priv(dev)->ao_dma_index = 0; - priv(dev)->ao_count = cmd->stop_arg * cmd->chanlist_len; - - set_dac_select_reg(dev, cmd); - set_dac_interval_regs(dev, cmd); - load_first_dma_descriptor(dev, 0, priv(dev)->ao_dma_desc_bus_addr | - PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT); - - set_dac_control1_reg(dev, cmd); - s->async->inttrig = ao_inttrig; - - return 0; -} - 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; @@ -3431,16 +3337,43 @@ static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, set_dac_control0_reg(dev, cmd); if (cmd->start_src == TRIG_INT) - writew(0, priv(dev)->main_iobase + DAC_START_REG); + 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; + devpriv->ao_count = cmd->stop_arg * cmd->chanlist_len; + + 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_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT); + + set_dac_control1_reg(dev, cmd); + s->async->inttrig = ao_inttrig; + + return 0; +} + static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); int err = 0; unsigned int tmp_arg; int i; @@ -3449,7 +3382,7 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_EXT); + TRIG_TIMER | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); @@ -3473,29 +3406,21 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) { - cmd->scan_begin_arg = board(dev)->ao_scan_speed; - err++; - } - if (get_ao_divisor(cmd->scan_begin_arg, - cmd->flags) > max_counter_value) { - cmd->scan_begin_arg = - (max_counter_value + 2) * TIMER_BASE; - err++; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->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; } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (err) return 3; @@ -3504,8 +3429,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 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; + cmd->scan_begin_arg = get_divisor(cmd->scan_begin_arg, + cmd->flags) * TIMER_BASE; if (tmp_arg != cmd->scan_begin_arg) err++; } @@ -3533,7 +3458,9 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG); + struct pcidas64_private *devpriv = dev->private; + + writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG); abort_dma(dev, 0); return 0; } @@ -3564,9 +3491,10 @@ static int dio_callback_4020(int dir, int port, int data, unsigned long arg) static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int bits; - bits = readb(priv(dev)->dio_counter_iobase + DI_REG); + bits = readb(devpriv->dio_counter_iobase + DI_REG); bits &= 0xf; data[1] = bits; data[0] = 0; @@ -3577,13 +3505,15 @@ static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; + data[0] &= 0xf; /* zero bits we are going to change */ s->state &= ~data[0]; /* set new bits */ s->state |= data[0] & data[1]; - writeb(s->state, priv(dev)->dio_counter_iobase + DO_REG); + writeb(s->state, devpriv->dio_counter_iobase + DO_REG); data[1] = s->state; @@ -3594,6 +3524,7 @@ static int dio_60xx_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int mask; mask = 1 << CR_CHAN(insn->chanspec); @@ -3613,7 +3544,7 @@ static int dio_60xx_config_insn(struct comedi_device *dev, } writeb(s->io_bits, - priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG); + devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG); return 1; } @@ -3621,24 +3552,143 @@ static int dio_60xx_config_insn(struct comedi_device *dev, static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); writeb(s->state, - priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG); + devpriv->dio_counter_iobase + DIO_DATA_60XX_REG); } - data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG); + data[1] = readb(devpriv->dio_counter_iobase + 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, + uint8_t 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) { + comedi_error(dev, "illegal caldac channel"); + 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) +{ + uint8_t serial_bytes[3]; + uint8_t 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: + comedi_error(dev, "invalid caldac channel\n"); + return -1; + break; + } + 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) { - priv(dev)->caldac_state[channel] = value; + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + + devpriv->caldac_state[channel] = value; - switch (board(dev)->layout) { + switch (thisboard->layout) { case LAYOUT_60XX: case LAYOUT_64XX: caldac_8800_write(dev, channel, value); @@ -3655,11 +3705,12 @@ static int calib_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; int channel = CR_CHAN(insn->chanspec); /* return immediately if setting hasn't changed, since * programming these things is slow */ - if (priv(dev)->caldac_state[channel] == data[0]) + if (devpriv->caldac_state[channel] == data[0]) return 1; caldac_write(dev, channel, data[0]); @@ -3671,9 +3722,10 @@ static int calib_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int channel = CR_CHAN(insn->chanspec); - data[0] = priv(dev)->caldac_state[channel]; + data[0] = devpriv->caldac_state[channel]; return 1; } @@ -3681,16 +3733,17 @@ static int calib_read_insn(struct comedi_device *dev, 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; - priv(dev)->ad8402_state[channel] = value; + devpriv->ad8402_state[channel] = value; register_bits = SELECT_8402_64XX_BIT; udelay(ad8402_udelay); - writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { if (bitstream & bit) @@ -3698,14 +3751,14 @@ static void ad8402_write(struct comedi_device *dev, unsigned int channel, else register_bits &= ~SERIAL_DATA_IN_BIT; udelay(ad8402_udelay); - writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); udelay(ad8402_udelay); writew(register_bits | SERIAL_CLOCK_BIT, - priv(dev)->main_iobase + CALIBRATION_REG); + devpriv->main_iobase + CALIBRATION_REG); } udelay(ad8402_udelay); - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + writew(0, devpriv->main_iobase + CALIBRATION_REG); } /* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */ @@ -3713,14 +3766,15 @@ static int ad8402_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; int channel = CR_CHAN(insn->chanspec); /* return immediately if setting hasn't changed, since * programming these things is slow */ - if (priv(dev)->ad8402_state[channel] == data[0]) + if (devpriv->ad8402_state[channel] == data[0]) return 1; - priv(dev)->ad8402_state[channel] = data[0]; + devpriv->ad8402_state[channel] = data[0]; ad8402_write(dev, channel, data[0]); @@ -3731,62 +3785,64 @@ static int ad8402_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int channel = CR_CHAN(insn->chanspec); - data[0] = priv(dev)->ad8402_state[channel]; + data[0] = devpriv->ad8402_state[channel]; return 1; } static uint16_t read_eeprom(struct comedi_device *dev, uint8_t 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 = - priv(dev)->plx9080_iobase + PLX_CONTROL_REG; + devpriv->plx9080_iobase + PLX_CONTROL_REG; uint16_t value; static const int value_length = 16; static const int eeprom_udelay = 1; udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS; + devpriv->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS; /* make sure we don't send anything to the i2c bus on 4020 */ - priv(dev)->plx_control_bits |= CTL_USERO; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_USERO; + writel(devpriv->plx_control_bits, plx_control_addr); /* activate serial eeprom */ udelay(eeprom_udelay); - priv(dev)->plx_control_bits |= CTL_EE_CS; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_EE_CS; + 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) - priv(dev)->plx_control_bits |= CTL_EE_W; + devpriv->plx_control_bits |= CTL_EE_W; else - priv(dev)->plx_control_bits &= ~CTL_EE_W; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_W; + writel(devpriv->plx_control_bits, plx_control_addr); /* clock in bit */ udelay(eeprom_udelay); - priv(dev)->plx_control_bits |= CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_EE_CLK; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_CLK; + 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); - priv(dev)->plx_control_bits |= CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_EE_CLK; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_CLK; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(eeprom_udelay); if (readl(plx_control_addr) & CTL_EE_R) value |= bit; @@ -3794,8 +3850,8 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) /* deactivate eeprom serial input */ udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CS; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_CS; + writel(devpriv->plx_control_bits, plx_control_addr); return value; } @@ -3809,419 +3865,386 @@ static int eeprom_read_insn(struct comedi_device *dev, return 1; } -/* 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 +/* Allocate and initialize the subdevice structures. */ -static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) +static int setup_subdevices(struct comedi_device *dev) { - unsigned int convert_divisor = 0, 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; + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + struct comedi_subdevice *s; + void __iomem *dio_8255_iobase; + int i; + int ret; - if (cmd->convert_src == TRIG_TIMER) { - if (board(dev)->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; + ret = comedi_alloc_subdevices(dev, 10); + if (ret) + return ret; - if (cmd->scan_begin_src == TRIG_TIMER) { - scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags); - if (cmd->convert_src == TRIG_TIMER) { - /* XXX check for integer overflows */ - 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; + 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 (thisboard->layout == LAYOUT_60XX) + s->subdev_flags |= SDF_COMMON | SDF_DIFF; + else if (thisboard->layout == LAYOUT_64XX) + s->subdev_flags |= SDF_DIFF; + /* XXX Number of inputs in differential mode is ignored */ + s->n_chan = thisboard->ai_se_chans; + s->len_chanlist = 0x2000; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = thisboard->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 (thisboard->layout == LAYOUT_4020) { + uint8_t 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)); } - return; -} - -/* 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 & TRIG_ROUND_MASK) { - case TRIG_ROUND_UP: - divisor = (ns + TIMER_BASE - 1) / TIMER_BASE; - break; - case TRIG_ROUND_DOWN: - divisor = ns / TIMER_BASE; - break; - case TRIG_ROUND_NEAREST: - default: - divisor = (ns + TIMER_BASE / 2) / TIMER_BASE; - break; + /* analog output subdevice */ + s = &dev->subdevices[1]; + if (thisboard->ao_nchan) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | + SDF_GROUND | SDF_CMD_WRITE; + s->n_chan = thisboard->ao_nchan; + s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = thisboard->ao_range_table; + s->insn_read = ao_readback_insn; + s->insn_write = ao_winsn; + if (ao_cmd_is_supported(thisboard)) { + dev->write_subdev = s; + s->do_cmdtest = ao_cmdtest; + s->do_cmd = ao_cmd; + s->len_chanlist = thisboard->ao_nchan; + s->cancel = ao_cancel; + } + } else { + s->type = COMEDI_SUBD_UNUSED; } - return divisor; -} -static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags) -{ - return get_divisor(ns, flags) - 2; -} + /* digital input */ + s = &dev->subdevices[2]; + if (thisboard->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; -/* 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) -{ - unsigned int num_fifo_entries; - int retval; - const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; + /* digital output */ + if (thisboard->layout == LAYOUT_64XX) { + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = do_wbits; + } else + s->type = COMEDI_SUBD_UNUSED; - num_fifo_entries = num_samples / fifo->sample_packing_ratio; + /* 8255 */ + s = &dev->subdevices[4]; + if (thisboard->has_8255) { + if (thisboard->layout == LAYOUT_4020) { + dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG; + subdev_8255_init(dev, s, dio_callback_4020, + (unsigned long)dio_8255_iobase); + } else { + dio_8255_iobase = + devpriv->dio_counter_iobase + DIO_8255_OFFSET; + subdev_8255_init(dev, s, dio_callback, + (unsigned long)dio_8255_iobase); + } + } else + s->type = COMEDI_SUBD_UNUSED; - retval = set_ai_fifo_segment_length(dev, - num_fifo_entries / - fifo->num_segments); - if (retval < 0) - return retval; + /* 8 channel dio for 60xx */ + s = &dev->subdevices[5]; + if (thisboard->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; - num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; + /* caldac */ + s = &dev->subdevices[6]; + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 8; + if (thisboard->layout == LAYOUT_4020) + s->maxdata = 0xfff; + else + s->maxdata = 0xff; + s->insn_read = calib_read_insn; + s->insn_write = calib_write_insn; + for (i = 0; i < s->n_chan; i++) + caldac_write(dev, i, s->maxdata / 2); - DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); + /* 2 channel ad8402 potentiometer */ + s = &dev->subdevices[7]; + if (thisboard->layout == LAYOUT_64XX) { + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 2; + s->insn_read = ad8402_read_insn; + s->insn_write = ad8402_write_insn; + s->maxdata = 0xff; + for (i = 0; i < s->n_chan; i++) + ad8402_write(dev, i, s->maxdata / 2); + } else + s->type = COMEDI_SUBD_UNUSED; - return num_samples; -} + /* serial EEPROM, if present */ + s = &dev->subdevices[8]; + if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { + 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; -/* query length of fifo */ -static unsigned int ai_fifo_size(struct comedi_device *dev) -{ - return priv(dev)->ai_fifo_segment_length * - board(dev)->ai_fifo->num_segments * - board(dev)->ai_fifo->sample_packing_ratio; + /* user counter subd XXX */ + s = &dev->subdevices[9]; + s->type = COMEDI_SUBD_UNUSED; + + return 0; } -static int set_ai_fifo_segment_length(struct comedi_device *dev, - unsigned int num_entries) +static const struct pcidas64_board +*cb_pcidas64_find_pci_board(struct pci_dev *pcidev) { - static const int increment_size = 0x100; - const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; - unsigned int num_increments; - uint16_t 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 = (num_entries + increment_size / 2) / increment_size; - - bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask; - priv(dev)->fifo_size_bits &= ~fifo->fifo_size_reg_mask; - priv(dev)->fifo_size_bits |= bits; - writew(priv(dev)->fifo_size_bits, - priv(dev)->main_iobase + FIFO_SIZE_REG); - - priv(dev)->ai_fifo_segment_length = num_increments * increment_size; - - DEBUG_PRINT("set hardware fifo segment length to %i\n", - priv(dev)->ai_fifo_segment_length); + unsigned int i; - return priv(dev)->ai_fifo_segment_length; + for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) + if (pcidev->device == pcidas64_boards[i].device_id) + return &pcidas64_boards[i]; + return NULL; } -/* 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, - uint8_t value) +static int auto_attach(struct comedi_device *dev, + unsigned long context_unused) { - 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; + const struct pcidas64_board *thisboard; + struct pcidas64_private *devpriv; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + uint32_t local_range, local_decode; + int retval; - if (address >= num_caldac_channels) { - comedi_error(dev, "illegal caldac channel"); - 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, priv(dev)->main_iobase + CALIBRATION_REG); - register_bits |= SERIAL_CLOCK_BIT; - udelay(caldac_8800_udelay); - writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG); + dev->board_ptr = cb_pcidas64_find_pci_board(pcidev); + if (!dev->board_ptr) { + dev_err(dev->class_dev, + "cb_pcidas64: does not support pci %s\n", + pci_name(pcidev)); + return -EINVAL; } - udelay(caldac_8800_udelay); - writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG); - udelay(caldac_8800_udelay); - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); - udelay(caldac_8800_udelay); - return 0; -} + thisboard = comedi_board(dev); -/* 4020 caldacs */ -static int caldac_i2c_write(struct comedi_device *dev, - unsigned int caldac_channel, unsigned int value) -{ - uint8_t serial_bytes[3]; - uint8_t 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, - }; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; - 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: - comedi_error(dev, "invalid caldac channel\n"); - return -1; - break; + if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { + dev_warn(dev->class_dev, + "failed to enable PCI device and request regions\n"); + return -EIO; } - serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf); - serial_bytes[2] = value & 0xff; - i2c_write(dev, i2c_addr, serial_bytes, 3); - return 0; -} + pci_set_master(pcidev); -/* 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; + /* Initialize dev->board_name */ + dev->board_name = thisboard->name; -/* set i2c data line high or low */ -static void i2c_set_sda(struct comedi_device *dev, int state) -{ - static const int data_bit = CTL_EE_W; - void __iomem *plx_control_addr = priv(dev)->plx9080_iobase + - PLX_CONTROL_REG; + dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); - if (state) { - /* set data line high */ - priv(dev)->plx_control_bits &= ~data_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); - udelay(i2c_high_udelay); - } else { /* set data line low */ + devpriv->plx9080_phys_iobase = + pci_resource_start(pcidev, PLX9080_BADDRINDEX); + devpriv->main_phys_iobase = dev->iobase; + devpriv->dio_counter_phys_iobase = + pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); - priv(dev)->plx_control_bits |= data_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); - udelay(i2c_low_udelay); + /* remap, won't work with 2.0 kernels but who cares */ + devpriv->plx9080_iobase = + ioremap(devpriv->plx9080_phys_iobase, + pci_resource_len(pcidev, PLX9080_BADDRINDEX)); + devpriv->main_iobase = + ioremap(devpriv->main_phys_iobase, + pci_resource_len(pcidev, MAIN_BADDRINDEX)); + devpriv->dio_counter_iobase = + ioremap(devpriv->dio_counter_phys_iobase, + pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); + + if (!devpriv->plx9080_iobase || !devpriv->main_iobase + || !devpriv->dio_counter_iobase) { + dev_warn(dev->class_dev, "failed to remap io memory\n"); + return -ENOMEM; } -} -/* set i2c clock line high or low */ -static void i2c_set_scl(struct comedi_device *dev, int state) -{ - static const int clock_bit = CTL_USERO; - void __iomem *plx_control_addr = priv(dev)->plx9080_iobase + - PLX_CONTROL_REG; - - if (state) { - /* set clock line high */ - priv(dev)->plx_control_bits &= ~clock_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); - udelay(i2c_high_udelay); - } else { /* set clock line low */ - - priv(dev)->plx_control_bits |= clock_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); - udelay(i2c_low_udelay); - } -} + DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); + DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); + DEBUG_PRINT(" diocounter remapped to 0x%p\n", + devpriv->dio_counter_iobase); -static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) -{ - uint8_t bit; - unsigned int num_bits = 8; + /* figure out what local addresses are */ + local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & + LRNG_MEM_MASK; + local_decode = readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) & + local_range & LMAP_MEM_MASK; + devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase & + ~local_range) | local_decode; + local_range = readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & + LRNG_MEM_MASK; + local_decode = readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) & + local_range & LMAP_MEM_MASK; + devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & + ~local_range) | local_decode; + + DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); + DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); - DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); + retval = alloc_and_init_dma_members(dev); + if (retval < 0) + return retval; - 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); + 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); + /* get irq */ + if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, + "cb_pcidas64", dev)) { + dev_dbg(dev->class_dev, "unable to allocate irq %u\n", + pcidev->irq); + return -EINVAL; } -} - -/* 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 */ -} + dev->irq = pcidev->irq; + dev_dbg(dev->class_dev, "irq %u\n", dev->irq); -/* 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); -} + retval = setup_subdevices(dev); + if (retval < 0) + return retval; -/* 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); + return 0; } -static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t *data, unsigned int length) +static void detach(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pcidas64_private *devpriv = dev->private; unsigned int i; - uint8_t bitstream; - static const int read_bit = 0x1; - -/* XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus */ - /* make sure we dont send anything to eeprom */ - priv(dev)->plx_control_bits &= ~CTL_EE_CS; - - 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) { - comedi_error(dev, "i2c write failed: no acknowledge"); - 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) { - comedi_error(dev, "i2c write failed: no acknowledge"); - i2c_stop(dev); - return; + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (pcidev) { + if (devpriv->plx9080_iobase) { + disable_plx_interrupts(dev); + iounmap(devpriv->plx9080_iobase); + } + if (devpriv->main_iobase) + iounmap(devpriv->main_iobase); + if (devpriv->dio_counter_iobase) + iounmap(devpriv->dio_counter_iobase); + /* free pci dma buffers */ + for (i = 0; i < ai_dma_ring_count(thisboard); i++) { + if (devpriv->ai_buffer[i]) + pci_free_consistent(pcidev, + 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]) + pci_free_consistent(pcidev, + DMA_BUFFER_SIZE, + devpriv->ao_buffer[i], + devpriv->ao_buffer_bus_addr[i]); + } + /* free dma descriptors */ + if (devpriv->ai_dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + ai_dma_ring_count(thisboard), + devpriv->ai_dma_desc, + devpriv->ai_dma_desc_bus_addr); + if (devpriv->ao_dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + AO_DMA_RING_COUNT, + devpriv->ao_dma_desc, + devpriv->ao_dma_desc_bus_addr); } } - i2c_stop(dev); + if (dev->subdevices) + subdev_8255_cleanup(dev, &dev->subdevices[4]); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } } static struct comedi_driver cb_pcidas64_driver = { .driver_name = "cb_pcidas64", .module = THIS_MODULE, - .attach = attach, + .auto_attach = auto_attach, .detach = detach, }; -static int __devinit cb_pcidas64_pci_probe(struct pci_dev *dev, +static int cb_pcidas64_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcidas64_driver); } -static void __devexit cb_pcidas64_pci_remove(struct pci_dev *dev) +static void cb_pcidas64_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001d) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001e) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0035) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0036) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0037) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0052) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005d) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005e) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005f) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0061) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0062) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0063) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0064) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0066) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0067) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0068) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x006f) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0078) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0079) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table); @@ -4230,7 +4253,7 @@ static struct pci_driver cb_pcidas64_pci_driver = { .name = "cb_pcidas64", .id_table = cb_pcidas64_pci_table, .probe = cb_pcidas64_pci_probe, - .remove = __devexit_p(cb_pcidas64_pci_remove), + .remove = cb_pcidas64_pci_remove, }; module_comedi_pci_driver(cb_pcidas64_driver, cb_pcidas64_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index aef946d..7c6029a 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -1,90 +1,78 @@ /* - comedi/drivers/cb_pcidda.c - This intends to be a 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> - - 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * 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> + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ -*/ /* -Driver: cb_pcidda -Description: MeasurementComputing PCI-DDA series -Author: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net> -Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12 -Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12, - PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16 - -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first available PCI - device will be used. - -Only simple analog output writing is supported. - -So far it has only been tested with: - - PCI-DDA08/12 -Please report success/failure with other different cards to -<comedi@comedi.org>. -*/ + * Driver: cb_pcidda + * Description: MeasurementComputing PCI-DDA series + * Devices: (Measurement Computing) PCI-DDA08/12 [pci-dda08/12] + * (Measurement Computing) PCI-DDA04/12 [pci-dda04/12] + * (Measurement Computing) PCI-DDA02/12 [pci-dda02/12] + * (Measurement Computing) PCI-DDA08/16 [pci-dda08/16] + * (Measurement Computing) PCI-DDA04/16 [pci-dda04/16] + * (Measurement Computing) 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 "../comedidev.h" #include "comedi_fc.h" #include "8255.h" -/* PCI vendor number of ComputerBoards */ -#define PCI_VENDOR_ID_CB 0x1307 +/* + * ComputerBoards PCI Device ID's supported by this driver + */ +#define PCI_DEVICE_ID_DDA02_12 0x0020 +#define PCI_DEVICE_ID_DDA04_12 0x0021 +#define PCI_DEVICE_ID_DDA08_12 0x0022 +#define PCI_DEVICE_ID_DDA02_16 0x0023 +#define PCI_DEVICE_ID_DDA04_16 0x0024 +#define PCI_DEVICE_ID_DDA08_16 0x0025 + #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 PORT1A 0 /* PORT 1A DATA */ - -#define PORT1B 1 /* PORT 1B DATA */ - -#define PORT1C 2 /* PORT 1C DATA */ - -#define CONTROL1 3 /* CONTROL REGISTER 1 */ - -#define PORT2A 4 /* PORT 2A DATA */ - -#define PORT2B 5 /* PORT 2B DATA */ - -#define PORT2C 6 /* PORT 2C DATA */ - -#define CONTROL2 7 /* CONTROL REGISTER 2 */ +#define CB_DDA_DIO0_8255_BASE 0x00 +#define CB_DDA_DIO1_8255_BASE 0x04 /* DAC registers */ -#define DACONTROL 0 /* D/A CONTROL REGISTER */ -#define SU 0000001 /* Simultaneous update enabled */ -#define NOSU 0000000 /* Simultaneous update disabled */ -#define ENABLEDAC 0000002 /* Enable specified DAC */ -#define DISABLEDAC 0000000 /* Disable specified DAC */ -#define RANGE2V5 0000000 /* 2.5V */ -#define RANGE5V 0000200 /* 5V */ -#define RANGE10V 0000300 /* 10V */ -#define UNIP 0000400 /* Unipolar outputs */ -#define BIP 0000000 /* Bipolar outputs */ +#define CB_DDA_DA_CTRL_REG 0x00 /* D/A Control Register */ +#define CB_DDA_DA_CTRL_SU (1 << 0) /* Simultaneous update */ +#define CB_DDA_DA_CTRL_EN (1 << 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 (1 << 8) /* Unipolar range */ #define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */ /* write bits */ @@ -109,107 +97,67 @@ Please report success/failure with other different cards to /* manual says to set this bit with no explanation */ #define DUMMY_BIT 0x40 -#define DADATA 8 /* FIRST D/A DATA REGISTER (0) */ +#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), - } + 6, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5) + } }; -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ struct cb_pcidda_board { const char *name; - char status; /* Driver status: */ - - /* - * 0 - tested - * 1 - manual read, not tested - * 2 - manual not read - */ - unsigned short device_id; int ao_chans; int ao_bits; - const struct comedi_lrange *ranges; }; static const struct cb_pcidda_board cb_pcidda_boards[] = { { - .name = "pci-dda02/12", - .status = 1, - .device_id = 0x20, - .ao_chans = 2, - .ao_bits = 12, - .ranges = &cb_pcidda_ranges, - }, - { - .name = "pci-dda04/12", - .status = 1, - .device_id = 0x21, - .ao_chans = 4, - .ao_bits = 12, - .ranges = &cb_pcidda_ranges, - }, - { - .name = "pci-dda08/12", - .status = 0, - .device_id = 0x22, - .ao_chans = 8, - .ao_bits = 12, - .ranges = &cb_pcidda_ranges, - }, - { - .name = "pci-dda02/16", - .status = 2, - .device_id = 0x23, - .ao_chans = 2, - .ao_bits = 16, - .ranges = &cb_pcidda_ranges, - }, - { - .name = "pci-dda04/16", - .status = 2, - .device_id = 0x24, - .ao_chans = 4, - .ao_bits = 16, - .ranges = &cb_pcidda_ranges, - }, - { - .name = "pci-dda08/16", - .status = 0, - .device_id = 0x25, - .ao_chans = 8, - .ao_bits = 16, - .ranges = &cb_pcidda_ranges, - }, + .name = "pci-dda02/12", + .device_id = PCI_DEVICE_ID_DDA02_12, + .ao_chans = 2, + .ao_bits = 12, + }, { + .name = "pci-dda04/12", + .device_id = PCI_DEVICE_ID_DDA04_12, + .ao_chans = 4, + .ao_bits = 12, + }, { + .name = "pci-dda08/12", + .device_id = PCI_DEVICE_ID_DDA08_12, + .ao_chans = 8, + .ao_bits = 12, + }, { + .name = "pci-dda02/16", + .device_id = PCI_DEVICE_ID_DDA02_16, + .ao_chans = 2, + .ao_bits = 16, + }, { + .name = "pci-dda04/16", + .device_id = PCI_DEVICE_ID_DDA04_16, + .ao_chans = 4, + .ao_bits = 16, + }, { + .name = "pci-dda08/16", + .device_id = PCI_DEVICE_ID_DDA08_16, + .ao_chans = 8, + .ao_bits = 16, + }, }; -/* - * 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_pcidda_private { - int data; - - unsigned long digitalio; - unsigned long dac; - - /* unsigned long control_status; */ - /* unsigned long adc_fifo; */ - /* bits last written to da calibration register 1 */ unsigned int dac_cal1_bits; /* current range settings for output channels */ @@ -217,181 +165,16 @@ struct cb_pcidda_private { u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */ }; -/* - * I will program this later... ;-) - */ -#if 0 -static int cb_pcidda_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - printk("cb_pcidda_ai_cmd\n"); - printk("subdev: %d\n", cmd->subdev); - printk("flags: %d\n", cmd->flags); - printk("start_src: %d\n", cmd->start_src); - printk("start_arg: %d\n", cmd->start_arg); - printk("scan_begin_src: %d\n", cmd->scan_begin_src); - printk("convert_src: %d\n", cmd->convert_src); - printk("convert_arg: %d\n", cmd->convert_arg); - printk("scan_end_src: %d\n", cmd->scan_end_src); - printk("scan_end_arg: %d\n", cmd->scan_end_arg); - printk("stop_src: %d\n", cmd->stop_src); - printk("stop_arg: %d\n", cmd->stop_arg); - printk("chanlist_len: %d\n", cmd->chanlist_len); -} -#endif - -#if 0 -static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - int err = 0; - int tmp; - - /* Step 1 : check if triggers are trivially valid */ - - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->convert_src, - TRIG_TIMER | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); - - if (err) - return 1; - - /* Step 2a : make sure trigger sources are unique */ - - err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); - err |= cfc_check_trigger_is_unique(cmd->convert_src); - err |= cfc_check_trigger_is_unique(cmd->stop_src); - - /* Step 2b : and mutually compatible */ - - if (err) - return 2; - - /* step 3: make sure arguments are trivially compatible */ - - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } -#define MAX_SPEED 10000 /* in nanoseconds */ -#define MIN_SPEED 1000000000 /* in nanoseconds */ - - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } - } else { - /* external trigger */ - /* should be level/edge, hi/lo specification here */ - /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } - } else { - /* external trigger */ - /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } - } - - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } - - if (err) - return 3; - - /* step 4: fix up any arguments */ - - if (cmd->scan_begin_src == TRIG_TIMER) { - tmp = cmd->scan_begin_arg; - cb_pcidda_ns_to_timer(&cmd->scan_begin_arg, - cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->scan_begin_arg) - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - tmp = cmd->convert_arg; - cb_pcidda_ns_to_timer(&cmd->convert_arg, - cmd->flags & TRIG_ROUND_MASK); - 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; -} -#endif - -/* 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. */ -#if 0 -static int cb_pcidda_ns_to_timer(unsigned int *ns, int round) -{ - /* trivial timer */ - return *ns; -} -#endif - /* 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->dac + DACALIBRATION1) & SERIAL_OUT_BIT) + if (inw_p(dev->iobase + DACALIBRATION1) & SERIAL_OUT_BIT) value |= 1 << (value_width - i); } @@ -411,7 +194,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, devpriv->dac_cal1_bits |= SERIAL_IN_BIT; else devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT; - outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1); + outw_p(devpriv->dac_cal1_bits, dev->iobase + DACALIBRATION1); } } @@ -419,7 +202,6 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, 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; @@ -435,7 +217,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, /* 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->dac + DACALIBRATION2); + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); /* tell eeprom we want to read */ cb_pcidda_serial_out(dev, read_instruction, instruction_length); @@ -446,7 +228,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, /* deactivate eeprom */ cal2_bits &= ~SELECT_EEPROM_BIT; - outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); return value; } @@ -456,7 +238,6 @@ 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 */ @@ -479,72 +260,10 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, cal2_bits |= DESELECT_CALDAC_BIT(i); /* activate the caldac we want */ cal2_bits &= ~DESELECT_CALDAC_BIT(caldac); - outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); /* deactivate caldac */ cal2_bits |= DESELECT_CALDAC_BIT(caldac); - outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); -} - -/* returns caldac that calibrates given analog out channel */ -static unsigned int caldac_number(unsigned int channel) -{ - return channel / 2; -} - -/* returns caldac channel that provides fine gain for given ao channel */ -static unsigned int fine_gain_channel(unsigned int ao_channel) -{ - return 4 * (ao_channel % 2); -} - -/* returns caldac channel that provides coarse gain for given ao channel */ -static unsigned int coarse_gain_channel(unsigned int ao_channel) -{ - return 1 + 4 * (ao_channel % 2); -} - -/* returns caldac channel that provides coarse offset for given ao channel */ -static unsigned int coarse_offset_channel(unsigned int ao_channel) -{ - return 2 + 4 * (ao_channel % 2); -} - -/* returns caldac channel that provides fine offset for given ao channel */ -static unsigned int fine_offset_channel(unsigned int ao_channel) -{ - return 3 + 4 * (ao_channel % 2); -} - -/* returns eeprom address that provides offset for given ao channel and range */ -static unsigned int offset_eeprom_address(unsigned int ao_channel, - unsigned int range) -{ - return 0x7 + 2 * range + 12 * ao_channel; -} - -/* - * returns eeprom address that provides gain calibration for given ao - * channel and range - */ -static unsigned int gain_eeprom_address(unsigned int ao_channel, - unsigned int range) -{ - return 0x8 + 2 * range + 12 * ao_channel; -} - -/* - * returns upper byte of eeprom entry, which gives the coarse adjustment - * values - */ -static unsigned int eeprom_coarse_byte(unsigned int word) -{ - return (word >> 8) & 0xff; -} - -/* returns lower byte of eeprom entry, which gives the fine adjustment values */ -static unsigned int eeprom_fine_byte(unsigned int word) -{ - return word & 0xff; + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); } /* set caldacs to eeprom values for given channel and range */ @@ -552,85 +271,68 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, unsigned int range) { struct cb_pcidda_private *devpriv = dev->private; - unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain; + 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; - /* remember range so we can tell when we need to readjust calibration */ + /* save range so we can tell when we need to readjust calibration */ devpriv->ao_range[channel] = range; - /* get values from eeprom data */ - coarse_offset = - eeprom_coarse_byte(devpriv->eeprom_data - [offset_eeprom_address(channel, range)]); - fine_offset = - eeprom_fine_byte(devpriv->eeprom_data - [offset_eeprom_address(channel, range)]); - coarse_gain = - eeprom_coarse_byte(devpriv->eeprom_data - [gain_eeprom_address(channel, range)]); - fine_gain = - eeprom_fine_byte(devpriv->eeprom_data - [gain_eeprom_address(channel, range)]); - - /* set caldacs */ - cb_pcidda_write_caldac(dev, caldac_number(channel), - coarse_offset_channel(channel), coarse_offset); - cb_pcidda_write_caldac(dev, caldac_number(channel), - fine_offset_channel(channel), fine_offset); - cb_pcidda_write_caldac(dev, caldac_number(channel), - coarse_gain_channel(channel), coarse_gain); - cb_pcidda_write_caldac(dev, caldac_number(channel), - fine_gain_channel(channel), fine_gain); + /* 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_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +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 command; - unsigned int channel, range; - - channel = CR_CHAN(insn->chanspec); - range = CR_RANGE(insn->chanspec); + unsigned int channel = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int ctrl; - /* adjust calibration dacs if range has changed */ if (range != devpriv->ao_range[channel]) cb_pcidda_calibrate(dev, channel, range); - /* output channel configuration */ - command = NOSU | ENABLEDAC; + ctrl = CB_DDA_DA_CTRL_EN | CB_DDA_DA_CTRL_DAC(channel); - /* output channel range */ switch (range) { case 0: - command |= BIP | RANGE10V; - break; - case 1: - command |= BIP | RANGE5V; - break; - case 2: - command |= BIP | RANGE2V5; - break; case 3: - command |= UNIP | RANGE10V; + ctrl |= CB_DDA_DA_CTRL_RANGE10V; break; + case 1: case 4: - command |= UNIP | RANGE5V; + ctrl |= CB_DDA_DA_CTRL_RANGE5V; break; + case 2: case 5: - command |= UNIP | RANGE2V5; + ctrl |= CB_DDA_DA_CTRL_RANGE2V5; break; } - /* output channel specification */ - command |= channel << 2; - outw(command, devpriv->dac + DACONTROL); + if (range > 2) + ctrl |= CB_DDA_DA_CTRL_UNIP; - /* write data */ - outw(data[0], devpriv->dac + DADATA + channel * 2); + outw(ctrl, dev->iobase + CB_DDA_DA_CTRL_REG); - /* return the number of samples read/written */ - return 1; + outw(data[0], dev->iobase + CB_DDA_DA_DATA_REG(channel)); + + return insn->n; } static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev, @@ -647,41 +349,33 @@ static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev, return NULL; } -static int cb_pcidda_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int cb_pcidda_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct cb_pcidda_board *thisboard; struct cb_pcidda_private *devpriv; struct comedi_subdevice *s; - int index; + unsigned long iobase_8255; + int i; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = cb_pcidda_find_boardinfo(dev, pcidev); - if (!pcidev) + if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; dev->board_name = thisboard->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - - devpriv->digitalio = pci_resource_start(pcidev, 2); - devpriv->dac = pci_resource_start(pcidev, 3); - dev->iobase = devpriv->dac; - - if (thisboard->status == 2) - printk - ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " - "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " - "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n"); + dev->iobase = pci_resource_start(pcidev, 3); + iobase_8255 = pci_resource_start(pcidev, 2); ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -693,29 +387,24 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->ao_chans; s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ranges; - s->insn_write = cb_pcidda_ao_winsn; - - /* s->subdev_flags |= SDF_CMD_READ; */ - /* s->do_cmd = cb_pcidda_ai_cmd; */ - /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */ - - /* two 8255 digital io subdevices */ - s = &dev->subdevices[1]; - subdev_8255_init(dev, s, NULL, devpriv->digitalio); - s = &dev->subdevices[2]; - subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A); - - dev_dbg(dev->class_dev, "eeprom:\n"); - for (index = 0; index < EEPROM_SIZE; index++) { - devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); - dev_dbg(dev->class_dev, "%i:0x%x\n", index, - devpriv->eeprom_data[index]); + 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, iobase_8255 + (i * 4)); + 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 (index = 0; index < thisboard->ao_chans; index++) - cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]); + for (i = 0; i < thisboard->ao_chans; i++) + cb_pcidda_calibrate(dev, i, devpriv->ao_range[i]); dev_info(dev->class_dev, "%s attached\n", dev->board_name); @@ -739,28 +428,28 @@ static void cb_pcidda_detach(struct comedi_device *dev) static struct comedi_driver cb_pcidda_driver = { .driver_name = "cb_pcidda", .module = THIS_MODULE, - .attach_pci = cb_pcidda_attach_pci, + .auto_attach = cb_pcidda_auto_attach, .detach = cb_pcidda_detach, }; -static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev, +static int cb_pcidda_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcidda_driver); } -static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev) +static void cb_pcidda_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_12) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_12) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_12) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_16) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table); @@ -769,7 +458,7 @@ static struct pci_driver cb_pcidda_pci_driver = { .name = "cb_pcidda", .id_table = cb_pcidda_pci_table, .probe = cb_pcidda_pci_probe, - .remove = __devexit_p(cb_pcidda_pci_remove), + .remove = cb_pcidda_pci_remove, }; module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 9515b69..b43a5f8 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -51,8 +51,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. /* #define CBPCIMDAS_DEBUG */ #undef CBPCIMDAS_DEBUG -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 - /* Registers for the PCIM-DAS1602/16 */ /* sizes of io regions (bytes) */ @@ -80,44 +78,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. #define RESID_COUNT_H 13 #define RESID_COUNT_L 14 -/* Board description */ -struct cb_pcimdas_board { - const char *name; - unsigned short device_id; - int ai_se_chans; /* Inputs in single-ended mode */ - int ai_diff_chans; /* Inputs in differential mode */ - int ai_bits; /* analog input resolution */ - int ai_speed; /* fastest conversion period in ns */ - int ao_nchan; /* number of analog out channels */ - int ao_bits; /* analogue output resolution */ - int has_ao_fifo; /* analog output has fifo */ - int ao_scan_speed; /* analog output speed for 1602 series (for a scan, not conversion) */ - int fifo_size; /* number of samples fifo can hold */ - int dio_bits; /* number of dio bits */ - int has_dio; /* has DIO */ - const struct comedi_lrange *ranges; -}; - -static const struct cb_pcimdas_board cb_pcimdas_boards[] = { - { - .name = "PCIM-DAS1602/16", - .device_id = 0x56, - .ai_se_chans = 16, - .ai_diff_chans = 8, - .ai_bits = 16, - .ai_speed = 10000, /* ?? */ - .ao_nchan = 2, - .ao_bits = 12, - .has_ao_fifo = 0, /* ?? */ - .ao_scan_speed = 10000, - /* ?? */ - .fifo_size = 1024, - .dio_bits = 24, - .has_dio = 1, -/* .ranges = &cb_pcimdas_ranges, */ - }, -}; - /* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, @@ -140,7 +100,6 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct cb_pcimdas_board *thisboard = comedi_board(dev); struct cb_pcimdas_private *devpriv = dev->private; int n, i; unsigned int d; @@ -153,9 +112,9 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, /* check channel number */ if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) /* differential mode */ - maxchans = thisboard->ai_diff_chans; + maxchans = s->n_chan / 2; else - maxchans = thisboard->ai_se_chans; + maxchans = s->n_chan; if (chan > (maxchans - 1)) return -ETIMEDOUT; /* *** Wrong error code. Fixme. */ @@ -195,12 +154,7 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, return -ETIMEDOUT; } /* read data */ - d = inw(dev->iobase + 0); - - /* mangle the data as necessary */ - /* d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed. */ - - data[n] = d; + data[n] = inw(dev->iobase + 0); } /* return the number of samples read/written */ @@ -251,51 +205,21 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, return i; } -static const void *cb_pcimdas_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) +static int cb_pcimdas_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { - const struct cb_pcimdas_board *thisboard; - int i; - - for (i = 0; i < ARRAY_SIZE(cb_pcimdas_boards); i++) { - thisboard = &cb_pcimdas_boards[i]; - if (thisboard->device_id == pcidev->device) - return thisboard; - } - return NULL; -} - -static int cb_pcimdas_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct cb_pcimdas_board *thisboard; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct cb_pcimdas_private *devpriv; struct comedi_subdevice *s; unsigned long iobase_8255; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); + dev->board_name = dev->driver->driver_name; - thisboard = cb_pcimdas_find_boardinfo(dev, pcidev); - if (!thisboard) - return -ENODEV; - dev->board_ptr = thisboard; - dev->board_name = thisboard->name; - - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; - - /* Warn about non-tested features */ - switch (thisboard->device_id) { - case 0x56: - break; - default: - dev_dbg(dev->class_dev, "THIS CARD IS UNSUPPORTED.\n"); - dev_dbg(dev->class_dev, - "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n"); - } + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -323,8 +247,8 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, /* analog input subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = thisboard->ai_se_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; + s->n_chan = 16; + s->maxdata = 0xffff; s->range_table = &range_unknown; s->len_chanlist = 1; /* This is the maximum chanlist length that */ /* the board can handle */ @@ -334,8 +258,8 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_nchan; - s->maxdata = 1 << thisboard->ao_bits; + s->n_chan = 2; + s->maxdata = 0xfff; /* ranges are hardware settable, but not software readable. */ s->range_table = &range_unknown; s->insn_write = &cb_pcimdas_ao_winsn; @@ -343,10 +267,7 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, s = &dev->subdevices[2]; /* digital i/o subdevice */ - if (thisboard->has_dio) - subdev_8255_init(dev, s, NULL, iobase_8255); - else - s->type = COMEDI_SUBD_UNUSED; + subdev_8255_init(dev, s, NULL, iobase_8255); dev_info(dev->class_dev, "%s attached\n", dev->board_name); @@ -368,23 +289,23 @@ static void cb_pcimdas_detach(struct comedi_device *dev) static struct comedi_driver cb_pcimdas_driver = { .driver_name = "cb_pcimdas", .module = THIS_MODULE, - .attach_pci = cb_pcimdas_attach_pci, + .auto_attach = cb_pcimdas_auto_attach, .detach = cb_pcimdas_detach, }; -static int __devinit cb_pcimdas_pci_probe(struct pci_dev *dev, +static int cb_pcimdas_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcimdas_driver); } -static void __devexit cb_pcimdas_pci_remove(struct pci_dev *dev) +static void cb_pcimdas_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); @@ -393,7 +314,7 @@ static struct pci_driver cb_pcimdas_pci_driver = { .name = "cb_pcimdas", .id_table = cb_pcimdas_pci_table, .probe = cb_pcimdas_pci_probe, - .remove = __devexit_p(cb_pcimdas_pci_remove), + .remove = cb_pcimdas_pci_remove, }; module_comedi_pci_driver(cb_pcimdas_driver, cb_pcimdas_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index ba9f059..699b84f 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -84,7 +84,6 @@ Configuration Options: not applicable, uses PCI auto config #include "8255.h" /* device ids of the cards we support -- currently only 1 card supported */ -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_ID_PCIM_DDA06_16 0x0053 /* @@ -152,20 +151,20 @@ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, return insn->n; } -static int cb_pcimdda_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int cb_pcimdda_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct cb_pcimdda_private *devpriv; struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -213,23 +212,23 @@ static void cb_pcimdda_detach(struct comedi_device *dev) static struct comedi_driver cb_pcimdda_driver = { .driver_name = "cb_pcimdda", .module = THIS_MODULE, - .attach_pci = cb_pcimdda_attach_pci, + .auto_attach = cb_pcimdda_auto_attach, .detach = cb_pcimdda_detach, }; -static int __devinit cb_pcimdda_pci_probe(struct pci_dev *dev, +static int cb_pcimdda_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcimdda_driver); } -static void __devexit cb_pcimdda_pci_remove(struct pci_dev *dev) +static void cb_pcimdda_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_ID_PCIM_DDA06_16) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcimdda_pci_table); @@ -238,7 +237,7 @@ static struct pci_driver cb_pcimdda_driver_pci_driver = { .name = "cb_pcimdda", .id_table = cb_pcimdda_pci_table, .probe = cb_pcimdda_pci_probe, - .remove = __devexit_p(cb_pcimdda_pci_remove), + .remove = cb_pcimdda_pci_remove, }; module_comedi_pci_driver(cb_pcimdda_driver, cb_pcimdda_driver_pci_driver); diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 5c768bc..3151599 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -304,10 +304,10 @@ static int bonding_attach(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* * Setup our bonding from config params.. sets up our private struct.. diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c index 63be619..8372829 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.c +++ b/drivers/staging/comedi/drivers/comedi_fc.c @@ -53,7 +53,7 @@ unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, retval = comedi_buf_write_alloc(async, num_bytes); if (retval != num_bytes) { - printk(KERN_WARNING "comedi: buffer overrun\n"); + dev_warn(subd->device->class_dev, "comedi: buffer overrun\n"); async->events |= COMEDI_CB_OVERFLOW; return 0; } diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index 94481c6..31afab7 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -105,4 +105,48 @@ static inline int cfc_check_trigger_is_unique(unsigned int src) return 0; } +/** + * cfc_check_trigger_arg_is() - trivially validate a trigger argument + * @arg: pointer to the trigger arg to validate + * @val: the value the argument should be + */ +static inline int cfc_check_trigger_arg_is(unsigned int *arg, unsigned int val) +{ + if (*arg != val) { + *arg = val; + return -EINVAL; + } + return 0; +} + +/** + * cfc_check_trigger_arg_min() - trivially validate a trigger argument + * @arg: pointer to the trigger arg to validate + * @val: the minimum value the argument should be + */ +static inline int cfc_check_trigger_arg_min(unsigned int *arg, + unsigned int val) +{ + if (*arg < val) { + *arg = val; + return -EINVAL; + } + return 0; +} + +/** + * cfc_check_trigger_arg_max() - trivially validate a trigger argument + * @arg: pointer to the trigger arg to validate + * @val: the maximum value the argument should be + */ +static inline int cfc_check_trigger_arg_max(unsigned int *arg, + unsigned int val) +{ + if (*arg > val) { + *arg = val; + return -EINVAL; + } + return 0; +} + #endif /* _COMEDI_FC_H */ diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 22ef942..76d59dc 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -196,28 +196,13 @@ static int parport_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -305,10 +290,10 @@ static int parport_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 7817def..fb3d093 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -252,55 +252,28 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_NOW) + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_NOW) { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < nano_per_micro) { - cmd->scan_begin_arg = nano_per_micro; - err++; - } - if (cmd->convert_src == TRIG_TIMER && - cmd->scan_begin_arg < - cmd->convert_arg * cmd->chanlist_len) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->chanlist_len; - err++; - } - } - /* - * XXX these checks are generic and should go in core if not there - * already - */ - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + nano_per_micro); + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + cmd->convert_arg * cmd->chanlist_len); } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -414,10 +387,10 @@ static int waveform_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* set default amplitude and period */ if (amplitude <= 0) diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 178a6a4..1a18fa3 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -68,14 +68,13 @@ static int contec_di_insn_bits(struct comedi_device *dev, return insn->n; } -static int contec_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +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; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); @@ -121,17 +120,17 @@ static void contec_detach(struct comedi_device *dev) static struct comedi_driver contec_pci_dio_driver = { .driver_name = "contec_pci_dio", .module = THIS_MODULE, - .attach_pci = contec_attach_pci, + .auto_attach = contec_auto_attach, .detach = contec_detach, }; -static int __devinit contec_pci_dio_pci_probe(struct pci_dev *dev, +static int contec_pci_dio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &contec_pci_dio_driver); } -static void __devexit contec_pci_dio_pci_remove(struct pci_dev *dev) +static void contec_pci_dio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -146,7 +145,7 @@ 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 = __devexit_p(contec_pci_dio_pci_remove), + .remove = contec_pci_dio_pci_remove, }; module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index d13c8c5..992e557 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -117,8 +117,6 @@ Configuration options: not applicable, uses PCI auto config #define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin" -#define PCI_VENDOR_ID_IOTECH 0x1616 - #define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */ #define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */ @@ -690,26 +688,25 @@ static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int daqboard2000_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int daqboard2000_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct daq200_boardtype *board; struct daqboard2000_private *devpriv; struct comedi_subdevice *s; int result; - comedi_set_hw_dev(dev, &pcidev->dev); - board = daqboard2000_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; dev->board_ptr = board; dev->board_name = board->name; - result = alloc_private(dev, sizeof(*devpriv)); - if (result < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; - devpriv = dev->private; + dev->private = devpriv; result = comedi_pci_enable(pcidev, dev->driver->driver_name); if (result < 0) @@ -792,17 +789,17 @@ static void daqboard2000_detach(struct comedi_device *dev) static struct comedi_driver daqboard2000_driver = { .driver_name = "daqboard2000", .module = THIS_MODULE, - .attach_pci = daqboard2000_attach_pci, + .auto_attach = daqboard2000_auto_attach, .detach = daqboard2000_detach, }; -static int __devinit daqboard2000_pci_probe(struct pci_dev *dev, +static int daqboard2000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &daqboard2000_driver); } -static void __devexit daqboard2000_pci_remove(struct pci_dev *dev) +static void daqboard2000_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -817,7 +814,7 @@ static struct pci_driver daqboard2000_pci_driver = { .name = "daqboard2000", .id_table = daqboard2000_pci_table, .probe = daqboard2000_pci_probe, - .remove = __devexit_p(daqboard2000_pci_remove), + .remove = daqboard2000_pci_remove, }; module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index c304528..b15e058 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -65,7 +65,6 @@ #define DO_PCI IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) #define DO_COMEDI_DRIVER_REGISTER (DO_ISA || DO_PCI) -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_DEVICE_ID_PCIDAS08 0x29 #define PCIDAS08_SIZE 0x54 @@ -775,24 +774,29 @@ das08_find_pci_board(struct pci_dev *pdev) } /* only called in the PCI probe path, via comedi_pci_auto_config() */ -static int __devinit __maybe_unused -das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) +static int __maybe_unused +das08_auto_attach(struct comedi_device *dev, unsigned long context_unused) { + struct pci_dev *pdev; + struct das08_private_struct *devpriv; unsigned long iobase; - int ret; if (!DO_PCI) return -EINVAL; - ret = alloc_private(dev, sizeof(struct das08_private_struct)); - if (ret < 0) - return ret; + + pdev = comedi_to_pci_dev(dev); + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + dev_info(dev->class_dev, "attach pci %s\n", pci_name(pdev)); dev->board_ptr = das08_find_pci_board(pdev); if (dev->board_ptr == NULL) { dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } - comedi_set_hw_dev(dev, &pdev->dev); + /* enable PCI device and reserve I/O spaces */ if (comedi_pci_enable(pdev, dev->driver->driver_name)) { dev_err(dev->class_dev, @@ -809,13 +813,12 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das08_board_struct *thisboard = comedi_board(dev); struct das08_private_struct *devpriv; - int ret; unsigned long iobase; - ret = alloc_private(dev, sizeof(struct das08_private_struct)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev_info(dev->class_dev, "attach\n"); if (is_pci_board(thisboard)) { @@ -866,7 +869,7 @@ static struct comedi_driver das08_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = das08_attach, - .attach_pci = das08_attach_pci, + .auto_attach = das08_auto_attach, .detach = das08_detach, .board_name = &das08_boards[0].name, .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), @@ -876,19 +879,19 @@ static struct comedi_driver das08_driver = { #if DO_PCI static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_PCIDAS08) }, {0} }; MODULE_DEVICE_TABLE(pci, das08_pci_table); -static int __devinit das08_pci_probe(struct pci_dev *dev, +static int das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &das08_driver); } -static void __devexit das08_pci_remove(struct pci_dev *dev) +static void das08_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -897,7 +900,7 @@ static struct pci_driver das08_pci_driver = { .id_table = das08_pci_table, .name = DRV_NAME, .probe = &das08_pci_probe, - .remove = __devexit_p(&das08_pci_remove) + .remove = &das08_pci_remove }; #endif /* DO_PCI */ diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index e4c91e6..0242623 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -90,13 +90,14 @@ static int das08_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das08_board_struct *thisboard = comedi_board(dev); - int ret; + struct das08_private_struct *devpriv; unsigned long iobase; struct pcmcia_device *link = cur_dev; /* XXX hack */ - ret = alloc_private(dev, sizeof(struct das08_private_struct)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev_info(dev->class_dev, "das08_cs: attach\n"); /* deal with a pci board */ diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index fcb8a32..b159f44 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -392,12 +392,12 @@ struct das16_private_struct { volatile short timer_running; volatile short timer_mode; /* true if using timer mode */ }; -#define devpriv ((struct das16_private_struct *)(dev->private)) static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; int err = 0, tmp; int gain, start_chan, i; int mask; @@ -442,46 +442,27 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - /* check against maximum frequency */ - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < - board->ai_speed * cmd->chanlist_len) { - cmd->scan_begin_arg = - board->ai_speed * cmd->chanlist_len; - err++; - } - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_speed) { - cmd->convert_arg = board->ai_speed; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + /* check against maximum frequency */ + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + board->ai_speed * cmd->chanlist_len); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ai_speed); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } if (err) return 3; @@ -540,6 +521,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct das16_private_struct *devpriv = dev->private; unsigned int size; unsigned int freq; @@ -581,6 +563,8 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, int rounding_flags) { + struct das16_private_struct *devpriv = dev->private; + i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1), &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK); @@ -595,6 +579,7 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte; @@ -701,6 +686,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); @@ -738,6 +724,7 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; int i, n; int range; int chan; @@ -848,10 +835,12 @@ static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, */ static int disable_dma_on_even(struct comedi_device *dev) { + struct das16_private_struct *devpriv = dev->private; int residue; int i; static const int disable_limit = 100; static const int enable_timeout = 100; + disable_dma(devpriv->dma_chan); residue = get_dma_residue(devpriv->dma_chan); for (i = 0; i < disable_limit && (residue % 2); ++i) { @@ -877,6 +866,7 @@ static int disable_dma_on_even(struct comedi_device *dev) static void das16_interrupt(struct comedi_device *dev) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; unsigned long dma_flags, spin_flags; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; @@ -973,6 +963,7 @@ static irqreturn_t das16_dma_interrupt(int irq, void *d) static void das16_timer_interrupt(unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; + struct das16_private_struct *devpriv = dev->private; das16_interrupt(dev); @@ -1001,6 +992,7 @@ static void reg_dump(struct comedi_device *dev) static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; int status; int diobits; @@ -1035,6 +1027,7 @@ static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) static int das1600_mode_detect(struct comedi_device *dev) { + struct das16_private_struct *devpriv = dev->private; int status = 0; status = inb(dev->iobase + DAS1600_STATUS_B); @@ -1080,6 +1073,7 @@ static void das16_ai_munge(struct comedi_device *dev, static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv; struct comedi_subdevice *s; int ret; unsigned int irq; @@ -1114,9 +1108,10 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - ret = alloc_private(dev, sizeof(struct das16_private_struct)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; if (board->size < 0x400) { printk(" 0x%04lx-0x%04lx\n", iobase, iobase + board->size); @@ -1353,6 +1348,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void das16_detach(struct comedi_device *dev) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; das16_reset(dev); if (dev->subdevices) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 3f87d75..b0a861a 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -28,7 +28,7 @@ Driver: das16m1 Description: CIO-DAS16/M1 Author: Frank Mori Hess <fmhess@users.sourceforge.net> -Devices: [Measurement Computing] CIO-DAS16/M1 (cio-das16/m1) +Devices: [Measurement Computing] CIO-DAS16/M1 (das16m1) Status: works This driver supports a single board - the CIO-DAS16/M1. @@ -132,11 +132,6 @@ static const struct comedi_lrange range_das16m1 = { 9, } }; -struct das16m1_board { - const char *name; - unsigned int ai_speed; -}; - struct das16m1_private_struct { unsigned int control_state; volatile unsigned int adc_count; /* number of samples completed */ @@ -149,7 +144,6 @@ struct das16m1_private_struct { unsigned int divisor1; /* divides master clock to obtain conversion speed */ unsigned int divisor2; /* divides master clock to obtain conversion speed */ }; -#define devpriv ((struct das16m1_private_struct *)(dev->private)) static inline short munge_sample(short data) { @@ -167,7 +161,7 @@ static void munge_sample_array(short *array, unsigned int num_elements) static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - const struct das16m1_board *board = comedi_board(dev); + struct das16m1_private_struct *devpriv = dev->private; unsigned int err = 0, tmp, i; /* Step 1 : check if triggers are trivially valid */ @@ -192,40 +186,23 @@ static int das16m1_cmd_test(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_speed) { - cmd->convert_arg = board->ai_speed; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 1000); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -277,6 +254,8 @@ static int das16m1_cmd_test(struct comedi_device *dev, static unsigned int das16m1_set_pacer(struct comedi_device *dev, unsigned int ns, int rounding_flags) { + struct das16m1_private_struct *devpriv = dev->private; + i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1), &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK); @@ -293,6 +272,7 @@ static unsigned int das16m1_set_pacer(struct comedi_device *dev, static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das16m1_private_struct *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte, i; @@ -356,6 +336,8 @@ static int das16m1_cmd_exec(struct comedi_device *dev, static int das16m1_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das16m1_private_struct *devpriv = dev->private; + devpriv->control_state &= ~INTE & ~PACER_MASK; outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL); @@ -366,6 +348,7 @@ static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16m1_private_struct *devpriv = dev->private; int i, n; int byte; const int timeout = 1000; @@ -417,6 +400,7 @@ static int das16m1_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16m1_private_struct *devpriv = dev->private; unsigned int wbits; /* only set bits that have been masked */ @@ -436,6 +420,7 @@ static int das16m1_do_wbits(struct comedi_device *dev, static void das16m1_handler(struct comedi_device *dev, unsigned int status) { + struct das16m1_private_struct *devpriv = dev->private; struct comedi_subdevice *s; struct comedi_async *async; struct comedi_cmd *cmd; @@ -582,26 +567,27 @@ static int das16m1_irq_bits(unsigned int irq) static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct das16m1_board *board = comedi_board(dev); + struct das16m1_private_struct *devpriv; struct comedi_subdevice *s; int ret; unsigned int irq; unsigned long iobase; - iobase = it->options[0]; + dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(struct das16m1_private_struct)); - if (ret < 0) - return ret; + iobase = it->options[0]; - dev->board_name = board->name; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; - if (!request_region(iobase, DAS16M1_SIZE, dev->driver->driver_name)) { + if (!request_region(iobase, DAS16M1_SIZE, dev->board_name)) { comedi_error(dev, "I/O port conflict\n"); return -EIO; } if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2, - dev->driver->driver_name)) { + dev->board_name)) { release_region(iobase, DAS16M1_SIZE); comedi_error(dev, "I/O port conflict\n"); return -EIO; @@ -698,21 +684,11 @@ static void das16m1_detach(struct comedi_device *dev) } } -static const struct das16m1_board das16m1_boards[] = { - { - .name = "cio-das16/m1", /* CIO-DAS16_M1.pdf */ - .ai_speed = 1000, /* 1MHz max speed */ - }, -}; - static struct comedi_driver das16m1_driver = { .driver_name = "das16m1", .module = THIS_MODULE, .attach = das16m1_attach, .detach = das16m1_detach, - .board_name = &das16m1_boards[0].name, - .num_names = ARRAY_SIZE(das16m1_boards), - .offset = sizeof(das16m1_boards[0]), }; module_comedi_driver(das16m1_driver); diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 2555f32..7900f95 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -454,8 +454,6 @@ struct das1800_private { short ao_update_bits; /* remembers the last write to the 'update' dac */ }; -#define devpriv ((struct das1800_private *)dev->private) - /* analog out range for boards with basic analog out */ static const struct comedi_lrange range_ao_1 = { 1, @@ -501,6 +499,7 @@ static void munge_data(struct comedi_device *dev, uint16_t * array, static void das1800_handle_fifo_half_full(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; int numPoints = 0; /* number of points to read */ struct comedi_cmd *cmd = &s->async->cmd; @@ -520,6 +519,7 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev, static void das1800_handle_fifo_not_empty(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; short dpnt; int unipolar; struct comedi_cmd *cmd = &s->async->cmd; @@ -548,6 +548,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int channel, uint16_t *buffer) { + struct das1800_private *devpriv = dev->private; unsigned int num_bytes, num_samples; struct comedi_cmd *cmd = &s->async->cmd; @@ -578,6 +579,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; unsigned long flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; @@ -609,6 +611,7 @@ static void das1800_flush_dma(struct comedi_device *dev, static void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int status) { + struct das1800_private *devpriv = dev->private; unsigned long flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; @@ -643,6 +646,8 @@ static void das1800_handle_dma(struct comedi_device *dev, static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; + outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ @@ -656,6 +661,7 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) /* the guts of the interrupt handler, that is shared with das1800_ai_poll */ static void das1800_ai_handler(struct comedi_device *dev) { + struct das1800_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -783,6 +789,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct das1800_private *devpriv = dev->private; int err = 0; unsigned int tmp_arg; int i; @@ -817,39 +824,23 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; @@ -1006,6 +997,7 @@ static int control_c_bits(const struct comedi_cmd *cmd) /* loads counters with divisor1, divisor2 from private structure */ static int das1800_set_frequency(struct comedi_device *dev) { + struct das1800_private *devpriv = dev->private; int err = 0; /* counter 1, mode 2 */ @@ -1026,6 +1018,7 @@ static int das1800_set_frequency(struct comedi_device *dev) static int setup_counters(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct das1800_private *devpriv = dev->private; unsigned int period; /* setup cascaded counters for conversion/scan frequency */ @@ -1107,6 +1100,7 @@ static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd) /* sets up dma */ static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct das1800_private *devpriv = dev->private; unsigned long lock_flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; @@ -1174,6 +1168,7 @@ static void program_chanlist(struct comedi_device *dev, static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; int ret; int control_a, control_c; struct comedi_async *async = s->async; @@ -1300,6 +1295,7 @@ static int das1800_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das1800_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); /* int range = CR_RANGE(insn->chanspec); */ int update_chan = thisboard->ao_n_chan - 1; @@ -1342,6 +1338,7 @@ static int das1800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das1800_private *devpriv = dev->private; unsigned int wbits; /* only set bits that have been masked */ @@ -1361,6 +1358,7 @@ static int das1800_do_wbits(struct comedi_device *dev, static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, unsigned int dma1) { + struct das1800_private *devpriv = dev->private; unsigned long flags; /* need an irq to do dma */ @@ -1518,6 +1516,7 @@ static int das1800_probe(struct comedi_device *dev) static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct das1800_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = it->options[0]; unsigned int irq = it->options[1]; @@ -1527,9 +1526,10 @@ static int das1800_attach(struct comedi_device *dev, int board; int retval; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct das1800_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name, iobase); @@ -1699,11 +1699,13 @@ static int das1800_attach(struct comedi_device *dev, static void das1800_detach(struct comedi_device *dev) { + struct das1800_private *devpriv = dev->private; + if (dev->iobase) release_region(dev->iobase, DAS1800_SIZE); if (dev->irq) free_irq(dev->irq, dev); - if (dev->private) { + if (devpriv) { if (devpriv->iobase2) release_region(devpriv->iobase2, DAS1800_SIZE); if (devpriv->dma0) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index e134c46..2efddb8 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -104,7 +104,6 @@ struct das6402_private { int das6402_ignoreirq; }; -#define devpriv ((struct das6402_private *)dev->private) static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subdevice *s) @@ -152,6 +151,7 @@ static void das6402_setcounter(struct comedi_device *dev) static irqreturn_t intr_handler(int irq, void *d) { struct comedi_device *dev = d; + struct das6402_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; if (!dev->attached || devpriv->das6402_ignoreirq) { @@ -196,6 +196,8 @@ static void das6402_ai_fifo_read(struct comedi_device *dev, short *data, int n) static int das6402_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das6402_private *devpriv = dev->private; + /* * This function should reset the board from whatever condition it * is in (i.e., acquiring data), to a non-active state. @@ -217,6 +219,8 @@ static int das6402_ai_cancel(struct comedi_device *dev, static int das6402_ai_mode2(struct comedi_device *dev, struct comedi_subdevice *s, comedi_trig * it) { + struct das6402_private *devpriv = dev->private; + devpriv->das6402_ignoreirq = 1; dev_dbg(dev->class_dev, "Starting acquisition\n"); outb_p(0x03, dev->iobase + 10); /* enable external trigging */ @@ -236,6 +240,7 @@ static int das6402_ai_mode2(struct comedi_device *dev, static int board_init(struct comedi_device *dev) { + struct das6402_private *devpriv = dev->private; BYTE b; devpriv->das6402_ignoreirq = 1; @@ -277,6 +282,7 @@ static int board_init(struct comedi_device *dev) static int das6402_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct das6402_private *devpriv; unsigned int irq; unsigned long iobase; int ret; @@ -303,9 +309,11 @@ static int das6402_attach(struct comedi_device *dev, return ret; dev->irq = irq; - ret = alloc_private(dev, sizeof(struct das6402_private)); - if (ret < 0) - return ret; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 215deac..38f625b 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -241,8 +241,6 @@ struct das800_private { volatile int do_bits; /* digital output bits */ }; -#define devpriv ((struct das800_private *)dev->private) - static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void das800_detach(struct comedi_device *dev); @@ -344,22 +342,7 @@ static int das800_probe(struct comedi_device *dev) return -1; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __init driver_das800_init_module(void) -{ - return comedi_driver_register(&driver_das800); -} - -static void __exit driver_das800_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das800); -} - -module_init(driver_das800_init_module); -module_exit(driver_das800_cleanup_module); +module_comedi_driver(driver_das800); /* interrupt service routine */ static irqreturn_t das800_interrupt(int irq, void *d) @@ -367,6 +350,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) short i; /* loop index */ short dataPoint = 0; struct comedi_device *dev = d; + struct das800_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */ struct comedi_async *async; int status; @@ -461,6 +445,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct das800_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = it->options[0]; unsigned int irq = it->options[1]; @@ -472,9 +457,10 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (irq) dev_dbg(dev->class_dev, "irq %u\n", irq); - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct das800_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; if (iobase == 0) { dev_err(dev->class_dev, @@ -569,6 +555,8 @@ static void das800_detach(struct comedi_device *dev) static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das800_private *devpriv = dev->private; + devpriv->forever = 0; devpriv->count = 0; disable_das800(dev); @@ -578,7 +566,9 @@ static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) /* enable_das800 makes the card start taking hardware triggered conversions */ static void enable_das800(struct comedi_device *dev) { + 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 (thisboard->resolution == 16) @@ -604,6 +594,7 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct das800_private *devpriv = dev->private; int err = 0; int tmp; int gain, startChan; @@ -631,37 +622,21 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -710,6 +685,7 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das800_private *devpriv = dev->private; int startChan, endChan, scan, gain; int conv_bits; unsigned long irq_flags; @@ -793,6 +769,7 @@ static int das800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das800_private *devpriv = dev->private; int i, n; int chan; int range; @@ -862,6 +839,7 @@ static int das800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das800_private *devpriv = dev->private; int wbits; unsigned long irq_flags; @@ -885,6 +863,7 @@ static int das800_do_wbits(struct comedi_device *dev, /* loads counters with divisor1, divisor2 from private structure */ static int das800_set_frequency(struct comedi_device *dev) { + struct das800_private *devpriv = dev->private; int err = 0; if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2)) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 4d5c33c..9e21241 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -158,10 +158,6 @@ static const struct comedi_lrange dmm32at_aoranges = { } }; -struct dmm32at_board { - const char *name; -}; - struct dmm32at_private { int data; @@ -284,33 +280,25 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SCAN_SPEED 1000000 /* in nanoseconds */ #define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SCAN_SPEED) { - cmd->scan_begin_arg = MAX_SCAN_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SCAN_SPEED) { - cmd->scan_begin_arg = MIN_SCAN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SCAN_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SCAN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } + if (cmd->convert_src == TRIG_TIMER) { if (cmd->convert_arg >= 17500) cmd->convert_arg = 20000; @@ -320,35 +308,20 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, cmd->convert_arg = 10000; else cmd->convert_arg = 5000; - } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0xfffffff0) { - cmd->stop_arg = 0xfffffff0; - err++; - } - if (cmd->stop_arg == 0) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0xfffffff0); + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -718,7 +691,6 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev, static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct dmm32at_board *board = comedi_board(dev); struct dmm32at_private *devpriv; int ret; struct comedi_subdevice *s; @@ -726,6 +698,8 @@ static int dmm32at_attach(struct comedi_device *dev, unsigned long iobase; unsigned int irq; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; irq = it->options[1]; @@ -734,7 +708,7 @@ static int dmm32at_attach(struct comedi_device *dev, iobase, irq); /* register address space */ - if (!request_region(iobase, DMM32AT_MEMSIZE, board->name)) { + if (!request_region(iobase, DMM32AT_MEMSIZE, dev->board_name)) { printk(KERN_ERR "comedi%d: dmm32at: I/O port conflict\n", dev->minor); return -EIO; @@ -788,7 +762,7 @@ static int dmm32at_attach(struct comedi_device *dev, /* board is there, register interrupt */ if (irq) { - ret = request_irq(irq, dmm32at_isr, 0, board->name, dev); + ret = request_irq(irq, dmm32at_isr, 0, dev->board_name, dev); if (ret < 0) { printk(KERN_ERR "dmm32at: irq conflict\n"); return ret; @@ -796,11 +770,10 @@ static int dmm32at_attach(struct comedi_device *dev, dev->irq = irq; } - dev->board_name = board->name; - - if (alloc_private(dev, sizeof(*devpriv)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; - devpriv = dev->private; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -867,20 +840,11 @@ static void dmm32at_detach(struct comedi_device *dev) release_region(dev->iobase, DMM32AT_MEMSIZE); } -static const struct dmm32at_board dmm32at_boards[] = { - { - .name = "dmm32at", - }, -}; - static struct comedi_driver dmm32at_driver = { .driver_name = "dmm32at", .module = THIS_MODULE, .attach = dmm32at_attach, .detach = dmm32at_detach, - .board_name = &dmm32at_boards[0].name, - .offset = sizeof(struct dmm32at_board), - .num_names = ARRAY_SIZE(dmm32at_boards), }; module_comedi_driver(dmm32at_driver); diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index c59a652..f6942aa 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -233,8 +233,6 @@ struct dt2801_private { unsigned int ao_readback[2]; }; -#define devpriv ((struct dt2801_private *)dev->private) - /* These are the low-level routines: writecommand: write a command to the board writedata: write data byte @@ -508,6 +506,8 @@ static int dt2801_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2801_private *devpriv = dev->private; + data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; return 1; @@ -517,6 +517,8 @@ static int dt2801_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2801_private *devpriv = dev->private; + dt2801_writecmd(dev, DT_C_WRITE_DAIM); dt2801_writedata(dev, CR_CHAN(insn->chanspec)); dt2801_writedata2(dev, data[0]); @@ -590,6 +592,7 @@ static int dt2801_dio_insn_config(struct comedi_device *dev, */ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dt2801_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int board_code, type; @@ -630,9 +633,10 @@ havetype: if (ret) goto out; - ret = alloc_private(dev, sizeof(struct dt2801_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_name = boardtype.name; diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index d3a8c1a..f90ecf4 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -226,8 +226,6 @@ struct dt2811_private { unsigned int ao_readback[2]; }; -#define devpriv ((struct dt2811_private *)dev->private) - static const struct comedi_lrange *dac_range_types[] = { &range_bipolar5, &range_bipolar2_5, @@ -242,6 +240,7 @@ static irqreturn_t dt2811_interrupt(int irq, void *d) int lo, hi; int data; struct comedi_device *dev = d; + struct dt2811_private *devpriv = dev->private; if (!dev->attached) { comedi_error(dev, "spurious interrupt"); @@ -318,6 +317,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2811_private *devpriv = dev->private; int i; int chan; @@ -337,6 +337,7 @@ static int dt2811_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2811_private *devpriv = dev->private; int i; int chan; @@ -397,6 +398,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* long flags; */ const struct dt2811_board *board = comedi_board(dev); + struct dt2811_private *devpriv; int ret; struct comedi_subdevice *s; unsigned long iobase; @@ -463,9 +465,10 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct dt2811_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; switch (it->options[2]) { case 0: diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 064a8f2..e520dba 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -68,8 +68,6 @@ struct dt2814_private { int curadchan; }; -#define devpriv ((struct dt2814_private *)dev->private) - #define DT2814_TIMEOUT 10 #define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */ @@ -151,36 +149,20 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg > 1000000000) { - cmd->scan_begin_arg = 1000000000; - err++; - } - if (cmd->scan_begin_arg < DT2814_MAX_SPEED) { - cmd->scan_begin_arg = DT2814_MAX_SPEED; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg < 2) { - cmd->stop_arg = 2; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 1000000000); + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + DT2814_MAX_SPEED); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 2); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -200,6 +182,7 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev, static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt2814_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int chan; int trigvar; @@ -221,6 +204,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) { int lo, hi; struct comedi_device *dev = d; + struct dt2814_private *devpriv = dev->private; struct comedi_subdevice *s; int data; @@ -258,6 +242,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dt2814_private *devpriv; int i, irq; int ret; struct comedi_subdevice *s; @@ -324,9 +309,10 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct dt2814_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index b9692ef..1e0cfe4 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -78,8 +78,6 @@ struct dt2815_private { unsigned int ao_readback[8]; }; -#define devpriv ((struct dt2815_private *)dev->private) - static int dt2815_wait_for_status(struct comedi_device *dev, int status) { int i; @@ -95,6 +93,7 @@ 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); @@ -107,6 +106,7 @@ static int dt2815_ao_insn_read(struct comedi_device *dev, 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 status; @@ -162,6 +162,7 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, 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; @@ -182,8 +183,10 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - if (alloc_private(dev, sizeof(struct dt2815_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; /* ao subdevice */ diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 78d3407..122d980 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -248,7 +248,6 @@ struct dt282x_private { int dma_dir; }; -#define devpriv ((struct dt282x_private *)dev->private) #define boardtype (*(const struct dt282x_board *)dev->board_ptr) /* @@ -290,6 +289,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2); static void dt282x_munge(struct comedi_device *dev, short *buf, unsigned int nbytes) { + struct dt282x_private *devpriv = dev->private; unsigned int i; unsigned short mask = (1 << boardtype.adbits) - 1; unsigned short sign = 1 << (boardtype.adbits - 1); @@ -309,6 +309,7 @@ static void dt282x_munge(struct comedi_device *dev, short *buf, static void dt282x_ao_dma_interrupt(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; void *ptr; int size; int i; @@ -341,6 +342,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) static void dt282x_ai_dma_interrupt(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; void *ptr; int size; int i; @@ -393,6 +395,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev) static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n) { + struct dt282x_private *devpriv = dev->private; int dma_chan; unsigned long dma_ptr; unsigned long flags; @@ -424,6 +427,7 @@ static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n) static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n) { + struct dt282x_private *devpriv = dev->private; int dma_chan; unsigned long dma_ptr; unsigned long flags; @@ -447,6 +451,7 @@ static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n) static irqreturn_t dt282x_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct dt282x_private *devpriv = dev->private; struct comedi_subdevice *s; struct comedi_subdevice *s_ao; unsigned int supcsr, adcsr, dacsr; @@ -525,6 +530,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) static void dt282x_load_changain(struct comedi_device *dev, int n, unsigned int *chanlist) { + struct dt282x_private *devpriv = dev->private; unsigned int i; unsigned int chan, range; @@ -548,6 +554,7 @@ 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; int i; /* XXX should we really be enabling the ad clock here? */ @@ -604,52 +611,30 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } if (cmd->scan_begin_src == TRIG_FOLLOW) { /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } - if (cmd->convert_arg < 4000) { - /* XXX board dependent */ - cmd->convert_arg = 4000; - err++; + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } + + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 4000); + #define SLOWEST_TIMER (250*(1<<15)*255) - if (cmd->convert_arg > SLOWEST_TIMER) { - cmd->convert_arg = SLOWEST_TIMER; - err++; - } - if (cmd->convert_arg < board->ai_speed) { - cmd->convert_arg = board->ai_speed; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, SLOWEST_TIMER); + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, board->ai_speed); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -671,6 +656,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct dt282x_board *board = comedi_board(dev); + struct dt282x_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int timer; @@ -733,6 +719,8 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static void dt282x_disable_dma(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; + if (devpriv->usedma) { disable_dma(devpriv->dma[0].chan); disable_dma(devpriv->dma[1].chan); @@ -742,6 +730,8 @@ static void dt282x_disable_dma(struct comedi_device *dev) 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; @@ -794,6 +784,8 @@ static int dt282x_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt282x_private *devpriv = dev->private; + data[0] = devpriv->ao[CR_CHAN(insn->chanspec)]; return 1; @@ -803,6 +795,7 @@ 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; short d; unsigned int chan; @@ -859,33 +852,17 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 5000); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, 2); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg < 5000 /* XXX unknown */) { - cmd->scan_begin_arg = 5000; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg > 2) { - /* XXX chanlist stuff? */ - cmd->scan_end_arg = 2; - err++; - } if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -908,6 +885,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int x) { + struct dt282x_private *devpriv = dev->private; int size; if (x != 0) @@ -937,6 +915,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt282x_private *devpriv = dev->private; int timer; struct comedi_cmd *cmd = &s->async->cmd; @@ -973,6 +952,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int dt282x_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt282x_private *devpriv = dev->private; + dt282x_disable_dma(dev); devpriv->dacsr = 0; @@ -1003,6 +984,7 @@ 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; int mask; mask = (CR_CHAN(insn->chanspec) < 8) ? 0x00ff : 0xff00; @@ -1074,6 +1056,7 @@ enum { /* i/o base, irq, dma channels */ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) { + struct dt282x_private *devpriv = dev->private; int ret; devpriv->usedma = 0; @@ -1135,6 +1118,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dt282x_board *board = comedi_board(dev); + struct dt282x_private *devpriv; int i, irq; int ret; struct comedi_subdevice *s; @@ -1217,9 +1201,10 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif } - ret = alloc_private(dev, sizeof(struct dt282x_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = dt282x_grab_dma(dev, it->options[opt_dma1], it->options[opt_dma2]); @@ -1292,6 +1277,8 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void dt282x_detach(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; + if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 43d05ef..960da8d 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -29,11 +29,7 @@ Devices: [Data Translation] DT3001 (dt3000), DT3001-PGL, DT3002, DT3003, Updated: Mon, 14 Apr 2008 15:41:24 +0100 Status: works -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration Options: not applicable, uses PCI auto config There is code to support AI commands, but it may not work. @@ -65,26 +61,36 @@ AO commands are not supported. #include "comedi_fc.h" -#define PCI_VENDOR_ID_DT 0x1116 - -static const struct comedi_lrange range_dt3000_ai = { 4, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25) - } +/* + * PCI device id's supported by this driver + */ +#define PCI_DEVICE_ID_DT3001 0x0022 +#define PCI_DEVICE_ID_DT3002 0x0023 +#define PCI_DEVICE_ID_DT3003 0x0024 +#define PCI_DEVICE_ID_DT3004 0x0025 +#define PCI_DEVICE_ID_DT3005 0x0026 +#define PCI_DEVICE_ID_DT3001_PGL 0x0027 +#define PCI_DEVICE_ID_DT3003_PGL 0x0028 + +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, { - RANGE(-10, 10), - RANGE(-1, 1), - RANGE(-0.1, 0.1), - RANGE(-0.02, 0.02) - } +static const struct comedi_lrange range_dt3000_ai_pgl = { + 4, { + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.02) + } }; struct dt3k_boardtype { - const char *name; unsigned int device_id; int adchan; @@ -96,73 +102,70 @@ struct dt3k_boardtype { }; static const struct dt3k_boardtype dt3k_boardtypes[] = { - {.name = "dt3001", - .device_id = 0x22, - .adchan = 16, - .adbits = 12, - .adrange = &range_dt3000_ai, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3001-pgl", - .device_id = 0x27, - .adchan = 16, - .adbits = 12, - .adrange = &range_dt3000_ai_pgl, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3002", - .device_id = 0x23, - .adchan = 32, - .adbits = 12, - .adrange = &range_dt3000_ai, - .ai_speed = 3000, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt3003", - .device_id = 0x24, - .adchan = 64, - .adbits = 12, - .adrange = &range_dt3000_ai, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3003-pgl", - .device_id = 0x28, - .adchan = 64, - .adbits = 12, - .adrange = &range_dt3000_ai_pgl, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3004", - .device_id = 0x25, - .adchan = 16, - .adbits = 16, - .adrange = &range_dt3000_ai, - .ai_speed = 10000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3005", /* a.k.a. 3004-200 */ - .device_id = 0x26, - .adchan = 16, - .adbits = 16, - .adrange = &range_dt3000_ai, - .ai_speed = 5000, - .dachan = 2, - .dabits = 12, - }, + { + .name = "dt3001", + .device_id = PCI_DEVICE_ID_DT3001, + .adchan = 16, + .adbits = 12, + .adrange = &range_dt3000_ai, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3001-pgl", + .device_id = PCI_DEVICE_ID_DT3001_PGL, + .adchan = 16, + .adbits = 12, + .adrange = &range_dt3000_ai_pgl, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3002", + .device_id = PCI_DEVICE_ID_DT3002, + .adchan = 32, + .adbits = 12, + .adrange = &range_dt3000_ai, + .ai_speed = 3000, + }, { + .name = "dt3003", + .device_id = PCI_DEVICE_ID_DT3003, + .adchan = 64, + .adbits = 12, + .adrange = &range_dt3000_ai, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3003-pgl", + .device_id = PCI_DEVICE_ID_DT3003_PGL, + .adchan = 64, + .adbits = 12, + .adrange = &range_dt3000_ai_pgl, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3004", + .device_id = PCI_DEVICE_ID_DT3004, + .adchan = 16, + .adbits = 16, + .adrange = &range_dt3000_ai, + .ai_speed = 10000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3005", /* a.k.a. 3004-200 */ + .device_id = PCI_DEVICE_ID_DT3005, + .adchan = 16, + .adbits = 16, + .adrange = &range_dt3000_ai, + .ai_speed = 5000, + .dachan = 2, + .dabits = 12, + }, }; -#define this_board ((const struct dt3k_boardtype *)dev->board_ptr) - #define DT3000_SIZE (4*0x1000) /* dual-ported RAM location definitions */ @@ -257,22 +260,29 @@ struct dt3k_private { unsigned int ai_rear; }; -#define devpriv ((struct dt3k_private *)dev->private) - -static void dt3k_ai_empty_fifo(struct comedi_device *dev, - struct comedi_subdevice *s); -static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg, - unsigned int round_mode); -static int dt3k_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); #ifdef DEBUG -static void debug_intr_flags(unsigned int flags); +static char *intr_flags[] = { + "AdFull", "AdSwError", "AdHwError", "DaEmpty", + "DaSwError", "DaHwError", "CtDone", "CmDone", +}; + +static void debug_intr_flags(unsigned int flags) +{ + int i; + printk(KERN_DEBUG "dt3k: intr_flags:"); + for (i = 0; i < 8; i++) { + if (flags & (1 << i)) + printk(KERN_CONT " %s", intr_flags[i]); + } + printk(KERN_CONT "\n"); +} #endif #define TIMEOUT 100 -static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) +static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) { + struct dt3k_private *devpriv = dev->private; int i; unsigned int status = 0; @@ -284,19 +294,18 @@ static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) break; udelay(1); } - if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) - return 0; - - dev_dbg(dev->class_dev, "dt3k_send_cmd() timeout/error status=0x%04x\n", - status); - return -ETIME; + if ((status & DT3000_COMPLETION_MASK) != DT3000_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) { + struct dt3k_private *devpriv = dev->private; + writew(subsys, devpriv->io_addr + DPR_SubSys); writew(chan, devpriv->io_addr + DPR_Params(0)); @@ -310,6 +319,8 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev, static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys, unsigned int chan, unsigned int data) { + struct dt3k_private *devpriv = dev->private; + writew(subsys, devpriv->io_addr + DPR_SubSys); writew(chan, devpriv->io_addr + DPR_Params(0)); @@ -319,6 +330,47 @@ static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys, dt3k_send_cmd(dev, 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; + short data; + + front = readw(devpriv->io_addr + DPR_AD_Buf_Front); + count = front - devpriv->ai_front; + if (count < 0) + count += AI_FIFO_DEPTH; + + rear = devpriv->ai_rear; + + for (i = 0; i < count; i++) { + data = readw(devpriv->io_addr + DPR_ADC_buffer + rear); + comedi_buf_put(s->async, data); + rear++; + if (rear >= AI_FIFO_DEPTH) + rear = 0; + } + + devpriv->ai_rear = rear; + writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear); +} + +static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) +{ + struct dt3k_private *devpriv = dev->private; + + writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); + dt3k_send_cmd(dev, CMD_STOP); + + writew(0, devpriv->io_addr + DPR_Int_Mask); + + return 0; +} + static int debug_n_ints; /* FIXME! Assumes shared interrupt is for this card. */ @@ -326,6 +378,7 @@ static int debug_n_ints; static irqreturn_t dt3k_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct dt3k_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned int status; @@ -356,57 +409,45 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) return IRQ_HANDLED; } -#ifdef DEBUG -static char *intr_flags[] = { - "AdFull", "AdSwError", "AdHwError", "DaEmpty", - "DaSwError", "DaHwError", "CtDone", "CmDone", -}; - -static void debug_intr_flags(unsigned int flags) -{ - int i; - printk(KERN_DEBUG "dt3k: intr_flags:"); - for (i = 0; i < 8; i++) { - if (flags & (1 << i)) - printk(KERN_CONT " %s", intr_flags[i]); - } - printk(KERN_CONT "\n"); -} -#endif - -static void dt3k_ai_empty_fifo(struct comedi_device *dev, - struct comedi_subdevice *s) +static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, + unsigned int round_mode) { - int front; - int rear; - int count; - int i; - short data; - - front = readw(devpriv->io_addr + DPR_AD_Buf_Front); - count = front - devpriv->ai_front; - if (count < 0) - count += AI_FIFO_DEPTH; - - dev_dbg(dev->class_dev, "reading %d samples\n", count); + int divider, base, prescale; - rear = devpriv->ai_rear; + /* This function needs improvment */ + /* Don't know if divider==0 works. */ - for (i = 0; i < count; i++) { - data = readw(devpriv->io_addr + DPR_ADC_buffer + rear); - comedi_buf_put(s->async, data); - rear++; - if (rear >= AI_FIFO_DEPTH) - rear = 0; + for (prescale = 0; prescale < 16; prescale++) { + base = timer_base * (prescale + 1); + switch (round_mode) { + case TRIG_ROUND_NEAREST: + default: + divider = (*nanosec + base / 2) / base; + break; + case TRIG_ROUND_DOWN: + divider = (*nanosec) / base; + break; + case TRIG_ROUND_UP: + divider = (*nanosec) / base; + break; + } + if (divider < 65536) { + *nanosec = divider * base; + return (prescale << 16) | (divider); + } } - devpriv->ai_rear = rear; - writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear); + prescale = 15; + base = timer_base * (1 << prescale); + 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 *this_board = comedi_board(dev); int err = 0; int tmp; @@ -427,54 +468,30 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < this_board->ai_speed) { - cmd->scan_begin_arg = this_board->ai_speed; - err++; - } - if (cmd->scan_begin_arg > 100 * 16 * 65535) { - cmd->scan_begin_arg = 100 * 16 * 65535; - err++; - } - } else { - /* not supported */ + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + this_board->ai_speed); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + 100 * 16 * 65535); } + if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_speed) { - cmd->convert_arg = this_board->ai_speed; - err++; - } - if (cmd->convert_arg > 50 * 16 * 65535) { - cmd->convert_arg = 50 * 16 * 65535; - err++; - } - } else { - /* not supported */ + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + this_board->ai_speed); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + 50 * 16 * 65535); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -487,9 +504,8 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, cmd->flags & TRIG_ROUND_MASK); if (tmp != cmd->scan_begin_arg) err++; - } else { - /* not supported */ } + if (cmd->convert_src == TRIG_TIMER) { tmp = cmd->convert_arg; dt3k_ns_to_timer(50, &cmd->convert_arg, @@ -503,8 +519,6 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, cmd->convert_arg * cmd->scan_end_arg; err++; } - } else { - /* not supported */ } if (err) @@ -513,52 +527,16 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, return 0; } -static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, - unsigned int round_mode) -{ - int divider, base, prescale; - - /* This function needs improvment */ - /* Don't know if divider==0 works. */ - - for (prescale = 0; prescale < 16; prescale++) { - base = timer_base * (prescale + 1); - switch (round_mode) { - case TRIG_ROUND_NEAREST: - default: - divider = (*nanosec + base / 2) / base; - break; - case TRIG_ROUND_DOWN: - divider = (*nanosec) / base; - break; - case TRIG_ROUND_UP: - divider = (*nanosec) / base; - break; - } - if (divider < 65536) { - *nanosec = divider * base; - return (prescale << 16) | (divider); - } - } - - prescale = 15; - base = timer_base * (1 << prescale); - divider = 65535; - *nanosec = divider * base; - return (prescale << 16) | (divider); -} - static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt3k_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int i; unsigned int chan, range, aref; unsigned int divider; unsigned int tscandiv; - int ret; unsigned int mode; - dev_dbg(dev->class_dev, "dt3k_ai_cmd:\n"); for (i = 0; i < cmd->chanlist_len; i++) { chan = CR_CHAN(cmd->chanlist[i]); range = CR_RANGE(cmd->chanlist[i]); @@ -569,41 +547,29 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) aref = CR_AREF(cmd->chanlist[0]); writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0)); - dev_dbg(dev->class_dev, "param[0]=0x%04x\n", cmd->scan_end_arg); if (cmd->convert_src == TRIG_TIMER) { divider = dt3k_ns_to_timer(50, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); writew((divider >> 16), devpriv->io_addr + DPR_Params(1)); - dev_dbg(dev->class_dev, "param[1]=0x%04x\n", divider >> 16); writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2)); - dev_dbg(dev->class_dev, "param[2]=0x%04x\n", divider & 0xffff); - } else { - /* not supported */ } if (cmd->scan_begin_src == TRIG_TIMER) { tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3)); - dev_dbg(dev->class_dev, "param[3]=0x%04x\n", tscandiv >> 16); writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4)); - dev_dbg(dev->class_dev, "param[4]=0x%04x\n", tscandiv & 0xffff); - } else { - /* not supported */ } mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0; writew(mode, devpriv->io_addr + DPR_Params(5)); - dev_dbg(dev->class_dev, "param[5]=0x%04x\n", mode); writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6)); - dev_dbg(dev->class_dev, "param[6]=0x%04x\n", aref == AREF_DIFF); writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7)); - dev_dbg(dev->class_dev, "param[7]=0x%04x\n", AI_FIFO_DEPTH / 2); writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); - ret = dt3k_send_cmd(dev, CMD_CONFIG); + dt3k_send_cmd(dev, CMD_CONFIG); writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR, devpriv->io_addr + DPR_Int_Mask); @@ -611,19 +577,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) debug_n_ints = 0; writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); - ret = dt3k_send_cmd(dev, CMD_START); - - return 0; -} - -static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) -{ - int ret; - - writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); - ret = dt3k_send_cmd(dev, CMD_STOP); - - writew(0, devpriv->io_addr + DPR_Int_Mask); + dt3k_send_cmd(dev, CMD_START); return 0; } @@ -648,6 +602,7 @@ static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int dt3k_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt3k_private *devpriv = dev->private; int i; unsigned int chan; @@ -664,6 +619,7 @@ static int dt3k_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt3k_private *devpriv = dev->private; int i; unsigned int chan; @@ -676,6 +632,8 @@ static int dt3k_ao_insn_read(struct comedi_device *dev, static void dt3k_dio_config(struct comedi_device *dev, int bits) { + struct dt3k_private *devpriv = dev->private; + /* XXX */ writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys); @@ -739,6 +697,7 @@ static int dt3k_mem_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt3k_private *devpriv = dev->private; unsigned int addr = CR_CHAN(insn->chanspec); int i; @@ -755,54 +714,42 @@ static int dt3k_mem_insn_read(struct comedi_device *dev, return i; } -static struct pci_dev *dt3000_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *dt3000_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct dt3k_boardtype *this_board; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_DT) - continue; - for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) { - if (dt3k_boardtypes[i].device_id != pcidev->device) - continue; - dev->board_ptr = dt3k_boardtypes + i; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) { + this_board = &dt3k_boardtypes[i]; + if (this_board->device_id == pcidev->device) + return this_board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int dt3000_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { - struct pci_dev *pcidev; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct dt3k_boardtype *this_board; + struct dt3k_private *devpriv; struct comedi_subdevice *s; resource_size_t pci_base; int ret = 0; - dev_dbg(dev->class_dev, "dt3000:\n"); - - ret = alloc_private(dev, sizeof(struct dt3k_private)); - if (ret < 0) - return ret; + this_board = dt3000_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->name; - pcidev = dt3000_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; - ret = comedi_pci_enable(pcidev, "dt3000"); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret < 0) return ret; dev->iobase = 1; /* the "detach" needs this */ @@ -812,14 +759,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv->io_addr) return -ENOMEM; - dev->board_name = this_board->name; - - if (request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, - "dt3000", dev)) { - dev_err(dev->class_dev, "unable to allocate IRQ %u\n", - pcidev->irq); - return -EINVAL; - } + ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret) + return ret; dev->irq = pcidev->irq; ret = comedi_alloc_subdevices(dev, 4); @@ -828,50 +771,49 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[0]; dev->read_subdev = s; - /* ai subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; - s->n_chan = this_board->adchan; - s->insn_read = dt3k_ai_insn; - s->maxdata = (1 << this_board->adbits) - 1; - s->len_chanlist = 512; - s->range_table = &range_dt3000_ai; /* XXX */ - s->do_cmd = dt3k_ai_cmd; - s->do_cmdtest = dt3k_ai_cmdtest; - s->cancel = dt3k_ai_cancel; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->n_chan = this_board->adchan; + s->insn_read = dt3k_ai_insn; + s->maxdata = (1 << this_board->adbits) - 1; + s->len_chanlist = 512; + s->range_table = &range_dt3000_ai; /* XXX */ + s->do_cmd = dt3k_ai_cmd; + s->do_cmdtest = dt3k_ai_cmdtest; + s->cancel = dt3k_ai_cancel; s = &dev->subdevices[1]; /* ao subsystem */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 2; - s->insn_read = dt3k_ao_insn_read; - s->insn_write = dt3k_ao_insn; - s->maxdata = (1 << this_board->dabits) - 1; - s->len_chanlist = 1; - s->range_table = &range_bipolar10; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 2; + s->insn_read = dt3k_ao_insn_read; + s->insn_write = dt3k_ao_insn; + s->maxdata = (1 << this_board->dabits) - 1; + s->len_chanlist = 1; + s->range_table = &range_bipolar10; s = &dev->subdevices[2]; /* dio subsystem */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->insn_config = dt3k_dio_insn_config; - s->insn_bits = dt3k_dio_insn_bits; - s->maxdata = 1; - s->len_chanlist = 8; - s->range_table = &range_digital; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->insn_config = dt3k_dio_insn_config; + s->insn_bits = dt3k_dio_insn_bits; + s->maxdata = 1; + s->len_chanlist = 8; + s->range_table = &range_digital; s = &dev->subdevices[3]; /* mem subsystem */ - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE; - s->n_chan = 0x1000; - s->insn_read = dt3k_mem_insn_read; - s->maxdata = 0xff; - s->len_chanlist = 1; - s->range_table = &range_unknown; + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE; + s->n_chan = 0x1000; + s->insn_read = dt3k_mem_insn_read; + s->maxdata = 0xff; + s->len_chanlist = 1; + s->range_table = &range_unknown; #if 0 s = &dev->subdevices[4]; @@ -879,12 +821,15 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_PROC; #endif + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + return 0; } static void dt3000_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct dt3k_private *devpriv = dev->private; if (dev->irq) free_irq(dev->irq, dev); @@ -895,36 +840,35 @@ static void dt3000_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver dt3000_driver = { .driver_name = "dt3000", .module = THIS_MODULE, - .attach = dt3000_attach, + .auto_attach = dt3000_auto_attach, .detach = dt3000_detach, }; -static int __devinit dt3000_pci_probe(struct pci_dev *dev, +static int dt3000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &dt3000_driver); } -static void __devexit dt3000_pci_remove(struct pci_dev *dev) +static void dt3000_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001_PGL) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3002) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003_PGL) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3004) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3005) }, { 0 } }; MODULE_DEVICE_TABLE(pci, dt3000_pci_table); @@ -933,7 +877,7 @@ static struct pci_driver dt3000_pci_driver = { .name = "dt3000", .id_table = dt3000_pci_table, .probe = dt3000_pci_probe, - .remove = __devexit_p(dt3000_pci_remove), + .remove = dt3000_pci_remove, }; module_comedi_pci_driver(dt3000_driver, dt3000_pci_driver); diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index bc6f409..1767998 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -43,6 +43,8 @@ for my needs. * says P1). */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/errno.h> #include <linux/init.h> @@ -323,9 +325,6 @@ static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, { static struct slot_dt9812 dt9812[DT9812_NUM_SLOTS]; -/* Useful shorthand access to private data */ -#define devpriv ((struct comedi_dt9812 *)dev->private) - static inline struct usb_dt9812 *to_dt9812_dev(struct kref *d) { return container_of(d, struct usb_dt9812, kref); @@ -893,6 +892,7 @@ static struct usb_driver dt9812_usb_driver = { static int dt9812_comedi_open(struct comedi_device *dev) { + struct comedi_dt9812 *devpriv = dev->private; int result = -ENODEV; down(&devpriv->slot->mutex); @@ -947,6 +947,7 @@ static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; u8 bits = 0; @@ -960,6 +961,7 @@ static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; u8 bits = 0; @@ -979,6 +981,7 @@ static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; for (n = 0; n < insn->n; n++) { @@ -995,6 +998,7 @@ static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; u16 value; @@ -1010,6 +1014,7 @@ static int dt9812_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; for (n = 0; n < insn->n; n++) @@ -1019,14 +1024,17 @@ static int dt9812_ao_winsn(struct comedi_device *dev, static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct comedi_dt9812 *devpriv; int i; struct comedi_subdevice *s; int ret; dev->board_name = "dt9812"; - if (alloc_private(dev, sizeof(struct comedi_dt9812)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; /* * Special open routine, since USB unit may be unattached at @@ -1077,8 +1085,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = &dt9812_ao_winsn; s->insn_read = &dt9812_ao_rinsn; - printk(KERN_INFO "comedi%d: successfully attached to dt9812.\n", - dev->minor); + dev_info(dev->class_dev, "successfully attached to dt9812.\n"); down(&dt9812_mutex); /* Find a slot for the comedi device */ @@ -1140,17 +1147,15 @@ static int __init usb_dt9812_init(void) /* register with the USB subsystem */ result = usb_register(&dt9812_usb_driver); if (result) { - printk(KERN_ERR KBUILD_MODNAME - ": usb_register failed. Error number %d\n", result); + pr_err("usb_register failed. Error number %d\n", result); return result; } /* register with comedi */ result = comedi_driver_register(&dt9812_comedi_driver); if (result) { usb_deregister(&dt9812_usb_driver); - printk(KERN_ERR KBUILD_MODNAME - ": comedi_driver_register failed. Error number %d\n", - result); + pr_err("comedi_driver_register failed. Error number %d\n", + result); } return result; diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 6f612be..8497a36 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -40,8 +40,6 @@ #include "../comedidev.h" #include <linux/mutex.h> -#define PCI_VENDOR_ID_DYNALOG 0x10b5 - #define READ_TIMEOUT 50 static const struct comedi_lrange range_pci1050_ai = { 3, { @@ -179,21 +177,20 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, return insn->n; } -static int dyna_pci10xx_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +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; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -269,23 +266,23 @@ static void dyna_pci10xx_detach(struct comedi_device *dev) static struct comedi_driver dyna_pci10xx_driver = { .driver_name = "dyna_pci10xx", .module = THIS_MODULE, - .attach_pci = dyna_pci10xx_attach_pci, + .auto_attach = dyna_pci10xx_auto_attach, .detach = dyna_pci10xx_detach, }; -static int __devinit dyna_pci10xx_pci_probe(struct pci_dev *dev, +static int dyna_pci10xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &dyna_pci10xx_driver); } -static void __devexit dyna_pci10xx_pci_remove(struct pci_dev *dev) +static void dyna_pci10xx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) }, + { PCI_DEVICE(PCI_VENDOR_ID_PLX, 0x1050) }, { 0 } }; MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table); @@ -294,7 +291,7 @@ static struct pci_driver dyna_pci10xx_pci_driver = { .name = "dyna_pci10xx", .id_table = dyna_pci10xx_pci_table, .probe = dyna_pci10xx_pci_probe, - .remove = __devexit_p(dyna_pci10xx_pci_remove), + .remove = dyna_pci10xx_pci_remove, }; module_comedi_pci_driver(dyna_pci10xx_driver, dyna_pci10xx_pci_driver); diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index ae8e8f4..019c96e 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -29,8 +29,6 @@ struct fl512_private { short ao_readback[2]; }; -#define devpriv ((struct fl512_private *) dev->private) - static const struct comedi_lrange range_fl512 = { 4, { BIP_RANGE(0.5), BIP_RANGE(1), @@ -75,6 +73,7 @@ static int fl512_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct fl512_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); /* get chan to write */ unsigned long iobase = dev->iobase; /* get base address */ @@ -99,6 +98,7 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct fl512_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -110,6 +110,7 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct fl512_private *devpriv; unsigned long iobase; int ret; @@ -125,8 +126,11 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; dev->board_name = "fl512"; - if (alloc_private(dev, sizeof(struct fl512_private)) < 0) + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; #if DEBUG printk(KERN_DEBUG "malloc ok\n"); diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index abff660..154598f 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -26,24 +26,26 @@ ************************************************************************/ /* + * 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. + */ -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: 2003-02-20 -Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi), - PMC-HPDI32 - -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - -There are some additional hpdi models available from GSC for which -support could be added to this driver. - -*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/interrupt.h> #include "../comedidev.h" @@ -64,9 +66,9 @@ static int dio_config_block_size(struct comedi_device *dev, unsigned int *data); /* #define HPDI_DEBUG enable debugging code */ #ifdef HPDI_DEBUG -#define DEBUG_PRINT(format, args...) printk(format , ## args) +#define DEBUG_PRINT(format, args...) pr_debug(format , ## args) #else -#define DEBUG_PRINT(format, args...) +#define DEBUG_PRINT(format, args...) no_printk(pr_fmt(format), ## args) #endif #define TIMER_BASE 50 /* 20MHz master clock */ @@ -104,35 +106,11 @@ enum hpdi_registers { INTERRUPT_POLARITY_REG = 0x54, }; -int command_channel_valid(unsigned int channel) -{ - if (channel == 0 || channel > 6) { - printk(KERN_WARNING - "gsc_hpdi: bug! invalid cable command channel\n"); - return 0; - } - return 1; -} - /* bit definitions */ enum firmware_revision_bits { FEATURES_REG_PRESENT_BIT = 0x8000, }; -int firmware_revision(uint32_t fwr_bits) -{ - return fwr_bits & 0xff; -} - -int pcb_revision(uint32_t fwr_bits) -{ - return (fwr_bits >> 8) & 0xff; -} - -int hpdi_subid(uint32_t fwr_bits) -{ - return (fwr_bits >> 16) & 0xff; -} enum board_control_bits { BOARD_RESET_BIT = 0x1, /* wait 10usec before accessing fifos */ @@ -147,22 +125,6 @@ enum board_control_bits { CABLE_THROTTLE_ENABLE_BIT = 0x20, TEST_MODE_ENABLE_BIT = 0x80000000, }; -uint32_t command_discrete_output_bits(unsigned int channel, int output, - int output_value) -{ - uint32_t bits = 0; - - if (command_channel_valid(channel) == 0) - return 0; - if (output) { - bits |= 0x1 << (16 + channel); - if (output_value) - bits |= 0x1 << (24 + channel); - } else - bits |= 0x1 << (24 + channel); - - return bits; -} enum board_status_bits { COMMAND_LINE_STATUS_MASK = 0x7f, @@ -182,28 +144,17 @@ enum board_status_bits { RX_OVERRUN_BIT = 0x800000, }; -uint32_t almost_full_bits(unsigned int num_words) +static uint32_t almost_full_bits(unsigned int num_words) { -/* XXX need to add or subtract one? */ + /* XXX need to add or subtract one? */ return (num_words << 16) & 0xff0000; } -uint32_t almost_empty_bits(unsigned int num_words) +static uint32_t almost_empty_bits(unsigned int num_words) { return num_words & 0xffff; } -unsigned int almost_full_num_words(uint32_t bits) -{ -/* XXX need to add or subtract one? */ - return (bits >> 16) & 0xffff; -} - -unsigned int almost_empty_num_words(uint32_t bits) -{ - return bits & 0xffff; -} - enum features_bits { FIFO_SIZE_PRESENT_BIT = 0x1, FIFO_WORDS_PRESENT_BIT = 0x2, @@ -225,46 +176,19 @@ enum interrupt_sources { RX_ALMOST_FULL_INTR = 14, RX_FULL_INTR = 15, }; -int command_intr_source(unsigned int channel) -{ - if (command_channel_valid(channel) == 0) - channel = 1; - return channel + 1; -} -uint32_t intr_bit(int interrupt_source) +static uint32_t intr_bit(int interrupt_source) { return 0x1 << interrupt_source; } -uint32_t tx_clock_divisor_bits(unsigned int divisor) -{ - return divisor & 0xff; -} - -unsigned int fifo_size(uint32_t fifo_size_bits) +static unsigned int fifo_size(uint32_t fifo_size_bits) { return fifo_size_bits & 0xfffff; } -unsigned int fifo_words(uint32_t fifo_words_bits) -{ - return fifo_words_bits & 0xfffff; -} - -uint32_t intr_edge_bit(int interrupt_source) -{ - return 0x1 << interrupt_source; -} - -uint32_t intr_active_high_bit(int interrupt_source) -{ - return 0x1 << interrupt_source; -} - struct hpdi_board { - - char *name; + const char *name; /* board name */ int device_id; /* pci device id */ int subdevice_id; /* pci subdevice id */ }; @@ -284,17 +208,7 @@ static const struct hpdi_board hpdi_boards[] = { #endif }; -static inline struct hpdi_board *board(const struct comedi_device *dev) -{ - return (struct hpdi_board *)dev->board_ptr; -} - struct hpdi_private { - - struct pci_dev *hw_dev; /* pointer to board's pci_dev struct */ - /* base addresses (physical) */ - resource_size_t plx9080_phys_iobase; - resource_size_t hpdi_phys_iobase; /* base addresses (ioremapped) */ void __iomem *plx9080_iobase; void __iomem *hpdi_iobase; @@ -321,27 +235,24 @@ struct hpdi_private { unsigned dio_config_output:1; }; -static inline struct hpdi_private *priv(struct comedi_device *dev) -{ - return dev->private; -} - static int dio_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct hpdi_private *devpriv = dev->private; + switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - priv(dev)->dio_config_output = 1; + devpriv->dio_config_output = 1; return insn->n; break; case INSN_CONFIG_DIO_INPUT: - priv(dev)->dio_config_output = 0; + devpriv->dio_config_output = 0; return insn->n; break; case INSN_CONFIG_DIO_QUERY: data[1] = - priv(dev)->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT; + devpriv->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT; return insn->n; break; case INSN_CONFIG_BLOCK_SIZE: @@ -356,21 +267,24 @@ static int dio_config_insn(struct comedi_device *dev, static void disable_plx_interrupts(struct comedi_device *dev) { - writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + struct hpdi_private *devpriv = dev->private; + + writel(0, devpriv->plx9080_iobase + PLX_INTRCS_REG); } /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { + struct hpdi_private *devpriv = dev->private; uint32_t bits; - void __iomem *plx_iobase = priv(dev)->plx9080_iobase; + void __iomem *plx_iobase = devpriv->plx9080_iobase; /* plx9080 dump */ DEBUG_PRINT(" plx interrupt status 0x%x\n", readl(plx_iobase + PLX_INTRCS_REG)); DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); DEBUG_PRINT(" plx control reg 0x%x\n", - readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG)); + readl(devpriv->plx9080_iobase + PLX_CONTROL_REG)); DEBUG_PRINT(" plx revision 0x%x\n", readl(plx_iobase + PLX_REVISION_REG)); @@ -396,7 +310,7 @@ static void init_plx9080(struct comedi_device *dev) #else bits = 0; #endif - writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG); + writel(bits, devpriv->plx9080_iobase + PLX_BIGEND_REG); disable_plx_interrupts(dev); @@ -457,28 +371,29 @@ static int setup_subdevices(struct comedi_device *dev) static int init_hpdi(struct comedi_device *dev) { + struct hpdi_private *devpriv = dev->private; uint32_t plx_intcsr_bits; - writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG); + writel(BOARD_RESET_BIT, devpriv->hpdi_iobase + BOARD_CONTROL_REG); udelay(10); writel(almost_empty_bits(32) | almost_full_bits(32), - priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG); + devpriv->hpdi_iobase + RX_PROG_ALMOST_REG); writel(almost_empty_bits(32) | almost_full_bits(32), - priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG); + devpriv->hpdi_iobase + TX_PROG_ALMOST_REG); - priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase + + devpriv->tx_fifo_size = fifo_size(readl(devpriv->hpdi_iobase + TX_FIFO_SIZE_REG)); - priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase + + devpriv->rx_fifo_size = fifo_size(readl(devpriv->hpdi_iobase + RX_FIFO_SIZE_REG)); - writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG); + writel(0, devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); /* enable interrupts */ plx_intcsr_bits = ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE | ICS_DMA0_E; - writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + writel(plx_intcsr_bits, devpriv->plx9080_iobase + PLX_INTRCS_REG); return 0; } @@ -487,6 +402,7 @@ static int init_hpdi(struct comedi_device *dev) static int setup_dma_descriptors(struct comedi_device *dev, unsigned int transfer_size) { + struct hpdi_private *devpriv = dev->private; unsigned int buffer_index, buffer_offset; uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI; @@ -500,25 +416,25 @@ static int setup_dma_descriptors(struct comedi_device *dev, DEBUG_PRINT(" transfer_size %i\n", transfer_size); DEBUG_PRINT(" descriptors at 0x%lx\n", - (unsigned long)priv(dev)->dma_desc_phys_addr); + (unsigned long)devpriv->dma_desc_phys_addr); buffer_offset = 0; buffer_index = 0; for (i = 0; i < NUM_DMA_DESCRIPTORS && buffer_index < NUM_DMA_BUFFERS; i++) { - priv(dev)->dma_desc[i].pci_start_addr = - cpu_to_le32(priv(dev)->dio_buffer_phys_addr[buffer_index] + + devpriv->dma_desc[i].pci_start_addr = + cpu_to_le32(devpriv->dio_buffer_phys_addr[buffer_index] + buffer_offset); - priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG); - priv(dev)->dma_desc[i].transfer_size = + devpriv->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG); + devpriv->dma_desc[i].transfer_size = cpu_to_le32(transfer_size); - priv(dev)->dma_desc[i].next = - cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i + + devpriv->dma_desc[i].next = + cpu_to_le32((devpriv->dma_desc_phys_addr + (i + 1) * - sizeof(priv(dev)->dma_desc[0])) | next_bits); + sizeof(devpriv->dma_desc[0])) | next_bits); - priv(dev)->desc_dio_buffer[i] = - priv(dev)->dio_buffer[buffer_index] + + devpriv->desc_dio_buffer[i] = + devpriv->dio_buffer[buffer_index] + (buffer_offset / sizeof(uint32_t)); buffer_offset += transfer_size; @@ -529,128 +445,110 @@ static int setup_dma_descriptors(struct comedi_device *dev, DEBUG_PRINT(" desc %i\n", i); DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n", - priv(dev)->desc_dio_buffer[i], - (unsigned long)priv(dev)->dma_desc[i]. + devpriv->desc_dio_buffer[i], + (unsigned long)devpriv->dma_desc[i]. pci_start_addr); DEBUG_PRINT(" next 0x%lx\n", - (unsigned long)priv(dev)->dma_desc[i].next); + (unsigned long)devpriv->dma_desc[i].next); } - priv(dev)->num_dma_descriptors = i; + devpriv->num_dma_descriptors = i; /* fix last descriptor to point back to first */ - priv(dev)->dma_desc[i - 1].next = - cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits); + devpriv->dma_desc[i - 1].next = + cpu_to_le32(devpriv->dma_desc_phys_addr | next_bits); DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1, - (unsigned long)priv(dev)->dma_desc[i - 1].next); + (unsigned long)devpriv->dma_desc[i - 1].next); - priv(dev)->block_size = transfer_size; + devpriv->block_size = transfer_size; return transfer_size; } -static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static const struct hpdi_board *hpdi_find_board(struct pci_dev *pcidev) { - struct pci_dev *pcidev; - int i; - int retval; + unsigned int i; - printk(KERN_WARNING "comedi%d: gsc_hpdi\n", dev->minor); + for (i = 0; i < ARRAY_SIZE(hpdi_boards); i++) + if (pcidev->device == hpdi_boards[i].device_id && + pcidev->subsystem_device == hpdi_boards[i].subdevice_id) + return &hpdi_boards[i]; + return NULL; +} - if (alloc_private(dev, sizeof(struct hpdi_private)) < 0) - return -ENOMEM; +static int hpdi_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct hpdi_board *thisboard; + struct hpdi_private *devpriv; + int i; + int retval; - pcidev = NULL; - for (i = 0; i < ARRAY_SIZE(hpdi_boards) && - dev->board_ptr == NULL; i++) { - do { - pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX, - hpdi_boards[i].device_id, - PCI_VENDOR_ID_PLX, - hpdi_boards[i].subdevice_id, - pcidev); - /* was a particular bus/slot requested? */ - if (it->options[0] || it->options[1]) { - /* are we on the wrong bus/slot? */ - if (pcidev->bus->number != it->options[0] || - PCI_SLOT(pcidev->devfn) != it->options[1]) - continue; - } - if (pcidev) { - priv(dev)->hw_dev = pcidev; - dev->board_ptr = hpdi_boards + i; - break; - } - } while (pcidev != NULL); - } - if (dev->board_ptr == NULL) { - printk(KERN_WARNING "gsc_hpdi: no hpdi card found\n"); - return -EIO; + thisboard = hpdi_find_board(pcidev); + if (!thisboard) { + dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n", + pci_name(pcidev)); + return -EINVAL; } + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; - printk(KERN_WARNING - "gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name, - pcidev->bus->number, PCI_SLOT(pcidev->devfn)); + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - printk(KERN_WARNING - " failed enable PCI device and request regions\n"); + if (comedi_pci_enable(pcidev, dev->board_name)) { + dev_warn(dev->class_dev, + "failed enable PCI device and request regions\n"); return -EIO; } + dev->iobase = 1; /* the "detach" needs this */ pci_set_master(pcidev); - /* Initialize dev->board_name */ - dev->board_name = board(dev)->name; - - priv(dev)->plx9080_phys_iobase = - pci_resource_start(pcidev, PLX9080_BADDRINDEX); - priv(dev)->hpdi_phys_iobase = - pci_resource_start(pcidev, HPDI_BADDRINDEX); - - /* remap, won't work with 2.0 kernels but who cares */ - priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase, - pci_resource_len(pcidev, - PLX9080_BADDRINDEX)); - priv(dev)->hpdi_iobase = - ioremap(priv(dev)->hpdi_phys_iobase, - pci_resource_len(pcidev, HPDI_BADDRINDEX)); - if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) { - printk(KERN_WARNING " failed to remap io memory\n"); + devpriv->plx9080_iobase = + ioremap(pci_resource_start(pcidev, PLX9080_BADDRINDEX), + pci_resource_len(pcidev, PLX9080_BADDRINDEX)); + devpriv->hpdi_iobase = + ioremap(pci_resource_start(pcidev, HPDI_BADDRINDEX), + pci_resource_len(pcidev, HPDI_BADDRINDEX)); + if (!devpriv->plx9080_iobase || !devpriv->hpdi_iobase) { + dev_warn(dev->class_dev, "failed to remap io memory\n"); return -ENOMEM; } - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase); - DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase); + DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); + DEBUG_PRINT(" hpdi remapped to 0x%p\n", devpriv->hpdi_iobase); init_plx9080(dev); /* get irq */ if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, - dev->driver->driver_name, dev)) { - printk(KERN_WARNING - " unable to allocate irq %u\n", pcidev->irq); + dev->board_name, dev)) { + dev_warn(dev->class_dev, + "unable to allocate irq %u\n", pcidev->irq); return -EINVAL; } dev->irq = pcidev->irq; - printk(KERN_WARNING " irq %u\n", dev->irq); + dev_dbg(dev->class_dev, " irq %u\n", dev->irq); /* allocate pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { - priv(dev)->dio_buffer[i] = - pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE, - &priv(dev)->dio_buffer_phys_addr[i]); + devpriv->dio_buffer[i] = + pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, + &devpriv->dio_buffer_phys_addr[i]); DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n", - priv(dev)->dio_buffer[i], - (unsigned long)priv(dev)->dio_buffer_phys_addr[i]); + devpriv->dio_buffer[i], + (unsigned long)devpriv->dio_buffer_phys_addr[i]); } /* allocate dma descriptors */ - priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev, - sizeof(struct plx_dma_desc) * - NUM_DMA_DESCRIPTORS, - &priv(dev)-> - dma_desc_phys_addr); - if (priv(dev)->dma_desc_phys_addr & 0xf) { - printk(KERN_WARNING - " dma descriptors not quad-word aligned (bug)\n"); + devpriv->dma_desc = pci_alloc_consistent(pcidev, + sizeof(struct plx_dma_desc) * + NUM_DMA_DESCRIPTORS, + &devpriv->dma_desc_phys_addr); + if (devpriv->dma_desc_phys_addr & 0xf) { + dev_warn(dev->class_dev, + " dma descriptors not quad-word aligned (bug)\n"); return -EIO; } @@ -667,39 +565,37 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void hpdi_detach(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct hpdi_private *devpriv = dev->private; unsigned int i; if (dev->irq) free_irq(dev->irq, dev); - if ((priv(dev)) && (priv(dev)->hw_dev)) { - if (priv(dev)->plx9080_iobase) { + if (devpriv) { + if (devpriv->plx9080_iobase) { disable_plx_interrupts(dev); - iounmap(priv(dev)->plx9080_iobase); + iounmap(devpriv->plx9080_iobase); } - if (priv(dev)->hpdi_iobase) - iounmap(priv(dev)->hpdi_iobase); + if (devpriv->hpdi_iobase) + iounmap(devpriv->hpdi_iobase); /* free pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { - if (priv(dev)->dio_buffer[i]) - pci_free_consistent(priv(dev)->hw_dev, + if (devpriv->dio_buffer[i]) + pci_free_consistent(pcidev, DMA_BUFFER_SIZE, - priv(dev)-> - dio_buffer[i], - priv - (dev)->dio_buffer_phys_addr - [i]); + devpriv->dio_buffer[i], + devpriv-> + dio_buffer_phys_addr[i]); } /* free dma descriptors */ - if (priv(dev)->dma_desc) - pci_free_consistent(priv(dev)->hw_dev, - sizeof(struct plx_dma_desc) - * NUM_DMA_DESCRIPTORS, - priv(dev)->dma_desc, - priv(dev)-> - dma_desc_phys_addr); - if (priv(dev)->hpdi_phys_iobase) - comedi_pci_disable(priv(dev)->hw_dev); - pci_dev_put(priv(dev)->hw_dev); + if (devpriv->dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + NUM_DMA_DESCRIPTORS, + devpriv->dma_desc, + devpriv->dma_desc_phys_addr); + if (dev->iobase) + comedi_pci_disable(pcidev); } } @@ -745,29 +641,20 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (!cmd->chanlist_len) { cmd->chanlist_len = 32; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= -EINVAL; } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; @@ -803,7 +690,9 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - if (priv(dev)->dio_config_output) + struct hpdi_private *devpriv = dev->private; + + if (devpriv->dio_config_output) return -EINVAL; else return di_cmd_test(dev, s, cmd); @@ -812,12 +701,15 @@ static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, static inline void hpdi_writel(struct comedi_device *dev, uint32_t bits, unsigned int offset) { - writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)], - priv(dev)->hpdi_iobase + offset); + struct hpdi_private *devpriv = dev->private; + + writel(bits | devpriv->bits[offset / sizeof(uint32_t)], + devpriv->hpdi_iobase + offset); } static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct hpdi_private *devpriv = dev->private; uint32_t bits; unsigned long flags; struct comedi_async *async = s->async; @@ -829,39 +721,39 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) abort_dma(dev, 0); - priv(dev)->dma_desc_index = 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, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); /* give location of first dma descriptor */ bits = - priv(dev)->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | + devpriv->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI; - writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + writel(bits, devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); /* spinlock for plx dma control/status reg */ spin_lock_irqsave(&dev->spinlock, flags); /* enable dma transfer */ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); if (cmd->stop_src == TRIG_COUNT) - priv(dev)->dio_count = cmd->stop_arg; + devpriv->dio_count = cmd->stop_arg; else - priv(dev)->dio_count = 1; + devpriv->dio_count = 1; /* clear over/under run status flags */ writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT, - priv(dev)->hpdi_iobase + BOARD_STATUS_REG); + devpriv->hpdi_iobase + BOARD_STATUS_REG); /* enable interrupts */ writel(intr_bit(RX_FULL_INTR), - priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG); + devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); DEBUG_PRINT("hpdi: starting rx\n"); hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG); @@ -871,7 +763,9 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - if (priv(dev)->dio_config_output) + struct hpdi_private *devpriv = dev->private; + + if (devpriv->dio_config_output) return -EINVAL; else return di_cmd(dev, s); @@ -879,6 +773,7 @@ static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { + struct hpdi_private *devpriv = dev->private; struct comedi_async *async = dev->read_subdev->async; uint32_t next_transfer_addr; int j; @@ -887,37 +782,37 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) if (channel) pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; else pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; /* loop until we have read all the full buffers */ j = 0; for (next_transfer_addr = readl(pci_addr_reg); (next_transfer_addr < - le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index]. + le32_to_cpu(devpriv->dma_desc[devpriv->dma_desc_index]. pci_start_addr) || next_transfer_addr >= - le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index]. - pci_start_addr) + priv(dev)->block_size) - && j < priv(dev)->num_dma_descriptors; j++) { + le32_to_cpu(devpriv->dma_desc[devpriv->dma_desc_index]. + pci_start_addr) + devpriv->block_size) + && j < devpriv->num_dma_descriptors; j++) { /* transfer data from dma buffer to comedi buffer */ - num_samples = priv(dev)->block_size / sizeof(uint32_t); + num_samples = devpriv->block_size / sizeof(uint32_t); if (async->cmd.stop_src == TRIG_COUNT) { - if (num_samples > priv(dev)->dio_count) - num_samples = priv(dev)->dio_count; - priv(dev)->dio_count -= num_samples; + if (num_samples > devpriv->dio_count) + num_samples = devpriv->dio_count; + devpriv->dio_count -= num_samples; } cfc_write_array_to_buffer(dev->read_subdev, - priv(dev)->desc_dio_buffer[priv(dev)-> + devpriv->desc_dio_buffer[devpriv-> dma_desc_index], num_samples * sizeof(uint32_t)); - priv(dev)->dma_desc_index++; - priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors; + devpriv->dma_desc_index++; + devpriv->dma_desc_index %= devpriv->num_dma_descriptors; DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long) - priv(dev)->dma_desc[priv(dev)->dma_desc_index]. + devpriv->dma_desc[devpriv->dma_desc_index]. next); DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } @@ -927,6 +822,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) static irqreturn_t handle_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; uint32_t hpdi_intr_status, hpdi_board_status; @@ -938,26 +834,26 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (!dev->attached) return IRQ_NONE; - plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) return IRQ_NONE; - hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG); - hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG); + hpdi_intr_status = readl(devpriv->hpdi_iobase + INTERRUPT_STATUS_REG); + hpdi_board_status = readl(devpriv->hpdi_iobase + BOARD_STATUS_REG); async->events = 0; if (hpdi_intr_status) { DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status); writel(hpdi_intr_status, - priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG); + devpriv->hpdi_iobase + INTERRUPT_STATUS_REG); } /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) @@ -968,10 +864,10 @@ static irqreturn_t handle_interrupt(int irq, void *d) /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + dma1_status = readb(devpriv->plx9080_iobase + PLX_DMA1_CS_REG); if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + devpriv->plx9080_iobase + PLX_DMA1_CS_REG); DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); DEBUG_PRINT(" cleared dma ch1 interrupt\n"); @@ -980,8 +876,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) /* clear possible plx9080 interrupt sources */ if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ - plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); - writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); + plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); + writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } @@ -989,7 +885,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) comedi_error(dev, "rx fifo overrun"); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; DEBUG_PRINT("dma0_status 0x%x\n", - (int)readb(priv(dev)->plx9080_iobase + + (int)readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG)); } @@ -998,7 +894,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } - if (priv(dev)->dio_count == 0) + if (devpriv->dio_count == 0) async->events |= COMEDI_CB_EOA; DEBUG_PRINT("board status 0x%x, ", hpdi_board_status); @@ -1013,21 +909,24 @@ static irqreturn_t handle_interrupt(int irq, void *d) static void 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(priv(dev)->plx9080_iobase, channel); + plx9080_abort_dma(devpriv->plx9080_iobase, channel); spin_unlock_irqrestore(&dev->spinlock, flags); } static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct hpdi_private *devpriv = dev->private; + hpdi_writel(dev, 0, BOARD_CONTROL_REG); - writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG); + writel(0, devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); abort_dma(dev, 0); @@ -1037,17 +936,17 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static struct comedi_driver gsc_hpdi_driver = { .driver_name = "gsc_hpdi", .module = THIS_MODULE, - .attach = hpdi_attach, + .auto_attach = hpdi_auto_attach, .detach = hpdi_detach, }; -static int __devinit gsc_hpdi_pci_probe(struct pci_dev *dev, +static int gsc_hpdi_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &gsc_hpdi_driver); } -static void __devexit gsc_hpdi_pci_remove(struct pci_dev *dev) +static void gsc_hpdi_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1063,7 +962,7 @@ static struct pci_driver gsc_hpdi_pci_driver = { .name = "gsc_hpdi", .id_table = gsc_hpdi_pci_table, .probe = gsc_hpdi_pci_probe, - .remove = __devexit_p(gsc_hpdi_pci_remove) + .remove = gsc_hpdi_pci_remove }; module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver); diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index d696d4d..a91a448 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -494,21 +494,21 @@ static int icp_multi_reset(struct comedi_device *dev) return 0; } -static int icp_multi_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int icp_multi_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct icp_multi_private *devpriv; struct comedi_subdevice *s; resource_size_t iobase; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -613,17 +613,17 @@ static void icp_multi_detach(struct comedi_device *dev) static struct comedi_driver icp_multi_driver = { .driver_name = "icp_multi", .module = THIS_MODULE, - .attach_pci = icp_multi_attach_pci, + .auto_attach = icp_multi_auto_attach, .detach = icp_multi_detach, }; -static int __devinit icp_multi_pci_probe(struct pci_dev *dev, +static int icp_multi_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &icp_multi_driver); } -static void __devexit icp_multi_pci_remove(struct pci_dev *dev) +static void icp_multi_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -638,7 +638,7 @@ static struct pci_driver icp_multi_pci_driver = { .name = "icp_multi", .id_table = icp_multi_pci_table, .probe = icp_multi_pci_probe, - .remove = __devexit_p(icp_multi_pci_remove), + .remove = icp_multi_pci_remove, }; module_comedi_pci_driver(icp_multi_driver, icp_multi_pci_driver); diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 65ff1c9..93584e2 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -156,7 +156,6 @@ struct pci20xxx_private { union pci20xxx_subdev_private subdev_private[PCI20000_MODULES]; }; -#define devpriv ((struct pci20xxx_private *)dev->private) #define CHAN (CR_CHAN(it->chanlist[0])) static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s, @@ -196,6 +195,7 @@ static int pci20xxx_dio_init(struct comedi_device *dev, static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pci20xxx_private *devpriv; unsigned char i; int ret; int id; @@ -206,22 +206,23 @@ static int pci20xxx_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(struct pci20xxx_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0]; dev->board_name = "pci20kc"; /* Check PCI-20001 C-2A Carrier Board ID */ if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) { - printk(KERN_WARNING "comedi%d: ii_pci20kc PCI-20001" - " C-2A Carrier Board at base=0x%p not found !\n", - dev->minor, devpriv->ioaddr); + dev_warn(dev->class_dev, + "PCI-20001 C-2A Carrier Board at base=0x%p not found !\n", + devpriv->ioaddr); return -EINVAL; } - printk(KERN_INFO "comedi%d: ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", - dev->minor, devpriv->ioaddr); + dev_info(dev->class_dev, "PCI-20001 C-2A at base=0x%p\n", + devpriv->ioaddr); for (i = 0; i < PCI20000_MODULES; i++) { s = &dev->subdevices[i]; @@ -234,23 +235,21 @@ static int pci20xxx_attach(struct comedi_device *dev, devpriv->ioaddr + (i + 1) * PCI20000_OFFSET; pci20006_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); - printk(KERN_INFO "comedi%d: " - "ii_pci20kc PCI-20006 module in slot %d\n", - dev->minor, i + 1); + dev_info(dev->class_dev, + "PCI-20006 module in slot %d\n", i + 1); break; case PCI20341_ID: sdp->pci20341.iobase = devpriv->ioaddr + (i + 1) * PCI20000_OFFSET; pci20341_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); - printk(KERN_INFO "comedi%d: " - "ii_pci20kc PCI-20341 module in slot %d\n", - dev->minor, i + 1); + dev_info(dev->class_dev, + "PCI-20341 module in slot %d\n", i + 1); break; default: - printk(KERN_WARNING "ii_pci20kc: unknown module " - "code 0x%02x in slot %d: module disabled\n", - id, i); /* XXX this looks like a bug! i + 1 ?? */ + dev_warn(dev->class_dev, + "unknown module code 0x%02x in slot %d: module disabled\n", + id, i); /* XXX this looks like a bug! i + 1 ?? */ /* fall through */ case PCI20xxx_EMPTY_ID: s->type = COMEDI_SUBD_UNUSED; @@ -346,8 +345,7 @@ static int pci20006_insn_write(struct comedi_device *dev, writeb(0x00, sdp->iobase + PCI20006_STROBE1); break; default: - printk(KERN_WARNING - " comedi%d: pci20xxx: ao channel Error!\n", dev->minor); + dev_warn(dev->class_dev, "ao channel Error!\n"); return -EINVAL; } @@ -462,10 +460,8 @@ static int pci20341_insn_read(struct comedi_device *dev, eoc = readb(sdp->iobase + PCI20341_STATUS_REG); } if (j >= 100) { - printk(KERN_WARNING - "comedi%d: pci20xxx: " - "AI interrupt channel %i polling exit !\n", - dev->minor, i); + dev_warn(dev->class_dev, + "AI interrupt channel %i polling exit !\n", i); return -EINVAL; } lo = readb(sdp->iobase + PCI20341_LDATA); @@ -541,6 +537,7 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci20xxx_private *devpriv = dev->private; unsigned int mask = data[0]; s->state &= ~mask; @@ -571,6 +568,7 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci20xxx_private *devpriv = dev->private; unsigned char control_01; unsigned char control_23; unsigned char buffer; @@ -627,6 +625,8 @@ static void pci20xxx_dio_config(struct comedi_device *dev, #if 0 static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci20xxx_private *devpriv = dev->private; + /* XXX if the channel is configured for input, does this do bad things? */ /* XXX it would be a good idea to only update the registers @@ -641,9 +641,10 @@ static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s) static unsigned int pci20xxx_di(struct comedi_device *dev, struct comedi_subdevice *s) { - /* XXX same note as above */ + struct pci20xxx_private *devpriv = dev->private; unsigned int bits; + /* XXX same note as above */ bits = readb(devpriv->ioaddr + PCI20000_DIO_0); bits |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8; bits |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16; diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 4a108ea..c756a35 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -21,24 +21,26 @@ */ /* -Driver: jr3_pci -Description: JR3/PCI force sensor board -Author: Anders Blomdell <anders.blomdell@control.lth.se> -Status: works -Devices: [JR3] PCI force sensor board (jr3_pci) - - 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 http://www.comedi.org - in the comedi_nonfree_firmware tarball. - - Configuration options: - [0] - PCI bus number - if bus number and slot number are 0, - then driver search for first unused card - [1] - PCI slot number - -*/ + * 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 http://www.comedi.org in the + * comedi_nonfree_firmware tarball. The file is called "jr3pci.idm". + */ #include "../comedidev.h" @@ -59,22 +61,18 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114 struct jr3_pci_dev_private { - - struct pci_dev *pci_dev; - int pci_enabled; - volatile struct jr3_t *iobase; + struct jr3_t __iomem *iobase; int n_channels; struct timer_list timer; }; struct poll_delay_t { - int min; int max; }; struct jr3_pci_subdev_private { - volatile struct jr3_channel *channel; + struct jr3_channel __iomem *channel; unsigned long next_time_min; unsigned long next_time_max; enum { state_jr3_poll, @@ -98,15 +96,15 @@ struct jr3_pci_subdev_private { }; /* Hotplug firmware loading stuff */ -static int comedi_load_firmware(struct comedi_device *dev, char *name, +static int comedi_load_firmware(struct comedi_device *dev, const char *name, int (*cb)(struct comedi_device *dev, const u8 *data, size_t size)) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); int result = 0; const struct firmware *fw; char *firmware_path; static const char *prefix = "comedi/"; - struct jr3_pci_dev_private *devpriv = dev->private; firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL); if (!firmware_path) { @@ -115,8 +113,7 @@ static int comedi_load_firmware(struct comedi_device *dev, char *name, firmware_path[0] = '\0'; strcat(firmware_path, prefix); strcat(firmware_path, name); - result = request_firmware(&fw, firmware_path, - &devpriv->pci_dev->dev); + result = request_firmware(&fw, firmware_path, &pcidev->dev); if (result == 0) { if (!cb) result = -EINVAL; @@ -138,7 +135,7 @@ static struct poll_delay_t poll_delay_min_max(int min, int max) return result; } -static int is_complete(volatile struct jr3_channel *channel) +static int is_complete(struct jr3_channel __iomem *channel) { return get_s16(&channel->command_word0) == 0; } @@ -150,14 +147,13 @@ struct transform_t { } link[8]; }; -static void set_transforms(volatile struct jr3_channel *channel, +static void set_transforms(struct jr3_channel __iomem *channel, struct transform_t transf, short num) { int i; num &= 0x000f; /* Make sure that 0 <= num <= 15 */ for (i = 0; i < 8; i++) { - set_u16(&channel->transforms[num].link[i].link_type, transf.link[i].link_type); udelay(1); @@ -169,18 +165,18 @@ static void set_transforms(volatile struct jr3_channel *channel, } } -static void use_transform(volatile struct jr3_channel *channel, +static void use_transform(struct jr3_channel __iomem *channel, short transf_num) { set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f)); } -static void use_offset(volatile struct jr3_channel *channel, short offset_num) +static void use_offset(struct jr3_channel __iomem *channel, short offset_num) { set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f)); } -static void set_offset(volatile struct jr3_channel *channel) +static void set_offset(struct jr3_channel __iomem *channel) { set_s16(&channel->command_word0, 0x0700); } @@ -194,13 +190,9 @@ struct six_axis_t { s16 mz; }; -static void set_full_scales(volatile struct jr3_channel *channel, +static void set_full_scales(struct jr3_channel __iomem *channel, struct six_axis_t full_scale) { - printk("%d %d %d %d %d %d\n", - full_scale.fx, - full_scale.fy, - full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz); set_s16(&channel->full_scale.fx, full_scale.fx); set_s16(&channel->full_scale.fy, full_scale.fy); set_s16(&channel->full_scale.fz, full_scale.fz); @@ -210,7 +202,7 @@ static void set_full_scales(volatile struct jr3_channel *channel, set_s16(&channel->command_word0, 0x0a00); } -static struct six_axis_t get_min_full_scales(volatile struct jr3_channel +static struct six_axis_t get_min_full_scales(struct jr3_channel __iomem *channel) { struct six_axis_t result; @@ -223,7 +215,7 @@ static struct six_axis_t get_min_full_scales(volatile struct jr3_channel return result; } -static struct six_axis_t get_max_full_scales(volatile struct jr3_channel +static struct six_axis_t get_max_full_scales(struct jr3_channel __iomem *channel) { struct six_axis_t result; @@ -273,71 +265,53 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, } else { int F = 0; switch (axis) { - case 0:{ - F = get_s16 - (&p->channel->filter - [filter].fx); - } + case 0: + F = get_s16(&p->channel-> + filter[filter].fx); break; - case 1:{ - F = get_s16 - (&p->channel->filter - [filter].fy); - } + case 1: + F = get_s16(&p->channel-> + filter[filter].fy); break; - case 2:{ - F = get_s16 - (&p->channel->filter - [filter].fz); - } + case 2: + F = get_s16(&p->channel-> + filter[filter].fz); break; - case 3:{ - F = get_s16 - (&p->channel->filter - [filter].mx); - } + case 3: + F = get_s16(&p->channel-> + filter[filter].mx); break; - case 4:{ - F = get_s16 - (&p->channel->filter - [filter].my); - } + case 4: + F = get_s16(&p->channel-> + filter[filter].my); break; - case 5:{ - F = get_s16 - (&p->channel->filter - [filter].mz); - } + case 5: + F = get_s16(&p->channel-> + filter[filter].mz); break; - case 6:{ - F = get_s16 - (&p->channel->filter - [filter].v1); - } + case 6: + F = get_s16(&p->channel-> + filter[filter].v1); break; - case 7:{ - F = get_s16 - (&p->channel->filter - [filter].v2); - } + case 7: + F = get_s16(&p->channel-> + filter[filter].v2); break; } data[i] = F + 0x4000; } } else if (channel == 56) { - if (p->state != state_jr3_done) { + if (p->state != state_jr3_done) data[i] = 0; - } else { + else data[i] = - get_u16(&p->channel->model_no); - } + get_u16(&p->channel->model_no); } else if (channel == 57) { - if (p->state != state_jr3_done) { + if (p->state != state_jr3_done) data[i] = 0; - } else { + else data[i] = - get_u16(&p->channel->serial_no); - } + get_u16(&p->channel->serial_no); } } } @@ -368,8 +342,8 @@ static int read_idm_word(const u8 *data, size_t size, int *pos, int result = 0; if (pos && val) { /* Skip over non hex */ - for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) { - } + for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) + ; /* Collect value */ *val = 0; for (; *pos < size; (*pos)++) { @@ -378,14 +352,15 @@ static int read_idm_word(const u8 *data, size_t size, int *pos, if (value >= 0) { result = 1; *val = (*val << 4) + value; - } else + } else { break; + } } } return result; } -static int jr3_download_firmware(struct comedi_device *dev, const u8 * data, +static int jr3_download_firmware(struct comedi_device *dev, const u8 *data, size_t size) { /* @@ -429,37 +404,38 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 * data, pos = 0; while (more) { unsigned int count, addr; - more = more - && read_idm_word(data, size, &pos, &count); + more = more && + read_idm_word(data, size, &pos, &count); if (more && count == 0xffff) break; - more = more - && read_idm_word(data, size, &pos, &addr); + more = more && + read_idm_word(data, size, &pos, &addr); dev_dbg(dev->class_dev, "Loading#%d %4.4x bytes at %4.4x\n", i, count, addr); while (more && count > 0) { if (addr & 0x4000) { - /* 16 bit data, never seen in real life!! */ + /* 16 bit data, never seen + * in real life!! */ unsigned int data1; - more = more - && read_idm_word(data, + more = more && + read_idm_word(data, size, &pos, &data1); count--; - /* printk("jr3_data, not tested\n"); */ - /* jr3[addr + 0x20000 * pnum] = data1; */ + /* jr3[addr + 0x20000 * pnum] = + data1; */ } else { /* Download 24 bit program */ unsigned int data1, data2; - more = more - && read_idm_word(data, + more = more && + read_idm_word(data, size, &pos, &data1); - more = more - && read_idm_word(data, size, + more = more && + read_idm_word(data, size, &pos, &data2); count -= 2; @@ -474,7 +450,6 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 * data, [i].program_high [addr], data2); udelay(1); - } } addr++; @@ -492,213 +467,152 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) int i; if (p) { - volatile struct jr3_channel *channel = p->channel; + struct jr3_channel __iomem *channel = p->channel; int errors = get_u16(&channel->errors); - if (errors != p->errors) { - printk("Errors: %x -> %x\n", p->errors, errors); + if (errors != p->errors) p->errors = errors; - } - if (errors & (watch_dog | watch_dog2 | sensor_change)) { + + if (errors & (watch_dog | watch_dog2 | sensor_change)) /* Sensor communication lost, force poll mode */ p->state = state_jr3_poll; - } switch (p->state) { - case state_jr3_poll:{ + case state_jr3_poll: { u16 model_no = get_u16(&channel->model_no); u16 serial_no = get_u16(&channel->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. - */ + /* + * Still no sensor, keep on polling. + * Since it takes up to 10 seconds + * for offsets to stabilize, polling + * each second should suffice. + */ result = poll_delay_min_max(1000, 2000); } else { p->retries = 0; p->state = - state_jr3_init_wait_for_offset; + state_jr3_init_wait_for_offset; result = poll_delay_min_max(1000, 2000); } } break; - case state_jr3_init_wait_for_offset:{ - p->retries++; - if (p->retries < 10) { - /* Wait for offeset to stabilize (< 10 s according to manual) */ - result = poll_delay_min_max(1000, 2000); - } else { - struct transform_t transf; - - p->model_no = - get_u16(&channel->model_no); - p->serial_no = - get_u16(&channel->serial_no); - - printk - ("Setting transform for channel %d\n", - p->channel_no); - printk("Sensor Model = %i\n", - p->model_no); - printk("Sensor Serial = %i\n", - p->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(channel, transf, 0); - use_transform(channel, 0); - p->state = - state_jr3_init_transform_complete; - result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */ + case state_jr3_init_wait_for_offset: + p->retries++; + if (p->retries < 10) { + /* Wait for offeset to stabilize + * (< 10 s according to manual) */ + result = poll_delay_min_max(1000, 2000); + } else { + struct transform_t transf; + + p->model_no = get_u16(&channel->model_no); + p->serial_no = get_u16(&channel->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; } - } break; - case state_jr3_init_transform_complete:{ - if (!is_complete(channel)) { - printk - ("state_jr3_init_transform_complete complete = %d\n", - is_complete(channel)); - 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(channel); - printk("Obtained Min. Full Scales:\n"); - printk(KERN_DEBUG "%i ", (min_full_scale).fx); - printk(KERN_CONT "%i ", (min_full_scale).fy); - printk(KERN_CONT "%i ", (min_full_scale).fz); - printk(KERN_CONT "%i ", (min_full_scale).mx); - printk(KERN_CONT "%i ", (min_full_scale).my); - printk(KERN_CONT "%i ", (min_full_scale).mz); - printk(KERN_CONT "\n"); - - max_full_scale = - get_max_full_scales(channel); - printk("Obtained Max. Full Scales:\n"); - printk(KERN_DEBUG "%i ", (max_full_scale).fx); - printk(KERN_CONT "%i ", (max_full_scale).fy); - printk(KERN_CONT "%i ", (max_full_scale).fz); - printk(KERN_CONT "%i ", (max_full_scale).mx); - printk(KERN_CONT "%i ", (max_full_scale).my); - printk(KERN_CONT "%i ", (max_full_scale).mz); - printk(KERN_CONT "\n"); - - set_full_scales(channel, - max_full_scale); - p->state = - state_jr3_init_set_full_scale_complete; - result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */ - } + set_transforms(channel, transf, 0); + use_transform(channel, 0); + p->state = state_jr3_init_transform_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(channel)) { - printk - ("state_jr3_init_set_full_scale_complete complete = %d\n", - is_complete(channel)); - result = poll_delay_min_max(20, 100); - } else { - volatile struct force_array *full_scale; - - /* Use ranges in kN or we will overflow arount 2000N! */ - full_scale = &channel->full_scale; - p->range[0].range.min = - -get_s16(&full_scale->fx) * 1000; - p->range[0].range.max = - get_s16(&full_scale->fx) * 1000; - p->range[1].range.min = - -get_s16(&full_scale->fy) * 1000; - p->range[1].range.max = - get_s16(&full_scale->fy) * 1000; - p->range[2].range.min = - -get_s16(&full_scale->fz) * 1000; - p->range[2].range.max = - get_s16(&full_scale->fz) * 1000; - p->range[3].range.min = - -get_s16(&full_scale->mx) * 100; - p->range[3].range.max = - get_s16(&full_scale->mx) * 100; - p->range[4].range.min = - -get_s16(&full_scale->my) * 100; - p->range[4].range.max = - get_s16(&full_scale->my) * 100; - p->range[5].range.min = - -get_s16(&full_scale->mz) * 100; - p->range[5].range.max = - get_s16(&full_scale->mz) * 100; - p->range[6].range.min = -get_s16(&full_scale->v1) * 100; /* ?? */ - p->range[6].range.max = get_s16(&full_scale->v1) * 100; /* ?? */ - p->range[7].range.min = -get_s16(&full_scale->v2) * 100; /* ?? */ - p->range[7].range.max = get_s16(&full_scale->v2) * 100; /* ?? */ - p->range[8].range.min = 0; - p->range[8].range.max = 65535; - - { - int i; - for (i = 0; i < 9; i++) { - printk("%d %d - %d\n", - i, - p-> - range[i].range. - min, - p-> - range[i].range. - max); - } - } - - use_offset(channel, 0); - p->state = - state_jr3_init_use_offset_complete; - result = poll_delay_min_max(40, 100); /* Allow 40 ms for completion */ - } + case state_jr3_init_transform_complete: + if (!is_complete(channel)) { + 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(channel); + max_full_scale = get_max_full_scales(channel); + set_full_scales(channel, max_full_scale); + + p->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_use_offset_complete:{ - if (!is_complete(channel)) { - printk - ("state_jr3_init_use_offset_complete complete = %d\n", - is_complete(channel)); - result = poll_delay_min_max(20, 100); - } else { - printk - ("Default offsets %d %d %d %d %d %d\n", - get_s16(&channel->offsets.fx), - get_s16(&channel->offsets.fy), - get_s16(&channel->offsets.fz), - get_s16(&channel->offsets.mx), - get_s16(&channel->offsets.my), - get_s16(&channel->offsets.mz)); - - set_s16(&channel->offsets.fx, 0); - set_s16(&channel->offsets.fy, 0); - set_s16(&channel->offsets.fz, 0); - set_s16(&channel->offsets.mx, 0); - set_s16(&channel->offsets.my, 0); - set_s16(&channel->offsets.mz, 0); - - set_offset(channel); - - p->state = state_jr3_done; - } + case state_jr3_init_set_full_scale_complete: + if (!is_complete(channel)) { + result = poll_delay_min_max(20, 100); + } else { + struct force_array __iomem *full_scale; + + /* Use ranges in kN or we will + * overflow around 2000N! */ + full_scale = &channel->full_scale; + p->range[0].range.min = + -get_s16(&full_scale->fx) * 1000; + p->range[0].range.max = + get_s16(&full_scale->fx) * 1000; + p->range[1].range.min = + -get_s16(&full_scale->fy) * 1000; + p->range[1].range.max = + get_s16(&full_scale->fy) * 1000; + p->range[2].range.min = + -get_s16(&full_scale->fz) * 1000; + p->range[2].range.max = + get_s16(&full_scale->fz) * 1000; + p->range[3].range.min = + -get_s16(&full_scale->mx) * 100; + p->range[3].range.max = + get_s16(&full_scale->mx) * 100; + p->range[4].range.min = + -get_s16(&full_scale->my) * 100; + p->range[4].range.max = + get_s16(&full_scale->my) * 100; + p->range[5].range.min = + -get_s16(&full_scale->mz) * 100; + p->range[5].range.max = + get_s16(&full_scale->mz) * 100; /* ?? */ + p->range[6].range.min = + -get_s16(&full_scale->v1) * 100;/* ?? */ + p->range[6].range.max = + get_s16(&full_scale->v1) * 100; /* ?? */ + p->range[7].range.min = + -get_s16(&full_scale->v2) * 100;/* ?? */ + p->range[7].range.max = + get_s16(&full_scale->v2) * 100; /* ?? */ + p->range[8].range.min = 0; + p->range[8].range.max = 65535; + + use_offset(channel, 0); + p->state = state_jr3_init_use_offset_complete; + /* Allow 40 ms for completion */ + result = poll_delay_min_max(40, 100); } break; - case state_jr3_done:{ - poll_delay_min_max(10000, 20000); + case state_jr3_init_use_offset_complete: + if (!is_complete(channel)) { + result = poll_delay_min_max(20, 100); + } else { + set_s16(&channel->offsets.fx, 0); + set_s16(&channel->offsets.fy, 0); + set_s16(&channel->offsets.fz, 0); + set_s16(&channel->offsets.mx, 0); + set_s16(&channel->offsets.my, 0); + set_s16(&channel->offsets.mz, 0); + + set_offset(channel); + + p->state = state_jr3_done; } break; - default:{ - poll_delay_min_max(1000, 2000); - } + case state_jr3_done: + poll_delay_min_max(10000, 20000); + break; + default: + poll_delay_min_max(1000, 2000); break; } } @@ -720,22 +634,21 @@ static void jr3_pci_poll_dev(unsigned long data) /* Poll all channels that are ready to be polled */ for (i = 0; i < devpriv->n_channels; i++) { struct jr3_pci_subdev_private *subdevpriv = - dev->subdevices[i].private; + dev->subdevices[i].private; if (now > subdevpriv->next_time_min) { struct poll_delay_t sub_delay; sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]); subdevpriv->next_time_min = - jiffies + msecs_to_jiffies(sub_delay.min); + jiffies + msecs_to_jiffies(sub_delay.min); subdevpriv->next_time_max = - jiffies + msecs_to_jiffies(sub_delay.max); - if (sub_delay.max && sub_delay.max < delay) { -/* -* Wake up as late as possible -> poll as many channels as possible -* at once -*/ + jiffies + msecs_to_jiffies(sub_delay.max); + if (sub_delay.max && sub_delay.max < delay) + /* + * Wake up as late as possible -> + * poll as many channels as possible at once. + */ delay = sub_delay.max; - } } } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -744,17 +657,14 @@ static void jr3_pci_poll_dev(unsigned long data) add_timer(&devpriv->timer); } -static int jr3_pci_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int jr3_pci_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { - int result = 0; - struct pci_dev *card = NULL; - int opt_bus, opt_slot, i; + int result; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + int i; struct jr3_pci_dev_private *devpriv; - opt_bus = it->options[0]; - opt_slot = it->options[1]; - if (sizeof(struct jr3_channel) != 0xc00) { dev_err(dev->class_dev, "sizeof(struct jr3_channel) = %x [expected %x]\n", @@ -762,70 +672,42 @@ static int jr3_pci_attach(struct comedi_device *dev, return -EINVAL; } - result = alloc_private(dev, sizeof(struct jr3_pci_dev_private)); - if (result < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; - card = NULL; - devpriv = dev->private; + dev->private = devpriv; + init_timer(&devpriv->timer); - while (1) { - card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card); - if (card == NULL) { - /* No card found */ - break; - } else { - switch (card->device) { - case PCI_DEVICE_ID_JR3_1_CHANNEL:{ - devpriv->n_channels = 1; - } - break; - case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW:{ - devpriv->n_channels = 1; - } - break; - case PCI_DEVICE_ID_JR3_2_CHANNEL:{ - devpriv->n_channels = 2; - } - break; - case PCI_DEVICE_ID_JR3_3_CHANNEL:{ - devpriv->n_channels = 3; - } - break; - case PCI_DEVICE_ID_JR3_4_CHANNEL:{ - devpriv->n_channels = 4; - } - break; - default:{ - devpriv->n_channels = 0; - } - } - if (devpriv->n_channels >= 1) { - if (opt_bus == 0 && opt_slot == 0) { - /* Take first available card */ - break; - } else if (opt_bus == card->bus->number && - opt_slot == PCI_SLOT(card->devfn)) { - /* Take requested card */ - break; - } - } - } - } - if (!card) { - dev_err(dev->class_dev, "no jr3_pci found\n"); - return -EIO; - } else { - devpriv->pci_dev = card; - dev->board_name = "jr3_pci"; + switch (pcidev->device) { + case PCI_DEVICE_ID_JR3_1_CHANNEL: + case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW: + devpriv->n_channels = 1; + break; + case PCI_DEVICE_ID_JR3_2_CHANNEL: + devpriv->n_channels = 2; + break; + case PCI_DEVICE_ID_JR3_3_CHANNEL: + devpriv->n_channels = 3; + break; + case PCI_DEVICE_ID_JR3_4_CHANNEL: + devpriv->n_channels = 4; + break; + default: + dev_err(dev->class_dev, "jr3_pci: pci %s not supported\n", + pci_name(pcidev)); + return -EINVAL; + break; } + dev->board_name = "jr3_pci"; - result = comedi_pci_enable(card, "jr3_pci"); + result = comedi_pci_enable(pcidev, "jr3_pci"); if (result < 0) - return -EIO; + return result; - devpriv->pci_enabled = 1; - devpriv->iobase = ioremap(pci_resource_start(card, 0), - offsetof(struct jr3_t, channel[devpriv->n_channels])); + dev->iobase = 1; /* the "detach" needs this */ + devpriv->iobase = ioremap(pci_resource_start(pcidev, 0), + offsetof(struct jr3_t, + channel[devpriv->n_channels])); if (!devpriv->iobase) return -ENOMEM; @@ -840,7 +722,8 @@ static int jr3_pci_attach(struct comedi_device *dev, dev->subdevices[i].n_chan = 8 * 7 + 2; dev->subdevices[i].insn_read = jr3_pci_ai_insn_read; dev->subdevices[i].private = - kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL); + kzalloc(sizeof(struct jr3_pci_subdev_private), + GFP_KERNEL); if (dev->subdevices[i].private) { struct jr3_pci_subdev_private *p; int j; @@ -849,8 +732,8 @@ static int jr3_pci_attach(struct comedi_device *dev, p->channel = &devpriv->iobase->channel[i].data; dev_dbg(dev->class_dev, "p->channel %p %p (%tx)\n", p->channel, devpriv->iobase, - ((char *)(p->channel) - - (char *)(devpriv->iobase))); + ((char __iomem *)p->channel - + (char __iomem *)devpriv->iobase)); p->channel_no = i; for (j = 0; j < 8; j++) { int k; @@ -870,15 +753,15 @@ static int jr3_pci_attach(struct comedi_device *dev, p->range[8].range.max = 65536; p->range_table_list[56] = - (struct comedi_lrange *)&p->range[8]; + (struct comedi_lrange *)&p->range[8]; p->range_table_list[57] = - (struct comedi_lrange *)&p->range[8]; + (struct comedi_lrange *)&p->range[8]; p->maxdata_list[56] = 0xffff; p->maxdata_list[57] = 0xffff; /* Channel specific range and maxdata */ dev->subdevices[i].range_table = NULL; dev->subdevices[i].range_table_list = - p->range_table_list; + p->range_table_list; dev->subdevices[i].maxdata = 0; dev->subdevices[i].maxdata_list = p->maxdata_list; } @@ -891,19 +774,20 @@ static int jr3_pci_attach(struct comedi_device *dev, dev_dbg(dev->class_dev, "Firmare load %d\n", result); if (result < 0) - goto out; -/* - * TODO: use firmware to load preferred offset tables. Suggested - * format: - * model serial Fx Fy Fz Mx My Mz\n - * - * comedi_load_firmware(dev, "jr3_offsets_table", jr3_download_firmware); - */ + return result; + /* + * TODO: use firmware to load preferred offset tables. Suggested + * format: + * model serial Fx Fy Fz Mx My Mz\n + * + * comedi_load_firmware(dev, "jr3_offsets_table", + * jr3_download_firmware); + */ -/* - * It takes a few milliseconds for software to settle as much as we - * can read firmware version - */ + /* + * It takes a few milliseconds for software to settle as much as we + * can read firmware version + */ msleep_interruptible(25); for (i = 0; i < 0x18; i++) { dev_dbg(dev->class_dev, "%c\n", @@ -924,13 +808,13 @@ static int jr3_pci_attach(struct comedi_device *dev, devpriv->timer.expires = jiffies + msecs_to_jiffies(1000); add_timer(&devpriv->timer); -out: return result; } static void jr3_pci_detach(struct comedi_device *dev) { int i; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct jr3_pci_dev_private *devpriv = dev->private; if (devpriv) { @@ -941,28 +825,26 @@ static void jr3_pci_detach(struct comedi_device *dev) kfree(dev->subdevices[i].private); } if (devpriv->iobase) - iounmap((void *)devpriv->iobase); - if (devpriv->pci_enabled) - comedi_pci_disable(devpriv->pci_dev); - if (devpriv->pci_dev) - pci_dev_put(devpriv->pci_dev); + iounmap(devpriv->iobase); + if (dev->iobase) + comedi_pci_disable(pcidev); } } static struct comedi_driver jr3_pci_driver = { .driver_name = "jr3_pci", .module = THIS_MODULE, - .attach = jr3_pci_attach, + .auto_attach = jr3_pci_auto_attach, .detach = jr3_pci_detach, }; -static int __devinit jr3_pci_pci_probe(struct pci_dev *dev, +static int jr3_pci_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &jr3_pci_driver); } -static void __devexit jr3_pci_pci_remove(struct pci_dev *dev) +static void jr3_pci_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -981,7 +863,7 @@ static struct pci_driver jr3_pci_pci_driver = { .name = "jr3_pci", .id_table = jr3_pci_pci_table, .probe = jr3_pci_pci_probe, - .remove = __devexit_p(jr3_pci_pci_remove), + .remove = jr3_pci_pci_remove, }; module_comedi_pci_driver(jr3_pci_driver, jr3_pci_pci_driver); diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h index 9c42653..3317f7a 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.h +++ b/drivers/staging/comedi/drivers/jr3_pci.h @@ -2,22 +2,22 @@ * is 16 bits, but aligned on a 32 bit PCI boundary */ -static inline u16 get_u16(volatile const u32 * p) +static inline u16 get_u16(const u32 __iomem *p) { - return (u16) readl(p); + return (u16)readl(p); } -static inline void set_u16(volatile u32 * p, u16 val) +static inline void set_u16(u32 __iomem *p, u16 val) { writel(val, p); } -static inline s16 get_s16(volatile const s32 * p) +static inline s16 get_s16(const s32 __iomem *p) { - return (s16) readl(p); + return (s16)readl(p); } -static inline void set_s16(volatile s32 * p, s16 val) +static inline void set_s16(s32 __iomem *p, s16 val) { writel(val, p); } diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index e867b72..19c9428 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -36,28 +36,8 @@ Kolter Electronic PCI Counter Card. #include "../comedidev.h" -#define CNT_DRIVER_NAME "ke_counter" -#define PCI_VENDOR_ID_KOLTER 0x1001 #define CNT_CARD_DEVICE_ID 0x0014 -/*-- board specification structure ------------------------------------------*/ - -struct cnt_board_struct { - - const char *name; - int device_id; - int cnt_channel_nbr; - int cnt_bits; -}; - -static const struct cnt_board_struct cnt_boards[] = { - { - .name = CNT_DRIVER_NAME, - .device_id = CNT_CARD_DEVICE_ID, - .cnt_channel_nbr = 3, - .cnt_bits = 24} -}; - /*-- counter write ----------------------------------------------------------*/ /* This should be used only for resetting the counters; maybe it is better @@ -107,34 +87,14 @@ static int cnt_rinsn(struct comedi_device *dev, return 1; } -static const void *cnt_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) +static int cnt_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { - const struct cnt_board_struct *board; - int i; - - for (i = 0; i < ARRAY_SIZE(cnt_boards); i++) { - board = &cnt_boards[i]; - if (board->device_id == pcidev->device) - return board; - } - return NULL; -} - -static int cnt_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct cnt_board_struct *board; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - - board = cnt_find_boardinfo(dev, pcidev); - if (!board) - return -ENODEV; - dev->board_ptr = board; - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -150,8 +110,8 @@ static int cnt_attach_pci(struct comedi_device *dev, s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ; - s->n_chan = board->cnt_channel_nbr; - s->maxdata = (1 << board->cnt_bits) - 1; + s->n_chan = 3; + s->maxdata = 0x00ffffff; s->insn_read = cnt_rinsn; s->insn_write = cnt_winsn; @@ -182,17 +142,17 @@ static void cnt_detach(struct comedi_device *dev) static struct comedi_driver ke_counter_driver = { .driver_name = "ke_counter", .module = THIS_MODULE, - .attach_pci = cnt_attach_pci, + .auto_attach = cnt_auto_attach, .detach = cnt_detach, }; -static int __devinit ke_counter_pci_probe(struct pci_dev *dev, +static int ke_counter_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ke_counter_driver); } -static void __devexit ke_counter_pci_remove(struct pci_dev *dev) +static void ke_counter_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -207,7 +167,7 @@ static struct pci_driver ke_counter_pci_driver = { .name = "ke_counter", .id_table = ke_counter_pci_table, .probe = ke_counter_pci_probe, - .remove = __devexit_p(ke_counter_pci_remove), + .remove = ke_counter_pci_remove, }; module_comedi_pci_driver(ke_counter_driver, ke_counter_pci_driver); diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 22db35d..3c4b022 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -60,8 +60,6 @@ broken. #include "me4000_fw.h" #endif -#define PCI_VENDOR_ID_MEILHAUS 0x1402 - #define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 #define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 #define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 @@ -971,28 +969,23 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, if (err) return 2; - /* - * Stage 3. Check if arguments are generally valid. - */ + /* Step 3: check if arguments are trivially valid */ + if (cmd->chanlist_len < 1) { - dev_err(dev->class_dev, "No channel list\n"); cmd->chanlist_len = 1; - err++; + err |= -EINVAL; } if (init_ticks < 66) { - dev_err(dev->class_dev, "Start arg to low\n"); cmd->start_arg = 2000; - err++; + err |= -EINVAL; } if (scan_ticks && scan_ticks < 67) { - dev_err(dev->class_dev, "Scan begin arg to low\n"); cmd->scan_begin_arg = 2031; - err++; + err |= -EINVAL; } if (chan_ticks < 66) { - dev_err(dev->class_dev, "Convert arg to low\n"); cmd->convert_arg = 2000; - err++; + err |= -EINVAL; } if (err) @@ -1570,26 +1563,25 @@ static const void *me4000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int me4000_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int me4000_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct me4000_board *thisboard; struct me4000_info *info; struct comedi_subdevice *s; int result; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = me4000_find_boardinfo(dev, pcidev); if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; dev->board_name = thisboard->name; - result = alloc_private(dev, sizeof(*info)); - if (result) - return result; - info = dev->private; + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + dev->private = info; result = comedi_pci_enable(pcidev, dev->board_name); if (result) @@ -1732,17 +1724,17 @@ static void me4000_detach(struct comedi_device *dev) static struct comedi_driver me4000_driver = { .driver_name = "me4000", .module = THIS_MODULE, - .attach_pci = me4000_attach_pci, + .auto_attach = me4000_auto_attach, .detach = me4000_detach, }; -static int __devinit me4000_pci_probe(struct pci_dev *dev, +static int me4000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &me4000_driver); } -static void __devexit me4000_pci_remove(struct pci_dev *dev) +static void me4000_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1769,7 +1761,7 @@ static struct pci_driver me4000_pci_driver = { .name = "me4000", .id_table = me4000_pci_table, .probe = me4000_pci_probe, - .remove = __devexit_p(me4000_pci_remove), + .remove = me4000_pci_remove, }; module_comedi_pci_driver(me4000_driver, me4000_pci_driver); diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 2ce0b14..ce8e3d3 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -1,47 +1,38 @@ /* - - 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> - - 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * 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> + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* -Driver: me_daq -Description: Meilhaus PCI data acquisition cards -Author: Michael Hillmann <hillmann@syscongroup.de> -Devices: [Meilhaus] ME-2600i (me_daq), ME-2000i -Status: experimental - -Supports: - - Analog Output - -Configuration options: - - [0] - PCI bus number (optional) - [1] - PCI slot number (optional) - - If bus/slot is not specified, the first available PCI - device will be used. -*/ + * Driver: me_daq + * Description: Meilhaus PCI data acquisition cards + * Devices: (Meilhaus) ME-2600i [me-2600i] + * (Meilhaus) 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/interrupt.h> #include <linux/sched.h> @@ -50,7 +41,6 @@ Configuration options: #define ME2600_FIRMWARE "me2600_firmware.bin" -#define PCI_VENDOR_ID_MEILHAUS 0x1402 #define ME2000_DEVICE_ID 0x2000 #define ME2600_DEVICE_ID 0x2600 @@ -136,97 +126,47 @@ Configuration options: #define ME_COUNTER_STARTDATA_B 0x0022 /* - | W */ #define ME_COUNTER_VALUE_B 0x0022 /* R | - */ -static const struct comedi_lrange me2000_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 me2600_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_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 me2600_ao_range = { - 3, - { - BIP_RANGE(10), - BIP_RANGE(5), - UNI_RANGE(10) - } +static const struct comedi_lrange me_ao_range = { + 3, { + BIP_RANGE(10), + BIP_RANGE(5), + UNI_RANGE(10) + } }; -/* Board specification structure */ struct me_board { - const char *name; /* driver name */ + const char *name; int device_id; - int ao_channel_nbr; /* DA config */ - int ao_resolution; - int ao_resolution_mask; - const struct comedi_lrange *ao_range_list; - int ai_channel_nbr; /* AD config */ - int ai_resolution; - int ai_resolution_mask; - const struct comedi_lrange *ai_range_list; - int dio_channel_nbr; /* DIO config */ + int has_ao; }; static const struct me_board me_boards[] = { { - .name = "me-2600i", - .device_id = ME2600_DEVICE_ID, - /* Analog Output */ - .ao_channel_nbr = 4, - .ao_resolution = 12, - .ao_resolution_mask = 0x0fff, - .ao_range_list = &me2600_ao_range, - .ai_channel_nbr = 16, - /* Analog Input */ - .ai_resolution = 12, - .ai_resolution_mask = 0x0fff, - .ai_range_list = &me2600_ai_range, - .dio_channel_nbr = 32, - }, - { - .name = "me-2000i", - .device_id = ME2000_DEVICE_ID, - /* Analog Output */ - .ao_channel_nbr = 0, - .ao_resolution = 0, - .ao_resolution_mask = 0, - .ao_range_list = NULL, - .ai_channel_nbr = 16, - /* Analog Input */ - .ai_resolution = 12, - .ai_resolution_mask = 0x0fff, - .ai_range_list = &me2000_ai_range, - .dio_channel_nbr = 32, - } + .name = "me-2600i", + .device_id = ME2600_DEVICE_ID, + .has_ao = 1, + }, { + .name = "me-2000i", + .device_id = ME2000_DEVICE_ID, + } }; -/* Private data structure */ struct me_private_data { void __iomem *plx_regbase; /* PLX configuration base address */ void __iomem *me_regbase; /* Base address of the Meilhaus card */ - unsigned long plx_regbase_size; /* Size of PLX configuration space */ - unsigned long me_regbase_size; /* Size of Meilhaus space */ unsigned short control_1; /* Mirror of CONTROL_1 register */ unsigned short control_2; /* Mirror of CONTROL_2 register */ @@ -234,110 +174,101 @@ struct me_private_data { int ao_readback[4]; /* Mirror of analog output data */ }; -#define dev_private ((struct me_private_data *)dev->private) - -/* - * ------------------------------------------------------------------ - * - * Helpful functions - * - * ------------------------------------------------------------------ - */ static inline void sleep(unsigned sec) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(sec * HZ); } -/* - * ------------------------------------------------------------------ - * - * DIGITAL INPUT/OUTPUT SECTION - * - * ------------------------------------------------------------------ - */ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - int bits; - int mask = 1 << CR_CHAN(insn->chanspec); + struct me_private_data *dev_private = dev->private; + unsigned int mask = 1 << CR_CHAN(insn->chanspec); + unsigned int bits; + unsigned int port; - /* calculate port */ - if (mask & 0x0000ffff) { /* Port A in use */ + if (mask & 0x0000ffff) { bits = 0x0000ffff; - - /* Enable Port A */ - dev_private->control_2 |= ENABLE_PORT_A; - writew(dev_private->control_2, - dev_private->me_regbase + ME_CONTROL_2); - } else { /* Port B in use */ - + port = ENABLE_PORT_A; + } else { bits = 0xffff0000; - - /* Enable Port B */ - dev_private->control_2 |= ENABLE_PORT_B; - writew(dev_private->control_2, - dev_private->me_regbase + ME_CONTROL_2); + port = ENABLE_PORT_B; } - if (data[0]) { - /* Config port as output */ - s->io_bits |= bits; - } else { - /* Config port as input */ + switch (data[0]) { + case INSN_CONFIG_DIO_INPUT: s->io_bits &= ~bits; + dev_private->control_2 &= ~port; + break; + case INSN_CONFIG_DIO_OUTPUT: + s->io_bits |= bits; + dev_private->control_2 |= port; + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT; + return insn->n; + break; + default: + return -EINVAL; } - return 1; + /* Update the port configuration */ + writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2); + + return insn->n; } -/* Digital instant input/outputs */ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { + struct me_private_data *dev_private = dev->private; + void __iomem *mmio_porta = dev_private->me_regbase + ME_DIO_PORT_A; + void __iomem *mmio_portb = dev_private->me_regbase + ME_DIO_PORT_B; unsigned int mask = data[0]; - s->state &= ~mask; - s->state |= (mask & data[1]); - - mask &= s->io_bits; - if (mask & 0x0000ffff) { /* Port A */ - writew((s->state & 0xffff), - dev_private->me_regbase + ME_DIO_PORT_A); - } else { - data[1] &= ~0x0000ffff; - data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_A); + unsigned int bits = data[1]; + unsigned int val; + + mask &= s->io_bits; /* only update the COMEDI_OUTPUT channels */ + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + if (mask & 0x0000ffff) + writew((s->state & 0xffff), mmio_porta); + if (mask & 0xffff0000) + writew(((s->state >> 16) & 0xffff), mmio_portb); } - if (mask & 0xffff0000) { /* Port B */ - writew(((s->state >> 16) & 0xffff), - dev_private->me_regbase + ME_DIO_PORT_B); - } else { - data[1] &= ~0xffff0000; - data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_B) << 16; - } + 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; } -/* - * ------------------------------------------------------------------ - * - * ANALOG INPUT SECTION - * - * ------------------------------------------------------------------ - */ - -/* Analog instant input */ static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned short value; - int chan = CR_CHAN((&insn->chanspec)[0]); - int rang = CR_RANGE((&insn->chanspec)[0]); - int aref = CR_AREF((&insn->chanspec)[0]); + struct me_private_data *dev_private = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int rang = CR_RANGE(insn->chanspec); + unsigned int aref = CR_AREF(insn->chanspec); + unsigned short val; int i; /* stop any running conversion */ @@ -356,15 +287,11 @@ static int me_ai_insn_read(struct comedi_device *dev, writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2); /* write to channel list fifo */ - /* b3:b0 are the channel number */ - value = chan & 0x0f; - /* b5:b4 are the channel gain */ - value |= (rang & 0x03) << 4; - /* b6 channel polarity */ - value |= (rang & 0x04) << 4; - /* b7 single or differential */ - value |= ((aref & AREF_DIFF) ? 0x80 : 0); - writew(value & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST); + val = chan & 0x0f; /* b3:b0 channel */ + val |= (rang & 0x03) << 4; /* b5:b4 gain */ + val |= (rang & 0x04) << 4; /* b6 polarity */ + val |= ((aref & AREF_DIFF) ? 0x80 : 0); /* b7 differential */ + writew(val & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST); /* set ADC mode to software trigger */ dev_private->control_1 |= SOFTWARE_TRIGGERED_ADC; @@ -380,12 +307,11 @@ static int me_ai_insn_read(struct comedi_device *dev, /* get value from ADC fifo */ if (i) { - data[0] = - (readw(dev_private->me_regbase + - ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF; + val = readw(dev_private->me_regbase + ME_READ_AD_FIFO); + val = (val ^ 0x800) & 0x0fff; + data[0] = val; } else { - printk(KERN_ERR "comedi%d: Cannot get single value\n", - dev->minor); + dev_err(dev->class_dev, "Cannot get single value\n"); return -EIO; } @@ -396,55 +322,14 @@ static int me_ai_insn_read(struct comedi_device *dev, return 1; } -/* - * ------------------------------------------------------------------ - * - * HARDWARE TRIGGERED ANALOG INPUT SECTION - * - * ------------------------------------------------------------------ - */ - -/* Cancel analog input autoscan */ -static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) -{ - /* disable interrupts */ - - /* stop any running conversion */ - dev_private->control_1 &= 0xFFFC; - writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1); - - return 0; -} - -/* Test analog input command */ -static int me_ai_do_cmd_test(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) -{ - return 0; -} - -/* Analog input command */ -static int me_ai_do_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - return 0; -} - -/* - * ------------------------------------------------------------------ - * - * ANALOG OUTPUT SECTION - * - * ------------------------------------------------------------------ - */ - -/* Analog instant output */ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - int chan; - int rang; + struct me_private_data *dev_private = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int rang = CR_RANGE(insn->chanspec); int i; /* Enable all DAC */ @@ -457,9 +342,6 @@ static int me_ao_insn_write(struct comedi_device *dev, /* Set dac-control register */ for (i = 0; i < insn->n; i++) { - chan = CR_CHAN((&insn->chanspec)[i]); - rang = CR_RANGE((&insn->chanspec)[i]); - /* clear bits for this channel */ dev_private->dac_control &= ~(0x0880 >> chan); if (rang == 0) @@ -477,7 +359,6 @@ static int me_ao_insn_write(struct comedi_device *dev, /* Set data register */ for (i = 0; i < insn->n; i++) { - chan = CR_CHAN((&insn->chanspec)[i]); writew((data[0] & s->maxdata), dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1)); dev_private->ao_readback[chan] = (data[0] & s->maxdata); @@ -486,36 +367,28 @@ static int me_ao_insn_write(struct comedi_device *dev, /* Update dac with data registers */ readw(dev_private->me_regbase + ME_DAC_UPDATE); - return i; + return insn->n; } -/* Analog output readback */ static int me_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { + struct me_private_data *dev_private = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); int i; - for (i = 0; i < insn->n; i++) { - data[i] = - dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])]; - } + for (i = 0; i < insn->n; i++) + data[i] = dev_private->ao_readback[chan]; - return 1; + return insn->n; } -/* - * ------------------------------------------------------------------ - * - * INITIALISATION SECTION - * - * ------------------------------------------------------------------ - */ - -/* Xilinx firmware download for card: ME-2600i */ static int me2600_xilinx_download(struct comedi_device *dev, const u8 *data, size_t size) { + struct me_private_data *dev_private = dev->private; unsigned int value; unsigned int file_length; unsigned int i; @@ -566,8 +439,7 @@ static int me2600_xilinx_download(struct comedi_device *dev, if (value & 0x20) { /* Disable interrupt */ writel(0x00, dev_private->plx_regbase + PLX_INTCSR); - printk(KERN_ERR "comedi%d: Xilinx download failed\n", - dev->minor); + dev_err(dev->class_dev, "Xilinx download failed\n"); return -EIO; } @@ -596,9 +468,10 @@ static int me2600_upload_firmware(struct comedi_device *dev) return ret; } -/* Reset device */ static int me_reset(struct comedi_device *dev) { + struct me_private_data *dev_private = dev->private; + /* Reset board */ writew(0x00, dev_private->me_regbase + ME_CONTROL_1); writew(0x00, dev_private->me_regbase + ME_CONTROL_2); @@ -627,20 +500,14 @@ static const void *me_find_boardinfo(struct comedi_device *dev, return NULL; } -static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +static int me_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct me_board *board; + struct me_private_data *dev_private; struct comedi_subdevice *s; - resource_size_t plx_regbase_tmp; - unsigned long plx_regbase_size_tmp; - resource_size_t me_regbase_tmp; - unsigned long me_regbase_size_tmp; - resource_size_t swap_regbase_tmp; - unsigned long swap_regbase_size_tmp; - resource_size_t regbase_tmp; - int result, error; - - comedi_set_hw_dev(dev, &pcidev->dev); + int ret; board = me_find_boardinfo(dev, pcidev); if (!board) @@ -648,123 +515,71 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) dev->board_ptr = board; dev->board_name = board->name; - /* Allocate private memory */ - if (alloc_private(dev, sizeof(struct me_private_data)) < 0) + dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL); + if (!dev_private) return -ENOMEM; + dev->private = dev_private; - /* Enable PCI device and request PCI regions */ - if (comedi_pci_enable(pcidev, dev->board_name) < 0) { - printk(KERN_ERR "comedi%d: Failed to enable PCI device and " - "request regions\n", dev->minor); - return -EIO; - } + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + dev->iobase = 1; /* detach needs this */ - /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */ - plx_regbase_tmp = pci_resource_start(pcidev, 0); - plx_regbase_size_tmp = pci_resource_len(pcidev, 0); - dev_private->plx_regbase = - ioremap(plx_regbase_tmp, plx_regbase_size_tmp); - dev_private->plx_regbase_size = plx_regbase_size_tmp; - if (!dev_private->plx_regbase) { - printk("comedi%d: Failed to remap I/O memory\n", dev->minor); + dev_private->plx_regbase = ioremap(pci_resource_start(pcidev, 0), + pci_resource_len(pcidev, 0)); + if (!dev_private->plx_regbase) return -ENOMEM; - } - - /* Read Swap base address [PCI_BASE_ADDRESS #5]. */ - - swap_regbase_tmp = pci_resource_start(pcidev, 5); - swap_regbase_size_tmp = pci_resource_len(pcidev, 5); - - if (!swap_regbase_tmp) - printk(KERN_ERR "comedi%d: Swap not present\n", dev->minor); - - /*---------------------------------------------- Workaround start ---*/ - if (plx_regbase_tmp & 0x0080) { - printk(KERN_ERR "comedi%d: PLX-Bug detected\n", dev->minor); - - if (swap_regbase_tmp) { - regbase_tmp = plx_regbase_tmp; - plx_regbase_tmp = swap_regbase_tmp; - swap_regbase_tmp = regbase_tmp; - - result = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (result != PCIBIOS_SUCCESSFUL) - return -EIO; - - result = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_5, - swap_regbase_tmp); - if (result != PCIBIOS_SUCCESSFUL) - return -EIO; - } else { - plx_regbase_tmp -= 0x80; - result = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (result != PCIBIOS_SUCCESSFUL) - return -EIO; - } - } - /*--------------------------------------------- Workaround end -----*/ - - /* Read Meilhaus register base address [PCI_BASE_ADDRESS #2]. */ - me_regbase_tmp = pci_resource_start(pcidev, 2); - me_regbase_size_tmp = pci_resource_len(pcidev, 2); - dev_private->me_regbase_size = me_regbase_size_tmp; - dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp); - if (!dev_private->me_regbase) { - printk(KERN_ERR "comedi%d: Failed to remap I/O memory\n", - dev->minor); + dev_private->me_regbase = ioremap(pci_resource_start(pcidev, 2), + pci_resource_len(pcidev, 2)); + if (!dev_private->me_regbase) return -ENOMEM; - } /* Download firmware and reset card */ if (board->device_id == ME2600_DEVICE_ID) { - result = me2600_upload_firmware(dev); - if (result < 0) - return result; + ret = me2600_upload_firmware(dev); + if (ret < 0) + return ret; } me_reset(dev); - error = comedi_alloc_subdevices(dev, 3); - if (error) - return error; + 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_CMD_READ; - s->n_chan = board->ai_channel_nbr; - s->maxdata = board->ai_resolution_mask; - s->len_chanlist = board->ai_channel_nbr; - s->range_table = board->ai_range_list; - s->cancel = me_ai_cancel; - s->insn_read = me_ai_insn_read; - s->do_cmdtest = me_ai_do_cmd_test; - s->do_cmd = me_ai_do_cmd; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON; + 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]; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; - s->n_chan = board->ao_channel_nbr; - s->maxdata = board->ao_resolution_mask; - s->len_chanlist = board->ao_channel_nbr; - s->range_table = board->ao_range_list; - s->insn_read = me_ao_insn_read; - s->insn_write = me_ao_insn_write; + if (board->has_ao) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; + s->n_chan = 4; + s->maxdata = 0x0fff; + s->len_chanlist = 4; + s->range_table = &me_ao_range; + s->insn_read = me_ao_insn_read; + s->insn_write = me_ao_insn_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; - s->n_chan = board->dio_channel_nbr; - s->maxdata = 1; - s->len_chanlist = board->dio_channel_nbr; - s->range_table = &range_digital; - s->insn_bits = me_dio_insn_bits; - s->insn_config = me_dio_insn_config; - s->io_bits = 0; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + 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; + s->io_bits = 0; dev_info(dev->class_dev, "%s: %s attached\n", dev->driver->driver_name, dev->board_name); @@ -775,6 +590,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) static void me_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct me_private_data *dev_private = dev->private; if (dev_private) { if (dev_private->me_regbase) { @@ -785,26 +601,25 @@ static void me_detach(struct comedi_device *dev) iounmap(dev_private->plx_regbase); } if (pcidev) { - if (dev_private->plx_regbase_size) + if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver me_daq_driver = { .driver_name = "me_daq", .module = THIS_MODULE, - .attach_pci = me_attach_pci, + .auto_attach = me_auto_attach, .detach = me_detach, }; -static int __devinit me_daq_pci_probe(struct pci_dev *dev, +static int me_daq_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &me_daq_driver); } -static void __devexit me_daq_pci_remove(struct pci_dev *dev) +static void me_daq_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -820,7 +635,7 @@ static struct pci_driver me_daq_pci_driver = { .name = "me_daq", .id_table = me_daq_pci_table, .probe = me_daq_pci_probe, - .remove = __devexit_p(me_daq_pci_remove), + .remove = me_daq_pci_remove, }; module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver); diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index f8b7fae..67dc5ad 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -122,13 +122,12 @@ Configuration Options: #define MPC624_SPEED_6_875_Hz \ (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0) /* -------------------------------------------------------------------------- */ -struct skel_private { +struct mpc624_private { /* set by mpc624_attach() from driver's parameters */ unsigned long int ulConvertionRate; }; -#define devpriv ((struct skel_private *)dev->private) /* -------------------------------------------------------------------------- */ static const struct comedi_lrange range_mpc624_bipolar1 = { 1, @@ -155,6 +154,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct mpc624_private *devpriv = dev->private; int n, i; unsigned long int data_in, data_out; unsigned char ucPort; @@ -283,6 +283,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct mpc624_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int ret; @@ -297,9 +298,10 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->board_name = "mpc624"; - /* Private structure initialization */ - if (alloc_private(dev, sizeof(struct skel_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; switch (it->options[1]) { case 0: diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c deleted file mode 100644 index c0c3329..0000000 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - comedi/drivers/mpc8260.c - driver for digital I/O pins on the MPC 8260 CPM module - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org> - - 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -/* -Driver: mpc8260cpm -Description: MPC8260 CPM module generic digital I/O lines -Devices: [Motorola] MPC8260 CPM (mpc8260cpm) -Author: ds -Status: experimental -Updated: Sat, 16 Mar 2002 17:34:48 -0800 - -This driver is specific to the Motorola MPC8260 processor, allowing -you to access the processor's generic digital I/O lines. - -It is apparently missing some code. -*/ - -#include "../comedidev.h" - -extern unsigned long mpc8260_dio_reserved[4]; - -struct mpc8260cpm_private { - - int data; - -}; - -#define devpriv ((struct mpc8260cpm_private *)dev->private) - -static unsigned long *cpm_pdat(int port) -{ - switch (port) { - case 0: - return &io->iop_pdata; - case 1: - return &io->iop_pdatb; - case 2: - return &io->iop_pdatc; - case 3: - return &io->iop_pdatd; - } -} - -static int mpc8260cpm_dio_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int n; - unsigned int d; - unsigned int mask; - int port; - - port = (int)s->private; - mask = 1 << CR_CHAN(insn->chanspec); - if (mask & cpm_reserved_bits[port]) { - return -EINVAL; - } - - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= mask; - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~mask; - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - } - - switch (port) { - case 0: - return &io->iop_pdira; - case 1: - return &io->iop_pdirb; - case 2: - return &io->iop_pdirc; - case 3: - return &io->iop_pdird; - } - - return 1; -} - -static int mpc8260cpm_dio_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int port; - unsigned long *p; - - p = cpm_pdat((int)s->private); - - return insn->n; -} - -static int mpc8260cpm_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int i; - int ret; - - printk("comedi%d: mpc8260cpm: ", dev->minor); - - dev->board_ptr = mpc8260cpm_boards + dev->board; - - dev->board_name = thisboard->name; - - if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) - return -ENOMEM; - - ret =comedi_alloc_subdevices(dev, 4); - if (ret) - return ret; - - for (i = 0; i < 4; i++) { - s = &dev->subdevices[i]; - 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_config = mpc8260cpm_dio_config; - s->insn_bits = mpc8260cpm_dio_bits; - } - - return 1; -} - -static void mpc8260cpm_detach(struct comedi_device *dev) -{ - /* Nothing to cleanup */ -} - -static struct comedi_driver mpc8260cpm_driver = { - .driver_name = "mpc8260cpm", - .module = THIS_MODULE, - .attach = mpc8260cpm_attach, - .detach = mpc8260cpm_detach, -}; -module_comedi_driver(mpc8260cpm_driver); diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index 4625cb4..1f5f402 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -86,7 +86,6 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3) struct multiq3_private { unsigned int ao_readback[2]; }; -#define devpriv ((struct multiq3_private *)dev->private) static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, @@ -129,6 +128,7 @@ static int multiq3_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct multiq3_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -142,6 +142,7 @@ static int multiq3_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct multiq3_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -230,6 +231,7 @@ static void encoder_reset(struct comedi_device *dev) static int multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct multiq3_private *devpriv; int result = 0; unsigned long iobase; unsigned int irq; @@ -256,9 +258,10 @@ static int multiq3_attach(struct comedi_device *dev, if (result) return result; - result = alloc_private(dev, sizeof(struct multiq3_private)); - if (result < 0) - return result; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; /* ai subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 51295f3..5196b460 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -112,12 +112,11 @@ struct ni6527_private { unsigned int filter_enable; }; -#define devpriv ((struct ni6527_private *)dev->private) - 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; int chan = CR_CHAN(insn->chanspec); unsigned int interval; @@ -164,6 +163,8 @@ static int ni6527_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni6527_private *devpriv = dev->private; + data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0)); data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8; data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16; @@ -175,6 +176,8 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni6527_private *devpriv = dev->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -202,6 +205,7 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, static irqreturn_t ni6527_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct ni6527_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[2]; unsigned int status; @@ -243,29 +247,13 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -281,6 +269,7 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, static int ni6527_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni6527_private *devpriv = dev->private; /* struct comedi_cmd *cmd = &s->async->cmd; */ writeb(ClrEdge | ClrOverflow, @@ -295,6 +284,8 @@ static int ni6527_intr_cmd(struct comedi_device *dev, static int ni6527_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni6527_private *devpriv = dev->private; + writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); return 0; @@ -312,6 +303,8 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni6527_private *devpriv = dev->private; + if (insn->n < 1) return -EINVAL; if (data[0] != INSN_CONFIG_CHANGE_NOTIFY) @@ -348,15 +341,18 @@ ni6527_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni6527_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int ni6527_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct ni6527_private *devpriv; struct comedi_subdevice *s; int ret; - ret = alloc_private(dev, sizeof(struct ni6527_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = ni6527_find_boardinfo(pcidev); if (!dev->board_ptr) @@ -430,6 +426,8 @@ static int __devinit ni6527_attach_pci(struct comedi_device *dev, static void ni6527_detach(struct comedi_device *dev) { + struct ni6527_private *devpriv = dev->private; + if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); @@ -444,17 +442,17 @@ static void ni6527_detach(struct comedi_device *dev) static struct comedi_driver ni6527_driver = { .driver_name = DRIVER_NAME, .module = THIS_MODULE, - .attach_pci = ni6527_attach_pci, + .auto_attach = ni6527_auto_attach, .detach = ni6527_detach, }; -static int __devinit ni6527_pci_probe(struct pci_dev *dev, +static int ni6527_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni6527_driver); } -static void __devexit ni6527_pci_remove(struct pci_dev *dev) +static void ni6527_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -463,7 +461,7 @@ static struct pci_driver ni6527_pci_driver = { .name = DRIVER_NAME, .id_table = ni6527_pci_table, .probe = ni6527_pci_probe, - .remove = __devexit_p(ni6527_pci_remove) + .remove = ni6527_pci_remove }; module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 2a73ff5..2fb4b77 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -48,7 +48,6 @@ except maybe the 6514. */ -#define _GNU_SOURCE #define DEBUG 1 #define DEBUG_FLAGS #include <linux/interrupt.h> @@ -291,11 +290,6 @@ struct ni_65xx_private { unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS]; }; -static inline struct ni_65xx_private *private(struct comedi_device *dev) -{ - return dev->private; -} - struct ni_65xx_subdevice_private { unsigned base_port; }; @@ -319,6 +313,7 @@ static int ni_65xx_config_filter(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; const unsigned chan = CR_CHAN(insn->chanspec); const unsigned port = sprivate(s)->base_port + ni_65xx_port_by_channel(chan); @@ -335,22 +330,22 @@ static int ni_65xx_config_filter(struct comedi_device *dev, interval = max_filter_interval; data[1] = interval * filter_resolution_ns; - if (interval != private(dev)->filter_interval) { + if (interval != devpriv->filter_interval) { writeb(interval, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Filter_Interval); - private(dev)->filter_interval = interval; + devpriv->filter_interval = interval; } - private(dev)->filter_enable[port] |= + devpriv->filter_enable[port] |= 1 << (chan % ni_65xx_channels_per_port); } else { - private(dev)->filter_enable[port] &= + devpriv->filter_enable[port] &= ~(1 << (chan % ni_65xx_channels_per_port)); } - writeb(private(dev)->filter_enable[port], - private(dev)->mite->daq_io_addr + Filter_Enable(port)); + writeb(devpriv->filter_enable[port], + devpriv->mite->daq_io_addr + Filter_Enable(port)); return 2; } @@ -359,6 +354,7 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; unsigned port; if (insn->n < 1) @@ -372,21 +368,21 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev, case INSN_CONFIG_DIO_OUTPUT: if (s->type != COMEDI_SUBD_DIO) return -EINVAL; - private(dev)->dio_direction[port] = COMEDI_OUTPUT; - writeb(0, private(dev)->mite->daq_io_addr + Port_Select(port)); + devpriv->dio_direction[port] = COMEDI_OUTPUT; + writeb(0, devpriv->mite->daq_io_addr + Port_Select(port)); return 1; break; case INSN_CONFIG_DIO_INPUT: if (s->type != COMEDI_SUBD_DIO) return -EINVAL; - private(dev)->dio_direction[port] = COMEDI_INPUT; - writeb(1, private(dev)->mite->daq_io_addr + Port_Select(port)); + devpriv->dio_direction[port] = COMEDI_INPUT; + writeb(1, devpriv->mite->daq_io_addr + Port_Select(port)); return 1; break; case INSN_CONFIG_DIO_QUERY: if (s->type != COMEDI_SUBD_DIO) return -EINVAL; - data[1] = private(dev)->dio_direction[port]; + data[1] = devpriv->dio_direction[port]; return insn->n; break; default: @@ -399,6 +395,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; unsigned base_bitfield_channel; const unsigned max_ports_per_bitfield = 5; unsigned read_bits = 0; @@ -432,18 +429,18 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, port_data &= 0xff; if (port_mask) { unsigned bits; - private(dev)->output_bits[port] &= ~port_mask; - private(dev)->output_bits[port] |= + devpriv->output_bits[port] &= ~port_mask; + devpriv->output_bits[port] |= port_data & port_mask; - bits = private(dev)->output_bits[port]; + bits = devpriv->output_bits[port]; if (board(dev)->invert_outputs) bits = ~bits; writeb(bits, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Port_Data(port)); } port_read_bits = - readb(private(dev)->mite->daq_io_addr + Port_Data(port)); + readb(devpriv->mite->daq_io_addr + Port_Data(port)); if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) { /* Outputs inverted, so invert value read back from * DO subdevice. (Does not apply to boards with DIO @@ -464,17 +461,18 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, static irqreturn_t ni_65xx_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct ni_65xx_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[2]; unsigned int status; - status = readb(private(dev)->mite->daq_io_addr + Change_Status); + status = readb(devpriv->mite->daq_io_addr + Change_Status); if ((status & MasterInterruptStatus) == 0) return IRQ_NONE; if ((status & EdgeStatus) == 0) return IRQ_NONE; writeb(ClrEdge | ClrOverflow, - private(dev)->mite->daq_io_addr + Clear_Register); + devpriv->mite->daq_io_addr + Clear_Register); comedi_buf_put(s->async, 0); s->async->events |= COMEDI_CB_EOS; @@ -505,29 +503,13 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -543,13 +525,14 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, static int ni_65xx_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_65xx_private *devpriv = dev->private; /* struct comedi_cmd *cmd = &s->async->cmd; */ writeb(ClrEdge | ClrOverflow, - private(dev)->mite->daq_io_addr + Clear_Register); + devpriv->mite->daq_io_addr + Clear_Register); writeb(FallingEdgeIntEnable | RisingEdgeIntEnable | MasterInterruptEnable | EdgeIntEnable, - private(dev)->mite->daq_io_addr + Master_Interrupt_Control); + devpriv->mite->daq_io_addr + Master_Interrupt_Control); return 0; } @@ -557,8 +540,9 @@ static int ni_65xx_intr_cmd(struct comedi_device *dev, static int ni_65xx_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - writeb(0x00, - private(dev)->mite->daq_io_addr + Master_Interrupt_Control); + struct ni_65xx_private *devpriv = dev->private; + + writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); return 0; } @@ -576,35 +560,37 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; + if (insn->n < 1) return -EINVAL; if (data[0] != INSN_CONFIG_CHANGE_NOTIFY) return -EINVAL; writeb(data[1], - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0)); writeb(data[1] >> 8, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x10)); writeb(data[1] >> 16, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x20)); writeb(data[1] >> 24, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x30)); writeb(data[2], - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0)); writeb(data[2] >> 8, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x10)); writeb(data[2] >> 16, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x20)); writeb(data[2] >> 24, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x30)); return 2; @@ -624,35 +610,38 @@ ni_65xx_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int ni_65xx_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct ni_65xx_private *devpriv; struct comedi_subdevice *s; unsigned i; int ret; - ret = alloc_private(dev, sizeof(struct ni_65xx_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = ni_65xx_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; - private(dev)->mite = mite_alloc(pcidev); - if (!private(dev)->mite) + devpriv->mite = mite_alloc(pcidev); + if (!devpriv->mite) return -ENOMEM; - ret = mite_setup(private(dev)->mite); + ret = mite_setup(devpriv->mite); if (ret < 0) { dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } dev->board_name = board(dev)->name; - dev->irq = mite_irq(private(dev)->mite); + dev->irq = mite_irq(devpriv->mite); dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name, - readb(private(dev)->mite->daq_io_addr + ID_Register)); + readb(devpriv->mite->daq_io_addr + ID_Register)); ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -710,7 +699,7 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, for (i = 0; i < board(dev)->num_dio_ports; ++i) { /* configure all ports for input */ writeb(0x1, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Port_Select(i)); } } else { @@ -732,21 +721,21 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) { writeb(0x00, - private(dev)->mite->daq_io_addr + Filter_Enable(i)); + devpriv->mite->daq_io_addr + Filter_Enable(i)); if (board(dev)->invert_outputs) writeb(0x01, - private(dev)->mite->daq_io_addr + Port_Data(i)); + devpriv->mite->daq_io_addr + Port_Data(i)); else writeb(0x00, - private(dev)->mite->daq_io_addr + Port_Data(i)); + devpriv->mite->daq_io_addr + Port_Data(i)); } writeb(ClrEdge | ClrOverflow, - private(dev)->mite->daq_io_addr + Clear_Register); + devpriv->mite->daq_io_addr + Clear_Register); writeb(0x00, - private(dev)->mite->daq_io_addr + Master_Interrupt_Control); + devpriv->mite->daq_io_addr + Master_Interrupt_Control); /* Set filter interval to 0 (32bit reg) */ - writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval); + writeb(0x00000000, devpriv->mite->daq_io_addr + Filter_Interval); ret = request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED, "ni_65xx", dev); @@ -760,15 +749,16 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, static void ni_65xx_detach(struct comedi_device *dev) { - if (private(dev) && private(dev)->mite - && private(dev)->mite->daq_io_addr) { + struct ni_65xx_private *devpriv = dev->private; + + if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) { writeb(0x00, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Master_Interrupt_Control); } if (dev->irq) free_irq(dev->irq, dev); - if (private(dev)) { + if (devpriv) { struct comedi_subdevice *s; unsigned i; @@ -777,9 +767,9 @@ static void ni_65xx_detach(struct comedi_device *dev) kfree(s->private); s->private = NULL; } - if (private(dev)->mite) { - mite_unsetup(private(dev)->mite); - mite_free(private(dev)->mite); + if (devpriv->mite) { + mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); } } } @@ -787,17 +777,17 @@ static void ni_65xx_detach(struct comedi_device *dev) static struct comedi_driver ni_65xx_driver = { .driver_name = "ni_65xx", .module = THIS_MODULE, - .attach_pci = ni_65xx_attach_pci, + .auto_attach = ni_65xx_auto_attach, .detach = ni_65xx_detach, }; -static int __devinit ni_65xx_pci_probe(struct pci_dev *dev, +static int ni_65xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_65xx_driver); } -static void __devexit ni_65xx_pci_remove(struct pci_dev *dev) +static void ni_65xx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -806,7 +796,7 @@ static struct pci_driver ni_65xx_pci_driver = { .name = "ni_65xx", .id_table = ni_65xx_pci_table, .probe = ni_65xx_pci_probe, - .remove = __devexit_p(ni_65xx_pci_remove) + .remove = ni_65xx_pci_remove }; module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index df2f3b0..26baf9c 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -419,16 +419,6 @@ static const struct ni_660x_board ni_660x_boards[] = { #define NI_660X_MAX_NUM_CHIPS 2 #define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip) -static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); - struct ni_660x_private { struct mite_struct *mite; struct ni_gpct_device *counter_dev; @@ -443,78 +433,11 @@ struct ni_660x_private { unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; }; -static inline struct ni_660x_private *private(struct comedi_device *dev) -{ - return dev->private; -} - -/* initialized in ni_660x_attach_pci() */ -static inline const struct ni_660x_board *board(struct comedi_device *dev) -{ - return dev->board_ptr; -} - -static int ni_660x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev); -static void ni_660x_detach(struct comedi_device *dev); -static void init_tio_chip(struct comedi_device *dev, int chipset); -static void ni_660x_select_pfi_output(struct comedi_device *dev, - unsigned pfi_channel, - unsigned output_select); - -static struct comedi_driver ni_660x_driver = { - .driver_name = "ni_660x", - .module = THIS_MODULE, - .attach_pci = ni_660x_attach_pci, - .detach = ni_660x_detach, -}; - -static int __devinit ni_660x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &ni_660x_driver); -} - -static void __devexit ni_660x_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver ni_660x_pci_driver = { - .name = "ni_660x", - .id_table = ni_660x_pci_table, - .probe = ni_660x_pci_probe, - .remove = __devexit_p(ni_660x_pci_remove) -}; -module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); - -static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, - unsigned source); - -/* Possible instructions for a GPCT */ -static int ni_660x_GPCT_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ni_660x_GPCT_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int ni_660x_GPCT_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Possible instructions for Digital IO */ -static int ni_660x_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int ni_660x_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - static inline unsigned ni_660x_num_counters(struct comedi_device *dev) { - return board(dev)->n_chips * counters_per_chip; + const struct ni_660x_board *board = comedi_board(dev); + + return board->n_chips * counters_per_chip; } static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg) @@ -737,8 +660,9 @@ static inline void ni_660x_write_register(struct comedi_device *dev, unsigned chip_index, unsigned bits, enum NI_660x_Register reg) { + struct ni_660x_private *devpriv = dev->private; void __iomem *write_address = - private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + + devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; switch (registerData[reg].size) { @@ -758,8 +682,9 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, unsigned chip_index, enum NI_660x_Register reg) { + struct ni_660x_private *devpriv = dev->private; void __iomem *read_address = - private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + + devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; switch (registerData[reg].size) { @@ -806,54 +731,56 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, unsigned mite_channel, struct ni_gpct *counter) { + struct ni_660x_private *devpriv = dev->private; unsigned long flags; - spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags); - private(dev)->dma_configuration_soft_copies[counter->chip_index] &= + + spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + devpriv->dma_configuration_soft_copies[counter->chip_index] &= ~dma_select_mask(mite_channel); - private(dev)->dma_configuration_soft_copies[counter->chip_index] |= + devpriv->dma_configuration_soft_copies[counter->chip_index] |= dma_select_bits(mite_channel, dma_selection_counter(counter->counter_index)); ni_660x_write_register(dev, counter->chip_index, - private(dev)-> - dma_configuration_soft_copies + devpriv->dma_configuration_soft_copies [counter->chip_index] | dma_reset_bit(mite_channel), DMAConfigRegister); mmiowb(); - spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags); + spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, unsigned mite_channel, struct ni_gpct *counter) { + struct ni_660x_private *devpriv = dev->private; unsigned long flags; - spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags); - private(dev)->dma_configuration_soft_copies[counter->chip_index] &= + + spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + devpriv->dma_configuration_soft_copies[counter->chip_index] &= ~dma_select_mask(mite_channel); - private(dev)->dma_configuration_soft_copies[counter->chip_index] |= + devpriv->dma_configuration_soft_copies[counter->chip_index] |= dma_select_bits(mite_channel, dma_selection_none); ni_660x_write_register(dev, counter->chip_index, - private(dev)-> - dma_configuration_soft_copies + devpriv->dma_configuration_soft_copies [counter->chip_index], DMAConfigRegister); mmiowb(); - spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags); + spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } 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; unsigned long flags; struct mite_channel *mite_chan; - spin_lock_irqsave(&private(dev)->mite_channel_lock, flags); + spin_lock_irqsave(&devpriv->mite_channel_lock, flags); BUG_ON(counter->mite_chan); - mite_chan = - mite_request_channel(private(dev)->mite, mite_ring(private(dev), - counter)); + mite_chan = mite_request_channel(devpriv->mite, + mite_ring(devpriv, counter)); if (mite_chan == NULL) { - spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags); + spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); comedi_error(dev, "failed to reserve mite dma channel for counter."); return -EBUSY; @@ -861,16 +788,17 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev, 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(&private(dev)->mite_channel_lock, flags); + 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(&private(dev)->mite_channel_lock, flags); + spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (counter->mite_chan) { struct mite_channel *mite_chan = counter->mite_chan; @@ -878,7 +806,7 @@ static void ni_660x_release_mite_channel(struct comedi_device *dev, ni_tio_set_mite_channel(counter, NULL); mite_release_channel(mite_chan); } - spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags); + spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); } static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s) @@ -947,6 +875,7 @@ static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev, 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 i; unsigned long flags; @@ -954,24 +883,26 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) if (dev->attached == 0) return IRQ_NONE; /* lock to avoid race with comedi_poll */ - spin_lock_irqsave(&private(dev)->interrupt_lock, flags); + spin_lock_irqsave(&devpriv->interrupt_lock, flags); smp_mb(); for (i = 0; i < ni_660x_num_counters(dev); ++i) { s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; ni_660x_handle_gpct_interrupt(dev, s); } - spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags); + 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; unsigned long flags; + /* lock to avoid race with comedi_poll */ - spin_lock_irqsave(&private(dev)->interrupt_lock, flags); + spin_lock_irqsave(&devpriv->interrupt_lock, flags); mite_sync_input_dma(subdev_to_counter(s)->mite_chan, s->async); - spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags); + spin_unlock_irqrestore(&devpriv->interrupt_lock, flags); return comedi_buf_read_n_available(s->async); } @@ -979,9 +910,10 @@ static int ni_660x_buf_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_660x_private *devpriv = dev->private; int ret; - ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)), + ret = mite_buf_change(mite_ring(devpriv, subdev_to_counter(s)), s->async); if (ret < 0) return ret; @@ -991,32 +923,35 @@ static int ni_660x_buf_change(struct comedi_device *dev, static int ni_660x_allocate_private(struct comedi_device *dev) { - int retval; + struct ni_660x_private *devpriv; unsigned i; - retval = alloc_private(dev, sizeof(struct ni_660x_private)); - if (retval < 0) - return retval; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; - spin_lock_init(&private(dev)->mite_channel_lock); - spin_lock_init(&private(dev)->interrupt_lock); - spin_lock_init(&private(dev)->soft_reg_copy_lock); + spin_lock_init(&devpriv->mite_channel_lock); + spin_lock_init(&devpriv->interrupt_lock); + spin_lock_init(&devpriv->soft_reg_copy_lock); for (i = 0; i < NUM_PFI_CHANNELS; ++i) - private(dev)->pfi_output_selects[i] = pfi_output_select_counter; + devpriv->pfi_output_selects[i] = pfi_output_select_counter; return 0; } static int ni_660x_alloc_mite_rings(struct comedi_device *dev) { + const struct ni_660x_board *board = comedi_board(dev); + struct ni_660x_private *devpriv = dev->private; unsigned i; unsigned j; - for (i = 0; i < board(dev)->n_chips; ++i) { + for (i = 0; i < board->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) { - private(dev)->mite_rings[i][j] = - mite_alloc_ring(private(dev)->mite); - if (private(dev)->mite_rings[i][j] == NULL) + devpriv->mite_rings[i][j] = + mite_alloc_ring(devpriv->mite); + if (devpriv->mite_rings[i][j] == NULL) return -ENOMEM; } } @@ -1025,12 +960,14 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev) static void ni_660x_free_mite_rings(struct comedi_device *dev) { + const struct ni_660x_board *board = comedi_board(dev); + struct ni_660x_private *devpriv = dev->private; unsigned i; unsigned j; - for (i = 0; i < board(dev)->n_chips; ++i) { + for (i = 0; i < board->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) - mite_free_ring(private(dev)->mite_rings[i][j]); + mite_free_ring(devpriv->mite_rings[i][j]); } } @@ -1048,145 +985,6 @@ ni_660x_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_660x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - struct comedi_subdevice *s; - int ret; - unsigned i; - unsigned global_interrupt_config_bits; - - ret = ni_660x_allocate_private(dev); - if (ret < 0) - return ret; - dev->board_ptr = ni_660x_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - private(dev)->mite = mite_alloc(pcidev); - if (!private(dev)->mite) - return -ENOMEM; - - dev->board_name = board(dev)->name; - - ret = mite_setup2(private(dev)->mite, 1); - if (ret < 0) { - dev_warn(dev->class_dev, "error setting up mite\n"); - return ret; - } - comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev); - ret = ni_660x_alloc_mite_rings(dev); - if (ret < 0) - return ret; - - ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); - if (ret) - return ret; - - s = &dev->subdevices[0]; - /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ - s->type = COMEDI_SUBD_UNUSED; - - s = &dev->subdevices[NI_660X_DIO_SUBDEV]; - /* DIGITAL I/O SUBDEVICE */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 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; - s->io_bits = 0; /* all bits default to input */ - /* we use the ioconfig registers to control dio direction, so zero - output enables in stc dio control reg */ - ni_660x_write_register(dev, 0, 0, STCDIOControl); - - private(dev)->counter_dev = ni_gpct_device_construct(dev, - &ni_gpct_write_register, - &ni_gpct_read_register, - ni_gpct_variant_660x, - ni_660x_num_counters - (dev)); - if (private(dev)->counter_dev == NULL) - return -ENOMEM; - for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { - s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; - if (i < ni_660x_num_counters(dev)) { - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | - SDF_CMD_READ /* | SDF_CMD_WRITE */ ; - s->n_chan = 3; - s->maxdata = 0xffffffff; - s->insn_read = ni_660x_GPCT_rinsn; - s->insn_write = ni_660x_GPCT_winsn; - s->insn_config = ni_660x_GPCT_insn_config; - s->do_cmd = &ni_660x_cmd; - s->len_chanlist = 1; - s->do_cmdtest = &ni_660x_cmdtest; - s->cancel = &ni_660x_cancel; - s->poll = &ni_660x_input_poll; - s->async_dma_dir = DMA_BIDIRECTIONAL; - s->buf_change = &ni_660x_buf_change; - s->private = &private(dev)->counter_dev->counters[i]; - - private(dev)->counter_dev->counters[i].chip_index = - i / counters_per_chip; - private(dev)->counter_dev->counters[i].counter_index = - i % counters_per_chip; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - } - for (i = 0; i < board(dev)->n_chips; ++i) - init_tio_chip(dev, i); - - for (i = 0; i < ni_660x_num_counters(dev); ++i) - ni_tio_init_counter(&private(dev)->counter_dev->counters[i]); - - for (i = 0; i < NUM_PFI_CHANNELS; ++i) { - if (i < min_counter_pfi_chan) - ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); - else - ni_660x_set_pfi_routing(dev, i, - pfi_output_select_counter); - ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); - } - /* 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(dev)->n_chips; ++i) - set_tio_counterswap(dev, i); - - ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt, - IRQF_SHARED, "ni_660x", dev); - if (ret < 0) { - dev_warn(dev->class_dev, " irq not available\n"); - return ret; - } - dev->irq = mite_irq(private(dev)->mite); - global_interrupt_config_bits = Global_Int_Enable_Bit; - if (board(dev)->n_chips > 1) - global_interrupt_config_bits |= Cascade_Int_Enable_Bit; - ni_660x_write_register(dev, 0, global_interrupt_config_bits, - GlobalInterruptConfigRegister); - dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); - return 0; -} - -static void ni_660x_detach(struct comedi_device *dev) -{ - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->private) { - if (private(dev)->counter_dev) - ni_gpct_device_destroy(private(dev)->counter_dev); - if (private(dev)->mite) { - ni_660x_free_mite_rings(dev); - mite_unsetup(private(dev)->mite); - mite_free(private(dev)->mite); - } - } -} - static int ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1196,17 +994,17 @@ ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static void init_tio_chip(struct comedi_device *dev, int chipset) { + struct ni_660x_private *devpriv = dev->private; unsigned i; /* init dma configuration register */ - private(dev)->dma_configuration_soft_copies[chipset] = 0; + devpriv->dma_configuration_soft_copies[chipset] = 0; for (i = 0; i < MAX_DMA_CHANNEL; ++i) { - private(dev)->dma_configuration_soft_copies[chipset] |= + devpriv->dma_configuration_soft_copies[chipset] |= dma_select_bits(i, dma_selection_none) & dma_select_mask(i); } ni_660x_write_register(dev, chipset, - private(dev)-> - dma_configuration_soft_copies[chipset], + devpriv->dma_configuration_soft_copies[chipset], DMAConfigRegister); for (i = 0; i < NUM_PFI_CHANNELS; ++i) ni_660x_write_register(dev, chipset, 0, IOConfigReg(i)); @@ -1251,6 +1049,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel, unsigned output_select) { + const struct ni_660x_board *board = comedi_board(dev); static const unsigned counter_4_7_first_pfi = 8; static const unsigned counter_4_7_last_pfi = 23; unsigned active_chipset = 0; @@ -1258,7 +1057,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned active_bits; unsigned idle_bits; - if (board(dev)->n_chips > 1) { + if (board->n_chips > 1) { if (output_select == pfi_output_select_counter && pfi_channel >= counter_4_7_first_pfi && pfi_channel <= counter_4_7_last_pfi) { @@ -1294,6 +1093,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { + struct ni_660x_private *devpriv = dev->private; + if (source > num_pfi_output_selects) return -EINVAL; if (source == pfi_output_select_high_Z) @@ -1305,76 +1106,249 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, if (source == pfi_output_select_do) return -EINVAL; } - BUG_ON(chan >= NUM_PFI_CHANNELS); - private(dev)->pfi_output_selects[chan] = source; - if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan)) + devpriv->pfi_output_selects[chan] = source; + if (devpriv->pfi_direction_bits & (((uint64_t) 1) << chan)) ni_660x_select_pfi_output(dev, chan, - private(dev)-> - pfi_output_selects[chan]); + devpriv->pfi_output_selects[chan]); return 0; } -static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev, - unsigned chan) -{ - BUG_ON(chan >= NUM_PFI_CHANNELS); - return private(dev)->pfi_output_selects[chan]; -} - -static void ni660x_config_filter(struct comedi_device *dev, - unsigned pfi_channel, - enum ni_gpct_filter_select filter) -{ - unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel)); - bits &= ~pfi_input_select_mask(pfi_channel); - bits |= pfi_input_select_bits(pfi_channel, filter); - ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel)); -} - static int ni_660x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - int chan = CR_CHAN(insn->chanspec); - - /* 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 - * value COMEDI_INPUT or COMEDI_OUTPUT. */ + struct ni_660x_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + uint64_t bit = 1ULL << chan; + unsigned int val; + int ret; switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan; + devpriv->pfi_direction_bits |= bit; ni_660x_select_pfi_output(dev, chan, - private(dev)-> - pfi_output_selects[chan]); + devpriv->pfi_output_selects[chan]); break; + case INSN_CONFIG_DIO_INPUT: - private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan); + devpriv->pfi_direction_bits &= ~bit; ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z); break; + case INSN_CONFIG_DIO_QUERY: - data[1] = - (private(dev)->pfi_direction_bits & - (((uint64_t) 1) << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; - return 0; + data[1] = (devpriv->pfi_direction_bits & bit) ? COMEDI_OUTPUT + : COMEDI_INPUT; + break; + case INSN_CONFIG_SET_ROUTING: - return ni_660x_set_pfi_routing(dev, chan, data[1]); + 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); + data[1] = devpriv->pfi_output_selects[chan]; break; + case INSN_CONFIG_FILTER: - ni660x_config_filter(dev, chan, data[1]); + val = ni_660x_read_register(dev, 0, IOConfigReg(chan)); + val &= ~pfi_input_select_mask(chan); + val |= pfi_input_select_bits(chan, data[1]); + ni_660x_write_register(dev, 0, val, IOConfigReg(chan)); break; + default: return -EINVAL; - break; } + + return insn->n; +} + +static int ni_660x_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct ni_660x_board *board; + struct ni_660x_private *devpriv; + struct comedi_subdevice *s; + int ret; + unsigned i; + unsigned global_interrupt_config_bits; + + ret = ni_660x_allocate_private(dev); + if (ret < 0) + return ret; + devpriv = dev->private; + + dev->board_ptr = ni_660x_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + board = comedi_board(dev); + + devpriv->mite = mite_alloc(pcidev); + if (!devpriv->mite) + return -ENOMEM; + + dev->board_name = board->name; + + ret = mite_setup2(devpriv->mite, 1); + if (ret < 0) { + dev_warn(dev->class_dev, "error setting up mite\n"); + return ret; + } + + ret = ni_660x_alloc_mite_rings(dev); + if (ret < 0) + return ret; + + ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); + if (ret) + return ret; + + s = &dev->subdevices[0]; + /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ + s->type = COMEDI_SUBD_UNUSED; + + s = &dev->subdevices[NI_660X_DIO_SUBDEV]; + /* DIGITAL I/O SUBDEVICE */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 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; + s->io_bits = 0; /* all bits default to input */ + /* we use the ioconfig registers to control dio direction, so zero + output enables in stc dio control reg */ + ni_660x_write_register(dev, 0, 0, STCDIOControl); + + devpriv->counter_dev = ni_gpct_device_construct(dev, + &ni_gpct_write_register, + &ni_gpct_read_register, + ni_gpct_variant_660x, + ni_660x_num_counters + (dev)); + if (devpriv->counter_dev == NULL) + return -ENOMEM; + for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { + s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; + if (i < ni_660x_num_counters(dev)) { + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = + SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | + SDF_CMD_READ /* | SDF_CMD_WRITE */ ; + s->n_chan = 3; + s->maxdata = 0xffffffff; + s->insn_read = ni_660x_GPCT_rinsn; + s->insn_write = ni_660x_GPCT_winsn; + s->insn_config = ni_660x_GPCT_insn_config; + s->do_cmd = &ni_660x_cmd; + s->len_chanlist = 1; + s->do_cmdtest = &ni_660x_cmdtest; + s->cancel = &ni_660x_cancel; + s->poll = &ni_660x_input_poll; + s->async_dma_dir = DMA_BIDIRECTIONAL; + s->buf_change = &ni_660x_buf_change; + s->private = &devpriv->counter_dev->counters[i]; + + devpriv->counter_dev->counters[i].chip_index = + i / counters_per_chip; + devpriv->counter_dev->counters[i].counter_index = + i % counters_per_chip; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + } + for (i = 0; i < board->n_chips; ++i) + init_tio_chip(dev, i); + + for (i = 0; i < ni_660x_num_counters(dev); ++i) + ni_tio_init_counter(&devpriv->counter_dev->counters[i]); + + for (i = 0; i < NUM_PFI_CHANNELS; ++i) { + if (i < min_counter_pfi_chan) + ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); + else + ni_660x_set_pfi_routing(dev, i, + pfi_output_select_counter); + ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); + } + /* 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(mite_irq(devpriv->mite), ni_660x_interrupt, + IRQF_SHARED, "ni_660x", dev); + if (ret < 0) { + dev_warn(dev->class_dev, " irq not available\n"); + return ret; + } + dev->irq = mite_irq(devpriv->mite); + global_interrupt_config_bits = Global_Int_Enable_Bit; + if (board->n_chips > 1) + global_interrupt_config_bits |= Cascade_Int_Enable_Bit; + ni_660x_write_register(dev, 0, global_interrupt_config_bits, + GlobalInterruptConfigRegister); + dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); return 0; } +static void ni_660x_detach(struct comedi_device *dev) +{ + struct ni_660x_private *devpriv = dev->private; + + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (devpriv->counter_dev) + ni_gpct_device_destroy(devpriv->counter_dev); + if (devpriv->mite) { + ni_660x_free_mite_rings(dev); + mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } + } +} + +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 *ent) +{ + return comedi_pci_auto_config(dev, &ni_660x_driver); +} + +static void ni_660x_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)}, + {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 = ni_660x_pci_remove, +}; +module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index eac6dc0..272caeb 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -201,19 +201,21 @@ ni_670x_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_670x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int ni_670x_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct ni_670x_board *thisboard; struct ni_670x_private *devpriv; struct comedi_subdevice *s; int ret; int i; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + dev->board_ptr = ni_670x_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; @@ -297,17 +299,17 @@ static void ni_670x_detach(struct comedi_device *dev) static struct comedi_driver ni_670x_driver = { .driver_name = "ni_670x", .module = THIS_MODULE, - .attach_pci = ni_670x_attach_pci, + .auto_attach = ni_670x_auto_attach, .detach = ni_670x_detach, }; -static int __devinit ni_670x_pci_probe(struct pci_dev *dev, +static int ni_670x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_670x_driver); } -static void __devexit ni_670x_pci_remove(struct pci_dev *dev) +static void ni_670x_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -320,10 +322,10 @@ static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { MODULE_DEVICE_TABLE(pci, ni_670x_pci_table); static struct pci_driver ni_670x_pci_driver = { - .name ="ni_670x", + .name = "ni_670x", .id_table = ni_670x_pci_table, .probe = ni_670x_pci_probe, - .remove = __devexit_p(ni_670x_pci_remove), + .remove = ni_670x_pci_remove, }; module_comedi_pci_driver(ni_670x_driver, ni_670x_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 8395080..06de25b 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -169,8 +169,6 @@ struct a2150_private { int config_bits; /* config register bits */ }; -#define devpriv ((struct a2150_private *)dev->private) - static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, @@ -182,6 +180,8 @@ static int a2150_set_chanlist(struct comedi_device *dev, static void ni_dump_regs(struct comedi_device *dev) { + struct a2150_private *devpriv = dev->private; + printk("config bits 0x%x\n", devpriv->config_bits); printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits); printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG)); @@ -196,6 +196,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) int status; unsigned long flags; struct comedi_device *dev = d; + struct a2150_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; struct comedi_cmd *cmd; @@ -300,6 +301,8 @@ static irqreturn_t a2150_interrupt(int irq, void *d) static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct a2150_private *devpriv = dev->private; + /* 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); @@ -342,37 +345,21 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -425,6 +412,7 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct a2150_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned long lock_flags; @@ -536,6 +524,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 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 i, n; static const int timeout = 100000; static const int filter_delay = 36; @@ -615,6 +604,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, int flags) { + struct a2150_private *devpriv = dev->private; int lub, glb, temp; int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index; int i, j; @@ -689,6 +679,8 @@ 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; @@ -727,6 +719,7 @@ static int a2150_probe(struct comedi_device *dev) static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct a2150_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = it->options[0]; unsigned int irq = it->options[1]; @@ -749,9 +742,10 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) } printk("\n"); - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct a2150_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; if (iobase == 0) { printk(" io base address required\n"); @@ -855,6 +849,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void a2150_detach(struct comedi_device *dev) { + struct a2150_private *devpriv = dev->private; + if (dev->iobase) { outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG); release_region(dev->iobase, A2150_SIZE); diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 93938ce..907f65c 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -167,10 +167,10 @@ struct atao_private { unsigned int ao_readback[10]; }; -#define devpriv ((struct atao_private *)dev->private) - 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; @@ -202,6 +202,7 @@ static void atao_reset(struct comedi_device *dev) static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atao_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); short bits; @@ -226,6 +227,7 @@ static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atao_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -254,6 +256,7 @@ 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; int chan = CR_CHAN(insn->chanspec); unsigned int mask, bit; @@ -309,6 +312,7 @@ static int atao_calib_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atao_private *devpriv = dev->private; unsigned int bitstring, bit; unsigned int chan = CR_CHAN(insn->chanspec); @@ -331,6 +335,7 @@ static int atao_calib_insn_write(struct comedi_device *dev, static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct atao_board *board = comedi_board(dev); + struct atao_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int ao_unipolar; @@ -351,8 +356,10 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - if (alloc_private(dev, sizeof(struct atao_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index cac2557..2cc2996 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -284,8 +284,6 @@ struct ni_private { }; -#define devpriv ((struct ni_private *)dev->private) - /* How we access registers */ #define ni_writel(a, b) (outl((a), (b)+dev->iobase)) @@ -303,6 +301,7 @@ struct ni_private { static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -317,6 +316,7 @@ static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr) static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; uint16_t ret; @@ -406,16 +406,17 @@ static int ni_getboardtype(struct comedi_device *dev) static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct ni_private *devpriv; struct pnp_dev *isapnp_dev; int ret; unsigned long iobase; int board; unsigned int irq; - /* allocate private area */ ret = ni_alloc_private(dev); - if (ret < 0) + if (ret) return ret; + devpriv = dev->private; devpriv->stc_writew = &ni_atmio_win_out; devpriv->stc_readw = &ni_atmio_win_in; @@ -499,6 +500,8 @@ static int ni_atmio_attach(struct comedi_device *dev, static void ni_atmio_detach(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + mio_common_detach(dev); if (dev->iobase) release_region(dev->iobase, NI_SIZE); diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index e91a620..4a17494f 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -102,7 +102,6 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d) #define CLOCK_100_HZ 0x8F25 /* Other miscellaneous defines */ #define ATMIO16D_SIZE 32 /* bus address range */ -#define devpriv ((struct atmio16d_private *)dev->private) #define ATMIO16D_TIMEOUT 10 struct atmio16_board_t { @@ -202,6 +201,7 @@ static void reset_counters(struct comedi_device *dev) static void reset_atmio16d(struct comedi_device *dev) { + struct atmio16d_private *devpriv = dev->private; int i; /* now we need to initialize the board */ @@ -271,51 +271,32 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } if (cmd->scan_begin_src == TRIG_FOLLOW) { /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } else { #if 0 /* external trigger */ /* should be level/edge, hi/lo specification here */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); #endif } - if (cmd->convert_arg < 10000) { - cmd->convert_arg = 10000; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); #if 0 - if (cmd->convert_arg > SLOWEST_TIMER) { - cmd->convert_arg = SLOWEST_TIMER; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, SLOWEST_TIMER); #endif - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -327,6 +308,7 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, 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; @@ -486,6 +468,7 @@ 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, t; int chan; int gain; @@ -539,6 +522,7 @@ static int atmio16d_ao_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; for (i = 0; i < insn->n; i++) @@ -550,6 +534,7 @@ 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; int i; int chan; int d; @@ -596,6 +581,7 @@ static int atmio16d_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct atmio16d_private *devpriv = dev->private; int i; int mask; @@ -651,6 +637,7 @@ static int atmio16d_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct atmio16_board_t *board = comedi_board(dev); + struct atmio16d_private *devpriv; unsigned int irq; unsigned long iobase; int ret; @@ -672,9 +659,10 @@ static int atmio16d_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(struct atmio16d_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* reset the atmio16d hardware */ reset_atmio16d(dev); diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 0ca222b..7b33335 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -96,8 +96,6 @@ struct dio24_private { int data; /* number of data points left to be taken */ }; -#define devpriv ((struct dio24_private *)dev->private) - static struct comedi_driver driver_dio24 = { .driver_name = "ni_daq_dio24", .module = THIS_MODULE, @@ -110,6 +108,7 @@ static struct comedi_driver driver_dio24 = { static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dio24_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = 0; #ifdef incomplete @@ -118,9 +117,10 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pcmcia_device *link; int ret; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct dio24_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { @@ -202,7 +202,7 @@ static int dio24_cs_attach(struct pcmcia_device *link) { struct local_info_t *local; - printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n"); + dev_info(&link->dev, "ni_daq_dio24: HOLA SOY YO - CS-attach!\n"); dev_dbg(&link->dev, "dio24_cs_attach()\n"); @@ -242,7 +242,7 @@ static void dio24_config(struct pcmcia_device *link) { int ret; - printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n"); + dev_info(&link->dev, "ni_daq_dio24: HOLA SOY YO! - config\n"); dev_dbg(&link->dev, "dio24_config\n"); @@ -265,7 +265,7 @@ static void dio24_config(struct pcmcia_device *link) return; failed: - printk(KERN_INFO "Fallo"); + dev_info(&link->dev, "Fallo"); dio24_release(link); } /* dio24_config */ diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index b5a19a0..d29c4d7 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -487,8 +487,6 @@ static const int dma_buffer_size = 0xff00; /* 2 bytes per sample */ static const int sample_size = 2; -#define devpriv ((struct labpc_private *)dev->private) - static inline int labpc_counter_load(struct comedi_device *dev, unsigned long base_address, unsigned int counter_number, @@ -504,6 +502,7 @@ static inline int labpc_counter_load(struct comedi_device *dev, int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, unsigned int irq, unsigned int dma_chan) { + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s; int i; unsigned long isr_flags; @@ -697,18 +696,23 @@ labpc_pci_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit labpc_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int labpc_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct labpc_private *devpriv; unsigned long iobase; unsigned int irq; int ret; if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) return -ENODEV; - ret = alloc_private(dev, sizeof(struct labpc_private)); - if (ret < 0) - return ret; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + dev->board_ptr = labpc_pci_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; @@ -725,13 +729,15 @@ static int __devinit labpc_attach_pci(struct comedi_device *dev, static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct labpc_private *devpriv; unsigned long iobase = 0; unsigned int irq = 0; unsigned int dma_chan = 0; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct labpc_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { @@ -770,6 +776,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) void labpc_common_detach(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s; if (!thisboard) @@ -799,6 +806,8 @@ EXPORT_SYMBOL_GPL(labpc_common_detach); static void labpc_clear_adc_fifo(const struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; + devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG); devpriv->read_byte(dev->iobase + ADC_FIFO_REG); devpriv->read_byte(dev->iobase + ADC_FIFO_REG); @@ -806,6 +815,7 @@ static void labpc_clear_adc_fifo(const struct comedi_device *dev) 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); @@ -1016,56 +1026,34 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg == TRIG_NOW && cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + if (cmd->start_arg == TRIG_NOW) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (!cmd->chanlist_len) - err++; + err |= -EINVAL; + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } /* make sure scan timing is not too fast */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->convert_src == TRIG_TIMER && - cmd->scan_begin_arg < - cmd->convert_arg * cmd->chanlist_len) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->chanlist_len; - err++; - } - if (cmd->scan_begin_arg < - thisboard->ai_speed * cmd->chanlist_len) { - cmd->scan_begin_arg = - thisboard->ai_speed * cmd->chanlist_len; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + cmd->convert_arg * cmd->chanlist_len); + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->ai_speed * cmd->chanlist_len); } - /* stop source */ + switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; /* * TRIG_EXT doesn't care since it doesn't @@ -1098,6 +1086,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct labpc_private *devpriv = dev->private; int channel, range, aref; #ifdef CONFIG_ISA_DMA_API unsigned long irq_flags; @@ -1365,6 +1354,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static irqreturn_t labpc_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; struct comedi_cmd *cmd; @@ -1453,6 +1443,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) /* read all available samples from ai fifo */ static int labpc_drain_fifo(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; unsigned int lsb, msb; short data; struct comedi_async *async = dev->read_subdev->async; @@ -1488,6 +1479,7 @@ static int labpc_drain_fifo(struct comedi_device *dev) #ifdef CONFIG_ISA_DMA_API static void labpc_drain_dma(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; int status; @@ -1541,6 +1533,8 @@ static void labpc_drain_dma(struct comedi_device *dev) static void handle_isa_dma(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; + labpc_drain_dma(dev); enable_dma(devpriv->dma_chan); @@ -1555,6 +1549,8 @@ static void handle_isa_dma(struct comedi_device *dev) static void labpc_drain_dregs(struct comedi_device *dev) { #ifdef CONFIG_ISA_DMA_API + struct labpc_private *devpriv = dev->private; + if (devpriv->current_transfer == isa_dma_transfer) labpc_drain_dma(dev); #endif @@ -1565,6 +1561,7 @@ static void labpc_drain_dregs(struct comedi_device *dev) static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; int i, n; int chan, range; int lsb, msb; @@ -1654,6 +1651,7 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; int channel, range; unsigned long flags; int lsb, msb; @@ -1695,6 +1693,8 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int labpc_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; + data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; return 1; @@ -1704,6 +1704,8 @@ static int labpc_calib_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; + data[0] = devpriv->caldac[CR_CHAN(insn->chanspec)]; return 1; @@ -1723,6 +1725,8 @@ static int labpc_eeprom_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; + data[0] = devpriv->eeprom_data[CR_CHAN(insn->chanspec)]; return 1; @@ -1779,6 +1783,7 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd) static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd, enum scan_mode mode) { + struct labpc_private *devpriv = dev->private; /* max value for 16 bit counter in mode 2 */ const int max_counter_value = 0x10000; /* min value for 16 bit counter in mode 2 */ @@ -1885,6 +1890,7 @@ static int labpc_dio_mem_callback(int dir, int port, int data, 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++) { @@ -1909,6 +1915,7 @@ static void labpc_serial_out(struct comedi_device *dev, unsigned int value, /* 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 */ @@ -1938,6 +1945,7 @@ static unsigned int labpc_serial_in(struct comedi_device *dev) 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; @@ -1970,6 +1978,7 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev, static int 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 */ @@ -2027,6 +2036,7 @@ static int labpc_eeprom_write(struct comedi_device *dev, 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 */ @@ -2056,6 +2066,8 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev) static void write_caldac(struct comedi_device *dev, unsigned int channel, unsigned int value) { + struct labpc_private *devpriv = dev->private; + if (value == devpriv->caldac[channel]) return; devpriv->caldac[channel] = value; @@ -2084,7 +2096,7 @@ static struct comedi_driver labpc_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = labpc_attach, - .attach_pci = labpc_attach_pci, + .auto_attach = labpc_auto_attach, .detach = labpc_common_detach, .num_names = ARRAY_SIZE(labpc_boards), .board_name = &labpc_boards[0].name, @@ -2098,13 +2110,13 @@ static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { }; MODULE_DEVICE_TABLE(pci, labpc_pci_table); -static int __devinit labpc_pci_probe(struct pci_dev *dev, +static int labpc_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &labpc_driver); } -static void __devexit labpc_pci_remove(struct pci_dev *dev) +static void labpc_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -2113,7 +2125,7 @@ static struct pci_driver labpc_pci_driver = { .name = DRV_NAME, .id_table = labpc_pci_table, .probe = labpc_pci_probe, - .remove = __devexit_p(labpc_pci_remove) + .remove = labpc_pci_remove }; module_comedi_pci_driver(labpc_driver, labpc_pci_driver); #else diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index eb0417e..bfe19fa 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -127,13 +127,15 @@ static struct comedi_driver driver_labpc_cs = { static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct labpc_private *devpriv; unsigned long iobase = 0; unsigned int irq = 0; struct pcmcia_device *link; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct labpc_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 3e5fdae..56dc599 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -410,6 +410,7 @@ static void get_last_sample_6143(struct comedi_device *dev); static inline void ni_set_bitfield(struct comedi_device *dev, int reg, unsigned bit_mask, unsigned bit_values) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); @@ -506,6 +507,7 @@ static inline void ni_set_gpct_dma_channel(struct comedi_device *dev, static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, int mite_channel) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); @@ -525,6 +527,7 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, static int ni_request_ai_mite_channel(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -545,6 +548,7 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev) static int ni_request_ao_mite_channel(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -567,6 +571,7 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev, unsigned gpct_index, enum comedi_io_direction direction) { + struct ni_private *devpriv = dev->private; unsigned long flags; struct mite_channel *mite_chan; @@ -595,6 +600,7 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev, static int ni_request_cdo_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); @@ -617,6 +623,7 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev) 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); @@ -632,6 +639,7 @@ static void ni_release_ai_mite_channel(struct comedi_device *dev) 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); @@ -648,6 +656,7 @@ static void ni_release_ao_mite_channel(struct comedi_device *dev) static void ni_release_gpct_mite_channel(struct comedi_device *dev, unsigned gpct_index) { + struct ni_private *devpriv = dev->private; unsigned long flags; BUG_ON(gpct_index >= NUM_GPCT); @@ -669,6 +678,7 @@ static void ni_release_gpct_mite_channel(struct comedi_device *dev, static void ni_release_cdo_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); @@ -686,6 +696,8 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev) static void ni_e_series_enable_second_irq(struct comedi_device *dev, unsigned gpct_index, short enable) { + struct ni_private *devpriv = dev->private; + if (boardtype.reg_type & ni_reg_m_series_mask) return; switch (gpct_index) { @@ -716,6 +728,8 @@ static void ni_e_series_enable_second_irq(struct comedi_device *dev, static void ni_clear_ai_fifo(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + if (boardtype.reg_type == ni_reg_6143) { /* Flush the 6143 data FIFO */ ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */ @@ -742,13 +756,17 @@ static void ni_clear_ai_fifo(struct comedi_device *dev) static void win_out2(struct comedi_device *dev, uint32_t data, int reg) { + struct ni_private *devpriv = dev->private; + devpriv->stc_writew(dev, data >> 16, reg); devpriv->stc_writew(dev, data & 0xffff, reg + 1); } static uint32_t win_in2(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; uint32_t bits; + bits = devpriv->stc_readw(dev, reg) << 16; bits |= devpriv->stc_readw(dev, reg + 1); return bits; @@ -758,6 +776,7 @@ static uint32_t win_in2(struct comedi_device *dev, int reg) static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -769,6 +788,7 @@ static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data, static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -779,6 +799,7 @@ static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data, 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; @@ -814,6 +835,7 @@ static inline void ni_set_bits(struct comedi_device *dev, int reg, static irqreturn_t ni_E_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct ni_private *devpriv = dev->private; unsigned short a_status; unsigned short b_status; unsigned int ai_mite_status = 0; @@ -872,6 +894,7 @@ static irqreturn_t ni_E_interrupt(int irq, void *d) #ifdef PCIDMA static void ni_sync_ai_dma(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; unsigned long flags; @@ -884,6 +907,7 @@ static void ni_sync_ai_dma(struct comedi_device *dev) static void mite_handle_b_linkc(struct mite_struct *mite, struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; unsigned long flags; @@ -896,6 +920,7 @@ static void mite_handle_b_linkc(struct mite_struct *mite, static int ni_ao_wait_for_dma_load(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; static const int timeout = 10000; int i; for (i = 0; i < timeout; i++) { @@ -918,6 +943,8 @@ static int ni_ao_wait_for_dma_load(struct comedi_device *dev) #endif /* PCIDMA */ 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; @@ -984,6 +1011,7 @@ 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)]; @@ -997,6 +1025,7 @@ static void handle_gpct_interrupt(struct comedi_device *dev, static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) { + struct ni_private *devpriv = dev->private; unsigned short ack = 0; if (a_status & AI_SC_TC_St) { @@ -1019,6 +1048,7 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, unsigned ai_mite_status) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */ @@ -1122,7 +1152,9 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) { + struct ni_private *devpriv = dev->private; unsigned short ack = 0; + if (b_status & AO_BC_TC_St) { ack |= AO_BC_TC_Interrupt_Ack; } @@ -1151,8 +1183,10 @@ static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) static void handle_b_interrupt(struct comedi_device *dev, unsigned short b_status, unsigned ao_mite_status) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; /* unsigned short ack=0; */ + #ifdef DEBUG_INTERRUPT printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n", b_status, ao_mite_status); @@ -1340,6 +1374,7 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, static int ni_ao_prep_fifo(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; int n; /* reset fifo */ @@ -1364,6 +1399,7 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, 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; int i; @@ -1434,6 +1470,7 @@ static void ni_handle_fifo_half_full(struct comedi_device *dev) #ifdef PCIDMA 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; @@ -1471,6 +1508,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev) */ static void ni_handle_fifo_dregs(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data[2]; u32 dl; @@ -1535,6 +1573,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) static void get_last_sample_611x(struct comedi_device *dev) { + struct ni_private *devpriv __maybe_unused = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; @@ -1552,6 +1591,7 @@ static void get_last_sample_611x(struct comedi_device *dev) static void get_last_sample_6143(struct comedi_device *dev) { + struct ni_private *devpriv __maybe_unused = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; @@ -1574,11 +1614,13 @@ 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; unsigned int i; unsigned int length = num_bytes / bytes_per_sample(s); short *array = data; unsigned int *larray = data; + for (i = 0; i < length; i++) { #ifdef PCIDMA if (s->subdev_flags & SDF_LSAMPL) @@ -1599,6 +1641,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ai_setup_MITE_dma(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; int retval; unsigned long flags; @@ -1638,6 +1681,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev) static int ni_ao_setup_MITE_dma(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; int retval; unsigned long flags; @@ -1676,6 +1720,8 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev) static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; + ni_release_ai_mite_channel(dev); /* ai configuration */ devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset, @@ -1786,6 +1832,7 @@ 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; int i, n; const unsigned int mask = (1 << boardtype.adbits) - 1; unsigned signbits; @@ -1881,7 +1928,9 @@ static int ni_ai_insn_read(struct comedi_device *dev, static void ni_prime_channelgain_list(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; int i; + devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register); for (i = 0; i < NI_TIMEOUT; ++i) { if (!(devpriv->stc_readw(dev, @@ -1899,6 +1948,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, unsigned int n_chan, unsigned int *list) { + struct ni_private *devpriv = dev->private; unsigned int chan, range, aref; unsigned int i; unsigned offset; @@ -2004,6 +2054,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_chan, unsigned int *list) { + struct ni_private *devpriv = dev->private; unsigned int chan, range, aref; unsigned int i; unsigned int hi, lo; @@ -2122,7 +2173,9 @@ static void ni_load_channelgain_list(struct comedi_device *dev, static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec, int round_mode) { + struct ni_private *devpriv = dev->private; int divider; + switch (round_mode) { case TRIG_ROUND_NEAREST: default: @@ -2140,6 +2193,8 @@ static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec, static unsigned ni_timer_to_ns(const struct comedi_device *dev, int timer) { + struct ni_private *devpriv = dev->private; + return devpriv->clock_ns * (timer + 1); } @@ -2162,6 +2217,7 @@ static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev, static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct ni_private *devpriv = dev->private; int err = 0; int tmp; unsigned int sources; @@ -2200,7 +2256,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->start_src == TRIG_EXT) { /* external trigger */ @@ -2209,30 +2265,17 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 16) tmp = 16; tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE)); - if (cmd->start_arg != tmp) { - cmd->start_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp); } else { - if (cmd->start_arg != 0) { - /* true for both TRIG_NOW and TRIG_INT */ - cmd->start_arg = 0; - err++; - } + /* true for both TRIG_NOW and TRIG_INT */ + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); } + if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev, - cmd-> - chanlist_len)) - { - cmd->scan_begin_arg = - ni_min_ai_scan_period_ns(dev, cmd->chanlist_len); - err++; - } - if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { - cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + ni_min_ai_scan_period_ns(dev, cmd->chanlist_len)); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + devpriv->clock_ns * 0xffffff); } else if (cmd->scan_begin_src == TRIG_EXT) { /* external trigger */ unsigned int tmp = CR_CHAN(cmd->scan_begin_arg); @@ -2240,32 +2283,20 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 16) tmp = 16; tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE)); - if (cmd->scan_begin_arg != tmp) { - cmd->scan_begin_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp); } else { /* TRIG_OTHER */ - if (cmd->scan_begin_arg) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } + if (cmd->convert_src == TRIG_TIMER) { if ((boardtype.reg_type == ni_reg_611x) || (boardtype.reg_type == ni_reg_6143)) { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } else { - if (cmd->convert_arg < boardtype.ai_speed) { - cmd->convert_arg = boardtype.ai_speed; - err++; - } - if (cmd->convert_arg > devpriv->clock_ns * 0xffff) { - cmd->convert_arg = devpriv->clock_ns * 0xffff; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + boardtype.ai_speed); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + devpriv->clock_ns * 0xffff); } } else if (cmd->convert_src == TRIG_EXT) { /* external trigger */ @@ -2274,40 +2305,23 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 16) tmp = 16; tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT)); - if (cmd->convert_arg != tmp) { - cmd->convert_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp); } else if (cmd->convert_src == TRIG_NOW) { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { unsigned int max_count = 0x01000000; if (boardtype.reg_type == ni_reg_611x) max_count -= num_adc_stages_611x; - if (cmd->stop_arg > max_count) { - cmd->stop_arg = max_count; - err++; - } - if (cmd->stop_arg < 1) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, max_count); + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -2356,6 +2370,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 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 */ @@ -2662,6 +2677,8 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct ni_private *devpriv = dev->private; + if (trignum != 0) return -EINVAL; @@ -2681,6 +2698,8 @@ static int ni_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + if (insn->n < 1) return -EINVAL; @@ -2734,6 +2753,7 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned int a, b, modebits; int err = 0; @@ -2857,6 +2877,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, unsigned int chanspec[], unsigned int n_chans, int timed) { + struct ni_private *devpriv = dev->private; unsigned int range; unsigned int chan; unsigned int conf; @@ -2928,6 +2949,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, unsigned int chanspec[], unsigned int n_chans) { + struct ni_private *devpriv = dev->private; unsigned int range; unsigned int chan; unsigned int conf; @@ -2984,6 +3006,8 @@ static int ni_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + data[0] = devpriv->ao[CR_CHAN(insn->chanspec)]; return 1; @@ -2993,6 +3017,7 @@ 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 invert; @@ -3013,6 +3038,7 @@ static int ni_ao_insn_write_671x(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 invert; @@ -3031,6 +3057,8 @@ static int ni_ao_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_GET_HARDWARE_BUFFER_SIZE: switch (data[1]) { @@ -3057,6 +3085,7 @@ static int ni_ao_insn_config(struct comedi_device *dev, static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct ni_private *devpriv = dev->private; int ret; int interrupt_b_bits; int i; @@ -3126,6 +3155,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, 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; int bits; int i; @@ -3330,6 +3360,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct ni_private *devpriv = dev->private; int err = 0; int tmp; @@ -3359,7 +3390,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->start_src == TRIG_EXT) { /* external trigger */ @@ -3368,48 +3399,27 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 18) tmp = 18; tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE)); - if (cmd->start_arg != tmp) { - cmd->start_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp); } else { - if (cmd->start_arg != 0) { - /* true for both TRIG_NOW and TRIG_INT */ - cmd->start_arg = 0; - err++; - } + /* true for both TRIG_NOW and TRIG_INT */ + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); } + if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < boardtype.ao_speed) { - cmd->scan_begin_arg = boardtype.ao_speed; - err++; - } - if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { /* XXX check */ - cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff; - err++; - } - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { /* XXX check */ - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + boardtype.ao_speed); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + devpriv->clock_ns * 0xffffff); } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + if (err) return 3; @@ -3438,6 +3448,8 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; + /* devpriv->ao0p=0x0000; */ /* ni_writew(devpriv->ao0p,AO_Configuration); */ @@ -3491,6 +3503,8 @@ 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; + #ifdef DEBUG_DIO printk("ni_dio_insn_config() chan=%d io=%d\n", CR_CHAN(insn->chanspec), data[0]); @@ -3524,6 +3538,8 @@ 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; + #ifdef DEBUG_DIO printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]); #endif @@ -3552,6 +3568,8 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv __maybe_unused = dev->private; + #ifdef DEBUG_DIO printk("ni_m_series_dio_insn_config() chan=%d io=%d\n", CR_CHAN(insn->chanspec), data[0]); @@ -3584,6 +3602,8 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv __maybe_unused = dev->private; + #ifdef DEBUG_DIO printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]); @@ -3623,39 +3643,18 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_src == TRIG_INT) { - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - } - if (cmd->scan_begin_src == TRIG_EXT) { - tmp = cmd->scan_begin_arg; - tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0, - CR_INVERT); - if (tmp != cmd->scan_begin_arg) { - err++; - } - } - if (cmd->convert_src == TRIG_NOW) { - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + tmp = cmd->scan_begin_arg; + tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0, CR_INVERT); + if (tmp != cmd->scan_begin_arg) + err |= -EINVAL; + + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -3680,6 +3679,7 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv __maybe_unused = dev->private; const struct comedi_cmd *cmd = &s->async->cmd; unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit; int retval; @@ -3719,6 +3719,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { #ifdef PCIDMA + struct ni_private *devpriv = dev->private; unsigned long flags; #endif int retval = 0; @@ -3766,6 +3767,8 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv __maybe_unused = dev->private; + ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit | CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit | CDO_FIFO_Request_Interrupt_Enable_Clear_Bit, @@ -3781,6 +3784,7 @@ static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static void handle_cdio_interrupt(struct comedi_device *dev) { + struct ni_private *devpriv __maybe_unused = dev->private; unsigned cdio_status; struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV]; #ifdef PCIDMA @@ -3824,6 +3828,7 @@ 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; int err = insn->n; unsigned char byte_out, byte_in = 0; @@ -3920,6 +3925,7 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, unsigned char data_out, unsigned char *data_in) { + struct ni_private *devpriv = dev->private; unsigned int status1; int err = 0, count = 20; @@ -3978,6 +3984,7 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, unsigned char data_out, unsigned char *data_in) { + struct ni_private *devpriv = dev->private; unsigned char mask, input = 0; #ifdef DEBUG_DIO @@ -4031,9 +4038,10 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, static void mio_common_detach(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s; - if (dev->private) { + if (devpriv) { if (devpriv->counter_dev) { ni_gpct_device_destroy(devpriv->counter_dev); } @@ -4151,6 +4159,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; + struct ni_private *devpriv = dev->private; unsigned stc_register; /* bits in the join reset register which are relevant to counters */ static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset; @@ -4219,7 +4228,9 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; + struct ni_private *devpriv = dev->private; unsigned stc_register; + switch (reg) { /* m-series only registers */ case NITIO_G0_DMA_Status_Reg: @@ -4251,6 +4262,8 @@ 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; + data[0] = devpriv->clock_and_fout & FOUT_Divider_mask; return 1; } @@ -4259,6 +4272,8 @@ 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; + devpriv->clock_and_fout &= ~FOUT_Enable; devpriv->stc_writew(dev, devpriv->clock_and_fout, Clock_and_FOUT_Register); @@ -4273,6 +4288,8 @@ static int ni_freq_out_insn_write(struct comedi_device *dev, static int ni_set_freq_out_clock(struct comedi_device *dev, unsigned int clock_source) { + struct ni_private *devpriv = dev->private; + switch (clock_source) { case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC: devpriv->clock_and_fout &= ~FOUT_Timebase_Select; @@ -4292,6 +4309,8 @@ static void ni_get_freq_out_clock(struct comedi_device *dev, unsigned int *clock_source, unsigned int *clock_period_ns) { + struct ni_private *devpriv = dev->private; + if (devpriv->clock_and_fout & FOUT_Timebase_Select) { *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC; *clock_period_ns = TIMEBASE_2_NS; @@ -4320,11 +4339,12 @@ static int ni_freq_out_insn_config(struct comedi_device *dev, static int ni_alloc_private(struct comedi_device *dev) { - int ret; + struct ni_private *devpriv; - ret = alloc_private(dev, sizeof(struct ni_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; spin_lock_init(&devpriv->window_lock); spin_lock_init(&devpriv->soft_reg_copy_lock); @@ -4335,6 +4355,7 @@ static int ni_alloc_private(struct comedi_device *dev) static int ni_E_init(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned j; enum ni_gpct_variant counter_variant; @@ -4661,6 +4682,7 @@ static int ni_E_init(struct comedi_device *dev) static int ni_8255_callback(int dir, int port, int data, unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; + struct ni_private *devpriv __maybe_unused = dev->private; if (dir) { ni_writeb(data, Port_A + 2 * port); @@ -4689,6 +4711,7 @@ static int ni_eeprom_insn_read(struct comedi_device *dev, static int ni_read_eeprom(struct comedi_device *dev, int addr) { + struct ni_private *devpriv __maybe_unused = dev->private; int bit; int bitstring; @@ -4716,6 +4739,8 @@ static int ni_m_series_eeprom_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)]; return 1; @@ -4723,6 +4748,8 @@ static int ni_m_series_eeprom_insn_read(struct comedi_device *dev, 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; @@ -4732,7 +4759,9 @@ 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 up_count, down_count; + switch (data[0]) { case INSN_CONFIG_PWM_OUTPUT: switch (data[1]) { @@ -4798,7 +4827,9 @@ 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 up_count, down_count; + switch (data[0]) { case INSN_CONFIG_PWM_OUTPUT: switch (data[1]) { @@ -4875,6 +4906,8 @@ 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; + data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)]; return 1; @@ -4905,6 +4938,7 @@ static struct caldac_struct caldacs[] = { static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; int i, j; int n_dacs; int n_chans = 0; @@ -4958,6 +4992,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) static void ni_write_caldac(struct comedi_device *dev, int addr, int val) { + struct ni_private *devpriv = dev->private; unsigned int loadbit = 0, bits = 0, bit, bitstring = 0; int i; int type; @@ -5211,8 +5246,10 @@ static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { + struct ni_private *devpriv = dev->private; unsigned pfi_reg_index; unsigned array_offset; + if ((source & 0x1f) != source) return -EINVAL; pfi_reg_index = 1 + chan / 3; @@ -5247,7 +5284,9 @@ static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan, static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev, unsigned chan) { + struct ni_private *devpriv = dev->private; const unsigned array_offset = chan / 3; + return MSeries_PFI_Output_Select_Source(chan, devpriv-> pfi_output_select_reg @@ -5306,7 +5345,9 @@ static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan) static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel, enum ni_pfi_filter_select filter) { + struct ni_private *devpriv __maybe_unused = dev->private; unsigned bits; + if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { return -ENOTSUPP; } @@ -5321,6 +5362,8 @@ 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 __maybe_unused = dev->private; + if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { return -ENOTSUPP; } @@ -5337,6 +5380,7 @@ static int ni_pfi_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; if (insn->n < 1) @@ -5379,6 +5423,8 @@ static int ni_pfi_insn_config(struct comedi_device *dev, */ static void ni_rtsi_init(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + /* Initialises the RTSI bus signal switch to a default state */ /* Set clock mode to internal */ @@ -5480,6 +5526,7 @@ static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev) static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned source, unsigned period_ns) { + struct ni_private *devpriv = dev->private; static const unsigned min_period_ns = 50; static const unsigned max_period_ns = 1000; static const unsigned timeout = 1000; @@ -5488,6 +5535,7 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned freq_multiplier; unsigned 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 */ @@ -5581,6 +5629,8 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, static int ni_set_master_clock(struct comedi_device *dev, unsigned source, unsigned period_ns) { + struct ni_private *devpriv = dev->private; + if (source == NI_MIO_INTERNAL_CLOCK) { devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit; devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, @@ -5666,6 +5716,8 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan, static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { + struct ni_private *devpriv = dev->private; + if (ni_valid_rtsi_output_source(dev, chan, source) == 0) return -EINVAL; if (chan < 4) { @@ -5686,6 +5738,8 @@ static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan, static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan) { + struct ni_private *devpriv = dev->private; + if (chan < 4) { return RTSI_Trig_Output_Source(chan, devpriv->rtsi_trig_a_output_reg); @@ -5704,7 +5758,9 @@ 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 INSN_CONFIG_DIO_OUTPUT: if (chan < num_configurable_rtsi_channels(dev)) { diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index ca4f8e0..76c6a13 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -175,9 +175,7 @@ struct ni_private { struct pcmcia_device *link; - NI_PRIVATE_COMMON}; - -#define devpriv ((struct ni_private *)dev->private) +NI_PRIVATE_COMMON}; /* How we access registers */ @@ -196,6 +194,7 @@ struct ni_private { static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -210,6 +209,7 @@ static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr) static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; uint16_t ret; @@ -251,7 +251,7 @@ static void mio_cs_config(struct pcmcia_device *link); static void cs_release(struct pcmcia_device *link); static void cs_detach(struct pcmcia_device *); -static struct pcmcia_device *cur_dev = NULL; +static struct pcmcia_device *cur_dev; static int cs_attach(struct pcmcia_device *link) { @@ -324,6 +324,7 @@ static void mio_cs_config(struct pcmcia_device *link) static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct ni_private *devpriv; struct pcmcia_device *link; unsigned int irq; int ret; @@ -339,13 +340,15 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = link->irq; - printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", - dev->minor, dev->driver->driver_name, dev->iobase, irq); + dev->board_ptr = ni_boards + ni_getboardtype(dev, link); #if 0 { int i; + printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", + dev->minor, dev->driver->driver_name, dev->iobase, irq); + printk(" board fingerprint:"); for (i = 0; i < 32; i += 2) { printk(" %04x %02x", inw(dev->iobase + i), @@ -356,26 +359,25 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (i = 0; i < 10; i++) printk(" 0x%04x", win_in(i)); printk("\n"); + + printk("boardtype.name: %s\n", boardtype.name); } #endif - dev->board_ptr = ni_boards + ni_getboardtype(dev, link); - - printk(" %s", boardtype.name); dev->board_name = boardtype.name; ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS, "ni_mio_cs", dev); if (ret < 0) { - printk(" irq not available\n"); + dev_err(dev->class_dev, "irq not available\n"); return -EINVAL; } dev->irq = irq; - /* allocate private area */ ret = ni_alloc_private(dev); - if (ret < 0) + if (ret) return ret; + devpriv = dev->private; devpriv->stc_writew = &mio_cs_win_out; devpriv->stc_readw = &mio_cs_win_in; @@ -400,7 +402,8 @@ static int ni_getboardtype(struct comedi_device *dev, return i; } - printk("unknown board 0x%04x -- pretend it is a ", link->card_id); + dev_err(dev->class_dev, + "unknown board 0x%04x -- pretend it is a ", link->card_id); return 0; } diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index bc9313e..084ebea 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -310,7 +310,6 @@ struct nidio96_private { struct mite_dma_descriptor_ring *di_mite_ring; spinlock_t mite_channel_lock; }; -#define devpriv ((struct nidio96_private *)dev->private) static int ni_pcidio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, @@ -332,6 +331,7 @@ static void ni_pcidio_print_status(unsigned int status); 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); @@ -355,6 +355,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) 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); @@ -384,6 +385,7 @@ static void ni_pcidio_event(struct comedi_device *dev, 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; @@ -400,6 +402,7 @@ static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s) 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->subdevices[0]; struct comedi_async *async = s->async; struct mite_struct *mite = devpriv->mite; @@ -609,6 +612,7 @@ static void ni_pcidio_print_status(unsigned int flags) #ifdef unused static void debug_int(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; int a, b; static int n_int; struct timeval tv; @@ -640,6 +644,8 @@ static int ni_pcidio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct nidio96_private *devpriv = dev->private; + if (insn->n != 1) return -EINVAL; switch (data[0]) { @@ -668,6 +674,8 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct nidio96_private *devpriv = dev->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -707,46 +715,32 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - /* same for both TRIG_INT and TRIG_NOW */ - cmd->start_arg = 0; - err++; - } #define MAX_SPEED (TIMER_BASE) /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } + err |= cfc_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++; + err |= -EINVAL; } } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* no limit */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -793,6 +787,7 @@ static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode) 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 */ @@ -910,6 +905,7 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) { + struct nidio96_private *devpriv = dev->private; int retval; unsigned long flags; @@ -934,6 +930,8 @@ static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_pcidio_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct nidio96_private *devpriv = dev->private; + if (trignum != 0) return -EINVAL; @@ -946,6 +944,8 @@ static int ni_pcidio_inttrig(struct comedi_device *dev, static int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct nidio96_private *devpriv = dev->private; + writeb(0x00, devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control); ni_pcidio_release_di_mite_channel(dev); @@ -956,6 +956,7 @@ static int ni_pcidio_cancel(struct comedi_device *dev, static int ni_pcidio_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct nidio96_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->di_mite_ring, s->async); @@ -970,6 +971,7 @@ static int ni_pcidio_change(struct comedi_device *dev, static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, const u8 *data, size_t data_len) { + struct nidio96_private *devpriv = dev->private; static const int timeout = 1000; int i; size_t j; @@ -1033,8 +1035,10 @@ static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index) static int pci_6534_reset_fpgas(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; int ret; int i; + writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register); for (i = 0; i < 3; ++i) { ret = pci_6534_reset_fpga(dev, i); @@ -1047,6 +1051,8 @@ static int pci_6534_reset_fpgas(struct comedi_device *dev) static void pci_6534_init_main_fpga(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; + writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register); writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register); writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register); @@ -1057,6 +1063,7 @@ static void pci_6534_init_main_fpga(struct comedi_device *dev) static int pci_6534_upload_firmware(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; int ret; const struct firmware *fw; static const char *const fw_file[3] = { @@ -1099,16 +1106,20 @@ nidio_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit nidio_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int nidio_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct nidio96_private *devpriv; struct comedi_subdevice *s; int ret; unsigned int irq; - ret = alloc_private(dev, sizeof(struct nidio96_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + spin_lock_init(&devpriv->mite_channel_lock); dev->board_ptr = nidio_find_boardinfo(pcidev); @@ -1123,7 +1134,7 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); + devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->di_mite_ring == NULL) return -ENOMEM; @@ -1184,6 +1195,8 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev, static void nidio_detach(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; + if (dev->irq) free_irq(dev->irq, dev); if (devpriv) { @@ -1201,17 +1214,17 @@ static void nidio_detach(struct comedi_device *dev) static struct comedi_driver ni_pcidio_driver = { .driver_name = "ni_pcidio", .module = THIS_MODULE, - .attach_pci = nidio_attach_pci, + .auto_attach = nidio_auto_attach, .detach = nidio_detach, }; -static int __devinit ni_pcidio_pci_probe(struct pci_dev *dev, +static int ni_pcidio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_pcidio_driver); } -static void __devexit ni_pcidio_pci_remove(struct pci_dev *dev) +static void ni_pcidio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1228,7 +1241,7 @@ static struct pci_driver ni_pcidio_pci_driver = { .name = "ni_pcidio", .id_table = ni_pcidio_pci_table, .probe = ni_pcidio_pci_probe, - .remove = __devexit_p(ni_pcidio_pci_remove), + .remove = ni_pcidio_pci_remove, }; module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index f284a90..aaac0b2 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1190,7 +1190,6 @@ static const struct ni_board_struct ni_boards[] = { struct ni_private { NI_PRIVATE_COMMON}; -#define devpriv ((struct ni_private *)dev->private) /* How we access registers */ @@ -1213,6 +1212,7 @@ NI_PRIVATE_COMMON}; static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -1223,6 +1223,7 @@ static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg) static uint16_t e_series_win_in(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; unsigned long flags; uint16_t ret; @@ -1237,7 +1238,9 @@ static uint16_t e_series_win_in(struct comedi_device *dev, int reg) static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case ADC_FIFO_Clear: offset = M_Offset_AI_FIFO_Clear; @@ -1381,8 +1384,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, /* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit) and M_Offset_SCXI_Serial_Data_Out (8 bit) */ default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return; break; @@ -1392,7 +1396,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case AI_Status_1_Register: offset = M_Offset_AI_Status_1; @@ -1416,8 +1422,9 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg) offset = M_Offset_G01_Status; break; default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return 0; break; @@ -1428,7 +1435,9 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg) static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case AI_SC_Load_A_Registers: offset = M_Offset_AI_SC_Load_A; @@ -1458,8 +1467,9 @@ static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, offset = M_Offset_G1_Load_B; break; default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return; break; @@ -1469,7 +1479,9 @@ static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case G_HW_Save_Register(0): offset = M_Offset_G0_HW_Save; @@ -1484,8 +1496,9 @@ static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg) offset = M_Offset_G1_Save; break; default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return 0; break; @@ -1516,6 +1529,7 @@ static int pcimio_dio_change(struct comedi_device *dev, static void m_series_init_eeprom_buffer(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; static const int Start_Cal_EEPROM = 0x400; static const unsigned window_size = 10; static const int serial_number_eeprom_offset = 0x4; @@ -1553,6 +1567,8 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev) static void init_6143(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + /* Disable interrupts */ devpriv->stc_writew(dev, 0, Interrupt_Control_Register); @@ -1572,10 +1588,12 @@ static void init_6143(struct comedi_device *dev) 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 (dev->private) { + if (devpriv) { mite_free_ring(devpriv->ai_mite_ring); mite_free_ring(devpriv->ao_mite_ring); mite_free_ring(devpriv->cdo_mite_ring); @@ -1602,16 +1620,19 @@ pcimio_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit pcimio_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int pcimio_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct ni_private *devpriv; int ret; dev_info(dev->class_dev, "ni_pcimio: attach %s\n", pci_name(pcidev)); ret = ni_alloc_private(dev); - if (ret < 0) + if (ret) return ret; + devpriv = dev->private; dev->board_ptr = pcimio_find_boardinfo(pcidev); if (!dev->board_ptr) @@ -1641,7 +1662,7 @@ static int __devinit pcimio_attach_pci(struct comedi_device *dev, pr_warn("error setting up mite\n"); return ret; } - comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); + devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->ai_mite_ring == NULL) return -ENOMEM; @@ -1693,6 +1714,7 @@ static int __devinit pcimio_attach_pci(struct comedi_device *dev, static int pcimio_ai_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->ai_mite_ring, s->async); @@ -1705,6 +1727,7 @@ static int pcimio_ai_change(struct comedi_device *dev, static int pcimio_ao_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->ao_mite_ring, s->async); @@ -1718,6 +1741,7 @@ static int pcimio_gpct0_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->gpct_mite_ring[0], s->async); @@ -1731,6 +1755,7 @@ static int pcimio_gpct1_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->gpct_mite_ring[1], s->async); @@ -1743,6 +1768,7 @@ static int pcimio_gpct1_change(struct comedi_device *dev, static int pcimio_dio_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->cdo_mite_ring, s->async); @@ -1755,17 +1781,17 @@ static int pcimio_dio_change(struct comedi_device *dev, static struct comedi_driver ni_pcimio_driver = { .driver_name = "ni_pcimio", .module = THIS_MODULE, - .attach_pci = pcimio_attach_pci, + .auto_attach = pcimio_auto_attach, .detach = pcimio_detach, }; -static int __devinit ni_pcimio_pci_probe(struct pci_dev *dev, +static int ni_pcimio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_pcimio_driver); } -static void __devexit ni_pcimio_pci_remove(struct pci_dev *dev) +static void ni_pcimio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1832,7 +1858,7 @@ static struct pci_driver ni_pcimio_pci_driver = { .name = "ni_pcimio", .id_table = ni_pcimio_pci_table, .probe = ni_pcimio_pci_probe, - .remove = __devexit_p(ni_pcimio_pci_remove) + .remove = ni_pcimio_pci_remove }; module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index b058820..8572996 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -120,9 +120,9 @@ struct ni_gpct { struct ni_gpct_device { struct comedi_device *dev; - void (*write_register) (struct ni_gpct * counter, unsigned bits, + void (*write_register) (struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg); - unsigned (*read_register) (struct ni_gpct * counter, + unsigned (*read_register) (struct ni_gpct *counter, enum ni_gpct_register reg); enum ni_gpct_variant variant; struct ni_gpct *counters; diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 8ee93d3..0c991b9 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -173,7 +173,8 @@ static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async) static int ni_tio_output_cmd(struct ni_gpct *counter, struct comedi_async *async) { - printk(KERN_ERR "ni_tio: output commands not yet implemented.\n"); + dev_err(counter->counter_dev->dev->class_dev, + "output commands not yet implemented.\n"); return -ENOTSUPP; counter->mite_chan->dir = COMEDI_OUTPUT; @@ -219,7 +220,10 @@ int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async) spin_lock_irqsave(&counter->lock, flags); if (counter->mite_chan == NULL) { - printk(KERN_ERR "ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n"); + 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(counter, async); @@ -271,37 +275,19 @@ int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd) if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_src != TRIG_EXT) { - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - } - if (cmd->scan_begin_src != TRIG_EXT) { - if (cmd->scan_begin_arg) { - cmd->scan_begin_arg = 0; - err++; - } - } - if (cmd->convert_src != TRIG_EXT) { - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + if (cmd->start_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->scan_begin_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + if (cmd->convert_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -427,8 +413,9 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, NITIO_Gxx_Joint_Status2_Reg (counter->counter_index)) & Gi_Permanent_Stale_Bit(counter->counter_index)) { - printk(KERN_INFO "%s: Gi_Permanent_Stale_Data detected.\n", - __func__); + dev_info(counter->counter_dev->dev->class_dev, + "%s: Gi_Permanent_Stale_Data detected.\n", + __func__); if (perm_stale_data) *perm_stale_data = 1; } @@ -448,7 +435,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error, &perm_stale_data, NULL); if (gate_error) { - printk(KERN_NOTICE "%s: Gi_Gate_Error detected.\n", __func__); + 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) @@ -459,8 +447,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, if (read_register(counter, NITIO_Gi_DMA_Status_Reg (counter->counter_index)) & Gi_DRQ_Error_Bit) { - printk(KERN_NOTICE "%s: Gi_DRQ_Error detected.\n", - __func__); + dev_notice(counter->counter_dev->dev->class_dev, + "%s: Gi_DRQ_Error detected.\n", __func__); s->async->events |= COMEDI_CB_OVERFLOW; } break; diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 89305a1..6ee5da2 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -161,14 +161,13 @@ struct pcl711_private { unsigned int divisor2; }; -#define devpriv ((struct pcl711_private *)dev->private) - static irqreturn_t pcl711_interrupt(int irq, void *d) { int lo, hi; int data; struct comedi_device *dev = d; const struct pcl711_board *board = comedi_board(dev); + struct pcl711_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; if (!dev->attached) { @@ -264,6 +263,7 @@ ok: static int pcl711_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct pcl711_private *devpriv = dev->private; int tmp; int err = 0; @@ -289,38 +289,24 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3 */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } if (cmd->scan_begin_src == TRIG_EXT) { - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } else { #define MAX_SPEED 1000 #define TIMER_BASE 100 - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); } + + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } else { /* ignore */ } @@ -349,6 +335,7 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev, static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl711_private *devpriv = dev->private; int timer1, timer2; struct comedi_cmd *cmd = &s->async->cmd; @@ -398,6 +385,7 @@ static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl711_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl711_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -417,6 +405,7 @@ static int pcl711_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl711_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -460,6 +449,7 @@ static int pcl711_do_insn_bits(struct comedi_device *dev, static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl711_board *board = comedi_board(dev); + struct pcl711_private *devpriv; int ret; unsigned long iobase; unsigned int irq; @@ -499,9 +489,10 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct pcl711_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; /* AI subdevice */ diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 07e72de..50e0196 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -152,11 +152,10 @@ struct pcl726_private { unsigned int ao_readback[12]; }; -#define devpriv ((struct pcl726_private *)dev->private) - static int pcl726_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl726_private *devpriv = dev->private; int hi, lo; int n; int chan = CR_CHAN(insn->chanspec); @@ -183,6 +182,7 @@ static int pcl726_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl726_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int n; @@ -226,6 +226,7 @@ static int pcl726_do_insn_bits(struct comedi_device *dev, static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl726_board *board = comedi_board(dev); + struct pcl726_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; @@ -247,9 +248,10 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - ret = alloc_private(dev, sizeof(struct pcl726_private)); - if (ret < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; for (i = 0; i < 12; i++) { devpriv->bipolar[i] = 0; diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 3cf55ff..560930e 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -369,8 +369,6 @@ struct pcl812_private { unsigned int ao_readback[2]; /* data for AO readback */ }; -#define devpriv ((struct pcl812_private *)dev->private) - /* ============================================================================== */ @@ -388,6 +386,7 @@ 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 n; int timeout, hi; @@ -465,6 +464,7 @@ static int pcl812_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl812_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int i; @@ -486,6 +486,7 @@ static int pcl812_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl812_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int i; @@ -533,6 +534,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; int err = 0; unsigned int flags; int tmp, divisor1, divisor2; @@ -563,53 +565,25 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ai_ns_min); + else /* TRIG_EXT */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_ns_min) { - cmd->convert_arg = board->ai_ns_min; - err++; - } - } else { /* TRIG_EXT */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, MAX_CHANLIST_LEN); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->chanlist_len > MAX_CHANLIST_LEN) { - cmd->chanlist_len = board->n_aichan; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -639,6 +613,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes; struct comedi_cmd *cmd = &s->async->cmd; @@ -789,6 +764,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) char err = 1; unsigned int mask, timeout; struct comedi_device *dev = d; + struct pcl812_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; unsigned int next_chan; @@ -862,6 +838,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, struct comedi_subdevice *s, short *ptr, unsigned int bufptr, unsigned int len) { + struct pcl812_private *devpriv = dev->private; unsigned int i; s->async->events = 0; @@ -892,6 +869,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) { struct comedi_device *dev = d; + struct pcl812_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; unsigned long dma_flags; int len, bufptr; @@ -938,6 +916,7 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) static irqreturn_t interrupt_pcl812(int irq, void *d) { struct comedi_device *dev = d; + struct pcl812_private *devpriv = dev->private; if (!dev->attached) { comedi_error(dev, "spurious interrupt"); @@ -954,6 +933,7 @@ static irqreturn_t interrupt_pcl812(int irq, void *d) */ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl812_private *devpriv = dev->private; unsigned long flags; unsigned int top1, top2, i; @@ -1002,6 +982,7 @@ static void setup_range_channel(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int rangechan, char wait) { + struct pcl812_private *devpriv = dev->private; unsigned char chan_reg = CR_CHAN(rangechan); /* normal board */ /* gain index */ unsigned char gain_reg = CR_RANGE(rangechan) + @@ -1063,8 +1044,9 @@ static void start_pacer(struct comedi_device *dev, int mode, static void free_resources(struct comedi_device *dev) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; - if (dev->private) { + if (devpriv) { if (devpriv->dmabuf[0]) free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); if (devpriv->dmabuf[1]) @@ -1084,6 +1066,8 @@ static void free_resources(struct comedi_device *dev) static int pcl812_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl812_private *devpriv = dev->private; + if (devpriv->ai_dma) disable_dma(devpriv->dma); outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */ @@ -1100,6 +1084,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev, static void pcl812_reset(struct comedi_device *dev) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; outb(0, dev->iobase + PCL812_MUX); outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN); @@ -1135,6 +1120,7 @@ static void pcl812_reset(struct comedi_device *dev) static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv; int ret, subdev; unsigned long iobase; unsigned int irq; @@ -1153,11 +1139,12 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(struct pcl812_private)); - if (ret < 0) { + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) { free_resources(dev); - return ret; /* Can't alloc mem */ + return -ENOMEM; } + dev->private = devpriv; dev->board_name = board->name; diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 0822de0..f625fda 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -126,8 +126,6 @@ struct pcl816_board { int i8254_osc_base; /* 1/frequency of on board oscilator in ns */ }; -#define devpriv ((struct pcl816_private *)dev->private) - #ifdef unused static int RTC_lock; /* RTC lock */ static int RTC_timer_lock; /* RTC int lock */ @@ -259,6 +257,7 @@ static int pcl816_ai_insn_read(struct comedi_device *dev, static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; + struct pcl816_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int low, hi; int timeout = 50; /* wait max 50us */ @@ -315,6 +314,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, struct comedi_subdevice *s, short *ptr, unsigned int bufptr, unsigned int len) { + struct pcl816_private *devpriv = dev->private; int i; s->async->events = 0; @@ -350,6 +350,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; + struct pcl816_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int len, bufptr, this_dma_buf; unsigned long dma_flags; @@ -398,6 +399,8 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) static irqreturn_t interrupt_pcl816(int irq, void *d) { struct comedi_device *dev = d; + struct pcl816_private *devpriv = dev->private; + DPRINTK("<I>"); if (!dev->attached) { @@ -481,43 +484,23 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_ns_min) { - cmd->convert_arg = board->ai_ns_min; - err++; - } - } else { /* TRIG_EXT */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ai_ns_min); + else /* TRIG_EXT */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -554,6 +537,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct pcl816_board *board = comedi_board(dev); + struct pcl816_private *devpriv = dev->private; unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq; struct comedi_cmd *cmd = &s->async->cmd; unsigned int seglen; @@ -682,6 +666,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl816_private *devpriv = dev->private; unsigned long flags; unsigned int top1, top2, i; @@ -727,6 +712,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl816_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl816_private *devpriv = dev->private; + /* DEBUG(printk("pcl816_ai_cancel()\n");) */ if (devpriv->irq_blocked > 0) { @@ -932,6 +919,7 @@ setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *chanlist, unsigned int seglen) { + struct pcl816_private *devpriv = dev->private; unsigned int i; devpriv->ai_act_chanlist_len = seglen; @@ -991,6 +979,7 @@ static int set_rtc_irq_bit(unsigned char bit) static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl816_board *board = comedi_board(dev); + struct pcl816_private *devpriv; int ret; unsigned long iobase; unsigned int irq, dma; @@ -1015,9 +1004,10 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - ret = alloc_private(dev, sizeof(struct pcl816_private)); - if (ret < 0) - return ret; /* Can't alloc mem */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_name = board->name; @@ -1216,6 +1206,7 @@ case COMEDI_SUBD_DO: static void pcl816_detach(struct comedi_device *dev) { const struct pcl816_board *board = comedi_board(dev); + struct pcl816_private *devpriv = dev->private; if (dev->private) { pcl816_ai_cancel(dev, devpriv->sub_ai); diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index d4b0859..06127a5 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -326,8 +326,6 @@ static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#define devpriv ((struct pcl818_private *)dev->private) - /* ============================================================================== */ @@ -406,6 +404,7 @@ static int pcl818_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl818_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -419,6 +418,7 @@ static int pcl818_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl818_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -478,6 +478,7 @@ static int pcl818_do_insn_bits(struct comedi_device *dev, static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int low; int timeout = 50; /* wait max 50us */ @@ -537,6 +538,7 @@ conv_finish: static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int i, len, bufptr; unsigned long flags; @@ -616,6 +618,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; unsigned long tmp; unsigned int top1, top2, i, bufptr; @@ -721,6 +724,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int i, len, lo; @@ -795,6 +799,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) static irqreturn_t interrupt_pcl818(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; if (!dev->attached) { comedi_error(dev, "premature interrupt"); @@ -861,6 +866,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; unsigned int flags; unsigned int bytes; @@ -902,6 +908,7 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; unsigned int flags; short *pole; @@ -943,6 +950,7 @@ static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev, static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int divisor1 = 0, divisor2 = 0; unsigned int seglen; @@ -1063,6 +1071,7 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, static int pcl818_ao_mode13(int mode, struct comedi_device *dev, struct comedi_subdevice *s, comedi_trig * it) { + struct pcl818_private *devpriv = dev->private; int divisor1 = 0, divisor2 = 0; if (!dev->irq) { @@ -1222,6 +1231,7 @@ static void setup_channel_list(struct comedi_device *dev, unsigned int *chanlist, unsigned int n_chan, unsigned int seglen) { + struct pcl818_private *devpriv = dev->private; int i; devpriv->act_chanlist_len = seglen; @@ -1259,6 +1269,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { const struct pcl818_board *board = comedi_board(dev); + struct pcl818_private *devpriv = dev->private; int err = 0; int tmp, divisor1 = 0, divisor2 = 0; @@ -1283,45 +1294,23 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ns_min); + else /* TRIG_EXT */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ns_min) { - cmd->convert_arg = board->ns_min; - err++; - } - } else { /* TRIG_EXT */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1358,6 +1347,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, */ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int retval; @@ -1397,6 +1387,8 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl818_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; + if (devpriv->irq_blocked > 0) { dev_dbg(dev->class_dev, "pcl818_ai_cancel()\n"); devpriv->irq_was_now_closed = 1; @@ -1482,6 +1474,7 @@ static int pcl818_check(unsigned long iobase) static void pcl818_reset(struct comedi_device *dev) { const struct pcl818_board *board = comedi_board(dev); + struct pcl818_private *devpriv = dev->private; if (devpriv->usefifo) { /* FIFO shutdown */ outb(0, dev->iobase + PCL818_FI_INTCLR); @@ -1552,6 +1545,7 @@ static int set_rtc_irq_bit(unsigned char bit) static void rtc_dropped_irq(unsigned long data) { struct comedi_device *dev = (void *)data; + struct pcl818_private *devpriv = dev->private; unsigned long flags, tmp; switch (devpriv->int818_mode) { @@ -1601,6 +1595,7 @@ static int rtc_setfreq_irq(int freq) static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl818_board *board = comedi_board(dev); + struct pcl818_private *devpriv; int ret; unsigned long iobase; unsigned int irq; @@ -1608,9 +1603,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long pages; struct comedi_subdevice *s; - ret = alloc_private(dev, sizeof(struct pcl818_private)); - if (ret < 0) - return ret; /* Can't alloc mem */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* claim our I/O space */ iobase = it->options[0]; @@ -1892,7 +1888,9 @@ no_dma: static void pcl818_detach(struct comedi_device *dev) { - if (dev->private) { + struct pcl818_private *devpriv = dev->private; + + if (devpriv) { pcl818_ai_cancel(dev, devpriv->sub_ai); pcl818_reset(dev); if (devpriv->dma) diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 4102547..5f062df 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -62,14 +62,6 @@ Copy/pasted/hacked from pcm724.c #define CR_A_MODE(a) ((a)<<5) #define CR_CW 0x80 -struct pcm3724_board { - const char *name; /* driver name */ - int dio; /* num of DIO */ - int numofports; /* num of 8255 subdevices */ - unsigned int IRQbits; /* allowed interrupts */ - unsigned int io_range; /* len of IO space */ -}; - /* used to track configured dios */ struct priv_pcm3724 { int dio_1; @@ -156,13 +148,12 @@ static void do_3724_config(struct comedi_device *dev, 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; - struct priv_pcm3724 *priv; gatecfg = 0; - priv = dev->private; mask = 1 << CR_CHAN(chanspec); if (s == s_dio1) @@ -233,36 +224,33 @@ static int subdev_3724_insn_config(struct comedi_device *dev, static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct pcm3724_board *board = comedi_board(dev); + struct priv_pcm3724 *priv; struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; - int ret, i, n_subdevices; + int ret, i; + + dev->board_name = dev->driver->driver_name; iobase = it->options[0]; - iorange = board->io_range; + iorange = PCM3724_SIZE; - ret = alloc_private(dev, sizeof(struct priv_pcm3724)); - if (ret < 0) + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - - ((struct priv_pcm3724 *)(dev->private))->dio_1 = 0; - ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0; + dev->private = priv; printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, - board->name, iobase); + dev->board_name, iobase); if (!iobase || !request_region(iobase, iorange, "pcm3724")) { printk("I/O port conflict\n"); return -EIO; } dev->iobase = iobase; - dev->board_name = board->name; printk(KERN_INFO "\n"); - n_subdevices = board->numofports; - - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; @@ -277,7 +265,6 @@ static int pcm3724_attach(struct comedi_device *dev, static void pcm3724_detach(struct comedi_device *dev) { - const struct pcm3724_board *board = comedi_board(dev); struct comedi_subdevice *s; int i; @@ -288,21 +275,14 @@ static void pcm3724_detach(struct comedi_device *dev) } } if (dev->iobase) - release_region(dev->iobase, board->io_range); + release_region(dev->iobase, PCM3724_SIZE); } -static const struct pcm3724_board boardtypes[] = { - { "pcm3724", 48, 2, 0x00fc, PCM3724_SIZE, }, -}; - static struct comedi_driver pcm3724_driver = { .driver_name = "pcm3724", .module = THIS_MODULE, .attach = pcm3724_attach, .detach = pcm3724_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcm3724_board), }; module_comedi_driver(pcm3724_driver); diff --git a/drivers/staging/comedi/drivers/pcm_common.c b/drivers/staging/comedi/drivers/pcm_common.c index 85ee05e..8a718ae 100644 --- a/drivers/staging/comedi/drivers/pcm_common.c +++ b/drivers/staging/comedi/drivers/pcm_common.c @@ -29,41 +29,19 @@ int comedi_pcm_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - - /* cmd->scan_begin_src == TRIG_EXT */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - - /* cmd->convert_src == TRIG_NOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - /* cmd->scan_end_src == TRIG_COUNT */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: /* any count allowed */ break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 5efeb92..13e8421 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -62,7 +62,6 @@ struct pcmad_priv_struct { int differential; int twos_comp; }; -#define devpriv ((struct pcmad_priv_struct *)dev->private) #define TIMEOUT 100 @@ -71,6 +70,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { const struct pcmad_board_struct *board = comedi_board(dev); + struct pcmad_priv_struct *devpriv = dev->private; int i; int chan; int n; @@ -104,6 +104,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcmad_board_struct *board = comedi_board(dev); + struct pcmad_priv_struct *devpriv; int ret; struct comedi_subdevice *s; unsigned long iobase; @@ -121,9 +122,10 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct pcmad_priv_struct)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_name = board->name; diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 28af8f6..0882daf 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -64,13 +64,6 @@ Configuration Options: #define MSB_PORT(chan) (LSB_PORT(chan)+1) #define BITS 12 -/* - * Bords - */ -struct pcmda12_board { - const char *name; -}; - /* note these have no effect and are merely here for reference.. these are configured by jumpering the board! */ static const struct comedi_lrange pcmda12_ranges = { @@ -86,8 +79,6 @@ struct pcmda12_private { int simultaneous_xfer_mode; }; -#define devpriv ((struct pcmda12_private *)(dev->private)) - static void zero_chans(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ @@ -104,6 +95,7 @@ static void zero_chans(struct comedi_device *dev) static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcmda12_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -146,6 +138,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcmda12_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -162,7 +155,7 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmda12_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct pcmda12_board *board = comedi_board(dev); + struct pcmda12_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int ret; @@ -178,16 +171,12 @@ static int pcmda12_attach(struct comedi_device *dev, } dev->iobase = iobase; - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) { - printk(KERN_ERR "cannot allocate private data structure\n"); + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; - } + dev->private = devpriv; devpriv->simultaneous_xfer_mode = it->options[1]; @@ -218,20 +207,11 @@ static void pcmda12_detach(struct comedi_device *dev) release_region(dev->iobase, IOSIZE); } -static const struct pcmda12_board pcmda12_boards[] = { - { - .name = "pcmda12", - }, -}; - static struct comedi_driver pcmda12_driver = { .driver_name = "pcmda12", .module = THIS_MODULE, .attach = pcmda12_attach, .detach = pcmda12_detach, - .board_name = &pcmda12_boards[0].name, - .offset = sizeof(struct pcmda12_board), - .num_names = ARRAY_SIZE(pcmda12_boards), }; module_comedi_driver(pcmda12_driver); diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index a10bf0a..7522bfb 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -145,35 +145,6 @@ Configuration Options: #define PAGE_ENAB 2 #define PAGE_INT_ID 3 -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ -struct pcmmio_board { - const char *name; - const int dio_num_asics; - const int dio_num_ports; - const int total_iosize; - const int ai_bits; - const int ao_bits; - const int n_ai_chans; - const int n_ao_chans; - const struct comedi_lrange *ai_range_table, *ao_range_table; - int (*ai_rinsn) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*ao_rinsn) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*ao_winsn) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -}; - static const struct comedi_lrange ranges_ai = { 4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0., 10.)} }; @@ -258,11 +229,6 @@ struct pcmmio_private { struct pcmmio_subdev_private *sprivs; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct pcmmio_private *)dev->private) #define subpriv ((struct pcmmio_subdev_private *)s->private) /* DIO devices are slightly special. Although it is possible to @@ -416,9 +382,9 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, static void switch_page(struct comedi_device *dev, int asic, int page) { - const struct pcmmio_board *board = comedi_board(dev); + struct pcmmio_private *devpriv = dev->private; - if (asic < 0 || asic >= board->dio_num_asics) + if (asic < 0 || asic >= 1) return; /* paranoia */ if (page < 0 || page >= NUM_PAGES) return; /* more paranoia */ @@ -434,10 +400,10 @@ static void switch_page(struct comedi_device *dev, int asic, int page) static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ - const struct pcmmio_board *board = comedi_board(dev); + struct pcmmio_private *devpriv = dev->private; int asic; - for (asic = 0; asic < board->dio_num_asics; ++asic) { + for (asic = 0; asic < 1; ++asic) { int port, page; unsigned long baseaddr = devpriv->asics[asic].iobase; @@ -472,9 +438,9 @@ static void init_asics(struct comedi_device *dev) #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { - const struct pcmmio_board *board = comedi_board(dev); + struct pcmmio_private *devpriv = dev->private; - if (asic < 0 || asic >= board->dio_num_asics) + if (asic < 0 || asic >= 1) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -488,9 +454,9 @@ static void lock_port(struct comedi_device *dev, int asic, int port) static void unlock_port(struct comedi_device *dev, int asic, int port) { - const struct pcmmio_board *board = comedi_board(dev); + struct pcmmio_private *devpriv = dev->private; - if (asic < 0 || asic >= board->dio_num_asics) + if (asic < 0 || asic >= 1) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -504,6 +470,7 @@ static void unlock_port(struct comedi_device *dev, int asic, int port) static void pcmmio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmmio_private *devpriv = dev->private; int nports, firstport, asic, port; asic = subpriv->dio.intr.asic; @@ -526,6 +493,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) { int asic, got1 = 0; struct comedi_device *dev = (struct comedi_device *)d; + struct pcmmio_private *devpriv = dev->private; int i; for (asic = 0; asic < MAX_ASICS; ++asic) { @@ -685,6 +653,8 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmmio_private *devpriv = dev->private; + if (!subpriv->dio.intr.continuous && subpriv->dio.intr.stop_count == 0) { /* An empty acquisition! */ s->async->events |= COMEDI_CB_EOA; @@ -1012,7 +982,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct pcmmio_board *board = comedi_board(dev); + struct pcmmio_private *devpriv; struct comedi_subdevice *s; int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, thisasic_chanct = 0; @@ -1020,32 +990,25 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int irq[MAX_ASICS]; int ret; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; irq[0] = it->options[1]; printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor, - dev->driver->driver_name, iobase); + dev->board_name, iobase); dev->iobase = iobase; - if (!iobase || !request_region(iobase, - board->total_iosize, - dev->driver->driver_name)) { + if (!iobase || !request_region(iobase, 32, dev->board_name)) { printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); return -EIO; } - dev->board_name = board->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) { - printk(KERN_ERR "comedi%d: cannot allocate private data structure\n", - dev->minor); + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; - } + dev->private = devpriv; for (asic = 0; asic < MAX_ASICS; ++asic) { devpriv->asics[asic].num = asic; @@ -1059,7 +1022,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) spin_lock_init(&devpriv->asics[asic].spinlock); } - chans_left = CHANS_PER_ASIC * board->dio_num_asics; + chans_left = CHANS_PER_ASIC * 1; n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); n_subdevs = n_dio_subdevs + 2; devpriv->sprivs = @@ -1078,13 +1041,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* First, AI */ s = &dev->subdevices[0]; s->private = &devpriv->sprivs[0]; - s->maxdata = (1 << board->ai_bits) - 1; - s->range_table = board->ai_range_table; + s->maxdata = 0xffff; + s->range_table = &ranges_ai; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->type = COMEDI_SUBD_AI; - s->n_chan = board->n_ai_chans; + s->n_chan = 16; s->len_chanlist = s->n_chan; - s->insn_read = board->ai_rinsn; + s->insn_read = ai_rinsn; subpriv->iobase = dev->iobase + 0; /* initialize the resource enable register by clearing it */ outb(0, subpriv->iobase + 3); @@ -1093,14 +1056,14 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Next, AO */ s = &dev->subdevices[1]; s->private = &devpriv->sprivs[1]; - s->maxdata = (1 << board->ao_bits) - 1; - s->range_table = board->ao_range_table; + s->maxdata = 0xffff; + s->range_table = &ranges_ao; s->subdev_flags = SDF_READABLE; s->type = COMEDI_SUBD_AO; - s->n_chan = board->n_ao_chans; + s->n_chan = 8; s->len_chanlist = s->n_chan; - s->insn_read = board->ao_rinsn; - s->insn_write = board->ao_winsn; + s->insn_read = ao_rinsn; + s->insn_write = ao_winsn; subpriv->iobase = dev->iobase + 8; /* initialize the resource enable register by clearing it */ outb(0, subpriv->iobase + 3); @@ -1180,7 +1143,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { if (irq[asic] && request_irq(irq[asic], interrupt_pcmmio, - IRQF_SHARED, board->name, dev)) { + IRQF_SHARED, dev->board_name, dev)) { int i; /* unroll the allocated irqs.. */ for (i = asic - 1; i >= 0; --i) { @@ -1204,11 +1167,11 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmmio_detach(struct comedi_device *dev) { - const struct pcmmio_board *board = comedi_board(dev); + struct pcmmio_private *devpriv = dev->private; int i; if (dev->iobase) - release_region(dev->iobase, board->total_iosize); + release_region(dev->iobase, 32); for (i = 0; i < MAX_ASICS; ++i) { if (devpriv && devpriv->asics[i].irq) free_irq(devpriv->asics[i].irq, dev); @@ -1217,32 +1180,11 @@ static void pcmmio_detach(struct comedi_device *dev) kfree(devpriv->sprivs); } -static const struct pcmmio_board pcmmio_boards[] = { - { - .name = "pcmmio", - .dio_num_asics = 1, - .dio_num_ports = 6, - .total_iosize = 32, - .ai_bits = 16, - .ao_bits = 16, - .n_ai_chans = 16, - .n_ao_chans = 8, - .ai_range_table = &ranges_ai, - .ao_range_table = &ranges_ao, - .ai_rinsn = ai_rinsn, - .ao_rinsn = ao_rinsn, - .ao_winsn = ao_winsn - }, -}; - static struct comedi_driver pcmmio_driver = { .driver_name = "pcmmio", .module = THIS_MODULE, .attach = pcmmio_attach, .detach = pcmmio_detach, - .board_name = &pcmmio_boards[0].name, - .offset = sizeof(struct pcmmio_board), - .num_names = ARRAY_SIZE(pcmmio_boards), }; module_comedi_driver(pcmmio_driver); diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 0e32119..31ea20c 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -194,11 +194,6 @@ struct pcmuio_private { struct pcmuio_subdev_private *sprivs; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct pcmuio_private *)dev->private) #define subpriv ((struct pcmuio_subdev_private *)s->private) /* DIO devices are slightly special. Although it is possible to @@ -348,6 +343,7 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, static void switch_page(struct comedi_device *dev, int asic, int page) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ @@ -404,6 +400,7 @@ static void init_asics(struct comedi_device *dev) static void lock_port(struct comedi_device *dev, int asic, int port) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ @@ -419,6 +416,7 @@ static void lock_port(struct comedi_device *dev, int asic, int port) static void unlock_port(struct comedi_device *dev, int asic, int port) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ @@ -435,6 +433,7 @@ static void pcmuio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { int nports, firstport, asic, port; + struct pcmuio_private *devpriv = dev->private; asic = subpriv->intr.asic; if (asic < 0) @@ -456,6 +455,7 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) { int asic, got1 = 0; struct comedi_device *dev = (struct comedi_device *)d; + struct pcmuio_private *devpriv = dev->private; int i; for (asic = 0; asic < MAX_ASICS; ++asic) { @@ -607,6 +607,8 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmuio_private *devpriv = dev->private; + if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) { /* An empty acquisition! */ s->async->events |= COMEDI_CB_EOA; @@ -748,6 +750,7 @@ pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv; struct comedi_subdevice *s; int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; unsigned long iobase; @@ -772,15 +775,10 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) { - dev_warn(dev->class_dev, - "cannot allocate private data structure\n"); + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; - } + dev->private = devpriv; for (asic = 0; asic < MAX_ASICS; ++asic) { devpriv->asics[asic].num = asic; @@ -905,6 +903,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmuio_detach(struct comedi_device *dev) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; int i; if (dev->iobase) diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index 78dfe16..d7842c9 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -57,13 +57,18 @@ struct boarddef_struct { const struct comedi_lrange *range; }; +struct poc_private { + unsigned int ao_readback[32]; +}; + static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct poc_private *devpriv = dev->private; int chan; chan = CR_CHAN(insn->chanspec); - data[0] = ((unsigned int *)dev->private)[chan]; + data[0] = devpriv->ao_readback[chan]; return 1; } @@ -75,12 +80,13 @@ static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int dac02_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct poc_private *devpriv = dev->private; int temp; int chan; int output; chan = CR_CHAN(insn->chanspec); - ((unsigned int *)dev->private)[chan] = data[0]; + devpriv->ao_readback[chan] = data[0]; output = data[0]; #ifdef wrong /* convert to complementary binary if range is bipolar */ @@ -131,6 +137,7 @@ static int pcl734_insn_bits(struct comedi_device *dev, static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct boarddef_struct *board = comedi_board(dev); + struct poc_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; unsigned int iosize; @@ -160,8 +167,10 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - if (alloc_private(dev, sizeof(unsigned int) * board->n_chan) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; /* analog output subdevice */ s = &dev->subdevices[0]; diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 3e276f7..ef0cdaa 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -47,6 +47,8 @@ Status: works Devices: [Quatech] DAQP-208 (daqp), DAQP-308 */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include <linux/semaphore.h> @@ -195,8 +197,8 @@ static struct comedi_driver driver_daqp = { static void daqp_dump(struct comedi_device *dev) { - printk(KERN_INFO "DAQP: status %02x; aux status %02x\n", - inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX)); + dev_info(dev->class_dev, "status %02x; aux status %02x\n", + inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX)); } static void hex_dump(char *str, void *ptr, int len) @@ -255,33 +257,29 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) int status; if (local == NULL) { - printk(KERN_WARNING - "daqp_interrupt(): irq %d for unknown device.\n", irq); + pr_warn("irq %d for unknown device.\n", irq); return IRQ_NONE; } dev = local->dev; if (dev == NULL) { - printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n"); + pr_warn("NULL comedi_device.\n"); return IRQ_NONE; } if (!dev->attached) { - printk(KERN_WARNING - "daqp_interrupt(): struct comedi_device not yet attached.\n"); + pr_warn("struct comedi_device not yet attached.\n"); return IRQ_NONE; } s = local->s; if (s == NULL) { - printk(KERN_WARNING - "daqp_interrupt(): NULL comedi_subdevice.\n"); + pr_warn("NULL comedi_subdevice.\n"); return IRQ_NONE; } if ((struct local_info_t *)s->private != local) { - printk(KERN_WARNING - "daqp_interrupt(): invalid comedi_subdevice.\n"); + pr_warn("invalid comedi_subdevice.\n"); return IRQ_NONE; } @@ -302,7 +300,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) if (status & DAQP_STATUS_DATA_LOST) { s->async->events |= COMEDI_CB_EOA | COMEDI_CB_OVERFLOW; - printk("daqp: data lost\n"); + dev_warn(dev->class_dev, "data lost\n"); daqp_ai_cancel(dev, s); break; } @@ -331,8 +329,8 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) } if (loop_limit <= 0) { - printk(KERN_WARNING - "loop_limit reached in daqp_interrupt()\n"); + dev_warn(dev->class_dev, + "loop_limit reached in daqp_interrupt()\n"); daqp_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } @@ -397,9 +395,11 @@ static int daqp_ai_insn_read(struct comedi_device *dev, */ while (--counter - && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; + && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) + ; if (!counter) { - printk("daqp: couldn't clear interrupts in status register\n"); + dev_err(dev->class_dev, + "couldn't clear interrupts in status register\n"); return -1; } @@ -482,19 +482,15 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED 10000 /* 100 kHz - in nanoseconds */ - if (cmd->scan_begin_src == TRIG_TIMER - && cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); /* 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 @@ -503,30 +499,18 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER && cmd->scan_begin_arg != cmd->convert_arg * cmd->scan_end_arg) { - err++; + err |= -EINVAL; } - if (cmd->convert_src == TRIG_TIMER && cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -734,10 +718,11 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) */ counter = 100; while (--counter - && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; + && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) + ; if (!counter) { - printk(KERN_ERR - "daqp: couldn't clear interrupts in status register\n"); + dev_err(dev->class_dev, + "couldn't clear interrupts in status register\n"); return -1; } @@ -824,8 +809,8 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) { - printk("comedi%d: No such daqp device %d\n", - dev->minor, it->options[0]); + dev_err(dev->class_dev, "No such daqp device %d\n", + it->options[0]); return -EIO; } @@ -852,8 +837,8 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - printk(KERN_INFO "comedi%d: attaching daqp%d (io 0x%04lx)\n", - dev->minor, it->options[0], dev->iobase); + dev_info(dev->class_dev, "attaching daqp%d (io 0x%04lx)\n", + it->options[0], dev->iobase); s = &dev->subdevices[0]; dev->read_subdev = s; @@ -958,7 +943,7 @@ static int daqp_cs_attach(struct pcmcia_device *link) if (dev_table[i] == NULL) break; if (i == MAX_DEV) { - printk(KERN_NOTICE "daqp_cs: no devices available\n"); + dev_notice(&link->dev, "no devices available\n"); return -ENODEV; } diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 41d24b0..8d7c948 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -107,14 +107,12 @@ Configuration options: #include "../comedidev.h" #include "comedi_fc.h" - -#define DRV_NAME "rtd520" +#include "rtd520.h" +#include "plx9080.h" /*====================================================================== Driver specific stuff (tunable) ======================================================================*/ -/* Enable this to test the new DMA support. You may get hard lock ups */ -/*#define USE_DMA*/ /* We really only need 2 buffers. More than that means being much smarter about knowing which ones are full. */ @@ -147,20 +145,6 @@ Configuration options: Board specific stuff ======================================================================*/ -/* registers */ -#define PCI_VENDOR_ID_RTD 0x1435 -/* - The board has three memory windows: las0, las1, and lcfg (the PCI chip) - Las1 has the data and can be burst DMAed 32bits at a time. -*/ -#define LCFG_PCIINDEX 0 -/* PCI region 1 is a 256 byte IO space mapping. Use??? */ -#define LAS0_PCIINDEX 2 /* PCI memory resources */ -#define LAS1_PCIINDEX 3 -#define LCFG_PCISIZE 0x100 -#define LAS0_PCISIZE 0x200 -#define LAS1_PCISIZE 0x10 - #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */ #define RTD_CLOCK_BASE 125 /* clock period in ns */ @@ -173,9 +157,6 @@ Configuration options: /* min speed when only 1 channel (no burst counter) */ #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */ -#include "rtd520.h" -#include "plx9080.h" - /* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */ #define DMA_MODE_BITS (\ PLX_LOCAL_BUS_16_WIDE_BITS \ @@ -270,30 +251,24 @@ static const struct comedi_lrange rtd_ao_range = { struct rtdBoard { const char *name; int device_id; - int aiChans; - int aiBits; - int aiMaxGain; int range10Start; /* start of +-10V range */ int rangeUniStart; /* start of +10V range */ + const struct comedi_lrange *ai_range; }; static const struct rtdBoard rtd520Boards[] = { { .name = "DM7520", .device_id = 0x7520, - .aiChans = 16, - .aiBits = 12, - .aiMaxGain = 32, .range10Start = 6, .rangeUniStart = 12, + .ai_range = &rtd_ai_7520_range, }, { .name = "PCI4520", .device_id = 0x4520, - .aiChans = 16, - .aiBits = 12, - .aiMaxGain = 128, .range10Start = 8, .rangeUniStart = 16, + .ai_range = &rtd_ai_4520_range, }, }; @@ -307,7 +282,6 @@ struct rtdPrivate { void __iomem *las1; void __iomem *lcfg; - unsigned long intCount; /* interrupt count */ long aiCount; /* total transfer size (samples) */ int transCount; /* # to transfer data. 0->1/2FIFO */ int flags; /* flag event modes */ @@ -328,21 +302,6 @@ struct rtdPrivate { u16 intClearMask; /* interrupt clear mask */ u8 utcCtrl[4]; /* crtl mode for 3 utc + read back */ u8 dioStatus; /* could be read back (dio0Ctrl) */ -#ifdef USE_DMA - /* - * Always DMA 1/2 FIFO. Buffer (dmaBuff?) is (at least) twice that - * size. After transferring, interrupt processes 1/2 FIFO and - * passes to comedi - */ - s16 dma0Offset; /* current processing offset (0, 1/2) */ - uint16_t *dma0Buff[DMA_CHAIN_COUNT]; /* DMA buffers (for ADC) */ - dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT]; /* physical addresses */ - struct plx_dma_desc *dma0Chain; /* DMA descriptor ring for dmaBuff */ - dma_addr_t dma0ChainPhysAddr; /* physical addresses */ - /* shadow registers */ - u8 dma0Control; - u8 dma1Control; -#endif /* USE_DMA */ unsigned fifoLen; }; @@ -365,9 +324,9 @@ struct rtdPrivate { 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, /* desired period (in ns) */ +static int rtd_ns_to_timer_base(unsigned int *nanosec, int round_mode, int base) -{ /* clock period (in ns) */ +{ int divider; switch (round_mode) { @@ -420,18 +379,19 @@ static unsigned short rtdConvertChanGain(struct comedi_device *dev, r |= chan & 0xf; /* Note: we also setup the channel list bipolar flag array */ - if (range < thisboard->range10Start) { /* first batch are +-5 */ - r |= 0x000; /* +-5 range */ - r |= (range & 0x7) << 4; /* gain */ + if (range < thisboard->range10Start) { + /* +-5 range */ + r |= 0x000; + r |= (range & 0x7) << 4; CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); - } else if (range < thisboard->rangeUniStart) { /* second batch are +-10 */ - r |= 0x100; /* +-10 range */ - /* gain */ + } else if (range < thisboard->rangeUniStart) { + /* +-10 range */ + r |= 0x100; r |= ((range - thisboard->range10Start) & 0x7) << 4; CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); - } else { /* last batch is +10 */ - r |= 0x200; /* +10 range */ - /* gain */ + } else { + /* +10 range */ + r |= 0x200; r |= ((range - thisboard->rangeUniStart) & 0x7) << 4; CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex); } @@ -507,15 +467,14 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev) } } if (i == limit) { - printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", - DRV_NAME); + dev_info(dev->class_dev, "failed to probe fifo size.\n"); return -EIO; } writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); if (fifo_size != 0x400 && fifo_size != 0x2000) { - printk - (KERN_INFO "\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n", - DRV_NAME, fifo_size); + dev_info(dev->class_dev, + "unexpected fifo size of %i, expected 1024 or 8192.\n", + fifo_size); return -EIO; } return fifo_size; @@ -558,12 +517,8 @@ static int rtd_ai_rinsn(struct comedi_device *dev, break; WAIT_QUIETLY; } - if (ii >= RTD_ADC_TIMEOUT) { - DPRINTK - ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n", - stat ^ 0x6666); + if (ii >= RTD_ADC_TIMEOUT) return -ETIMEDOUT; - } /* read data */ d = readw(devpriv->las1 + LAS1_ADC_FIFO); @@ -600,15 +555,8 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = readw(devpriv->las1 + LAS1_ADC_FIFO); continue; } -#if 0 - if (!(readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY)) { - DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1, - count); - break; - } -#endif - d = readw(devpriv->las1 + LAS1_ADC_FIFO); + d = readw(devpriv->las1 + LAS1_ADC_FIFO); d = d >> 3; /* low 3 bits are marker lines */ if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { /* convert to comedi unsigned data */ @@ -656,125 +604,6 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -#ifdef USE_DMA -/* - Terminate a DMA transfer and wait for everything to quiet down -*/ -void abort_dma(struct comedi_device *dev, unsigned int channel) -{ /* DMA channel 0, 1 */ - struct rtdPrivate *devpriv = dev->private; - unsigned long dma_cs_addr; /* the control/status register */ - uint8_t status; - unsigned int ii; - /* unsigned long flags; */ - - dma_cs_addr = (unsigned long)devpriv->lcfg - + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1); - - /* spinlock for plx dma control/status reg */ - /* spin_lock_irqsave( &dev->spinlock, flags ); */ - - /* abort dma transfer if necessary */ - status = readb(dma_cs_addr); - if ((status & PLX_DMA_EN_BIT) == 0) { /* not enabled (Error?) */ - DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n", - channel, status); - goto abortDmaExit; - } - - /* wait to make sure done bit is zero (needed?) */ - for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) { - WAIT_QUIETLY; - status = readb(dma_cs_addr); - } - if (status & PLX_DMA_DONE_BIT) { - printk("rtd520: Timeout waiting for dma %i done clear\n", - channel); - goto abortDmaExit; - } - - /* disable channel (required) */ - writeb(0, dma_cs_addr); - udelay(1); /* needed?? */ - /* set abort bit for channel */ - writeb(PLX_DMA_ABORT_BIT, dma_cs_addr); - - /* wait for dma done bit to be set */ - status = readb(dma_cs_addr); - for (ii = 0; - (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) { - status = readb(dma_cs_addr); - WAIT_QUIETLY; - } - if ((status & PLX_DMA_DONE_BIT) == 0) { - printk("rtd520: Timeout waiting for dma %i done set\n", - channel); - } - -abortDmaExit: - /* spin_unlock_irqrestore( &dev->spinlock, flags ); */ -} - -/* - Process what is in the DMA transfer buffer and pass to comedi - Note: this is not re-entrant -*/ -static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct rtdPrivate *devpriv = dev->private; - int ii, n; - s16 *dp; - - if (devpriv->aiCount == 0) /* transfer already complete */ - return 0; - - dp = devpriv->dma0Buff[devpriv->dma0Offset]; - for (ii = 0; ii < devpriv->fifoLen / 2;) { /* convert samples */ - short sample; - - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { - sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */ - else - sample = *dp >> 3; /* low 3 bits are marker lines */ - - *dp++ = sample; /* put processed value back */ - - if (++s->async->cur_chan >= s->async->cmd.chanlist_len) - s->async->cur_chan = 0; - - ++ii; /* number ready to transfer */ - if (devpriv->aiCount > 0) { /* < 0, means read forever */ - if (--devpriv->aiCount == 0) { /* done */ - /*DPRINTK ("rtd520: Final %d samples\n", ii); */ - break; - } - } - } - - /* now pass the whole array to the comedi buffer */ - dp = devpriv->dma0Buff[devpriv->dma0Offset]; - n = comedi_buf_write_alloc(s->async, ii * sizeof(s16)); - if (n < (ii * sizeof(s16))) { /* any residual is an error */ - DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n", - ii - (n / sizeof(s16))); - s->async->events |= COMEDI_CB_ERROR; - return -1; - } - comedi_buf_memcpy_to(s->async, 0, dp, n); - comedi_buf_write_free(s->async, n); - - /* - * always at least 1 scan -- 1/2 FIFO is larger than our max scan list - */ - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - - if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */ - devpriv->dma0Offset = 0; - } - return 0; -} -#endif /* USE_DMA */ - /* Handle all rtd520 interrupts. Runs atomically and is never re-entered. @@ -794,47 +623,10 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ if (!dev->attached) return IRQ_NONE; - devpriv->intCount++; /* DEBUG statistics */ - fifoStatus = readl(devpriv->las0 + LAS0_ADC); /* check for FIFO full, this automatically halts the ADC! */ - if (!(fifoStatus & FS_ADC_NOT_FULL)) { /* 0 -> full */ - DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ + if (!(fifoStatus & FS_ADC_NOT_FULL)) /* 0 -> full */ goto abortTransfer; - } -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { /* Check DMA */ - u32 istatus = readl(devpriv->lcfg + LCFG_ITCSR); - - if (istatus & ICS_DMA0_A) { - if (ai_process_dma(dev, s) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n", - devpriv->aiCount); - devpriv->dma0Control &= ~PLX_DMA_START_BIT; - devpriv->dma0Control |= PLX_CLEAR_DMA_INTR_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - goto abortTransfer; - } - - /*DPRINTK ("rtd520: DMA transfer: %ld to go, istatus %x\n", - devpriv->aiCount, istatus); */ - devpriv->dma0Control &= ~PLX_DMA_START_BIT; - devpriv->dma0Control |= PLX_CLEAR_DMA_INTR_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK("rtd520: Samples Done (DMA).\n"); - goto transferDone; - } - comedi_event(dev, s); - } else { - /*DPRINTK ("rtd520: No DMA ready: istatus %x\n", istatus); */ - } - } - /* Fall through and check for other interrupt sources */ -#endif /* USE_DMA */ status = readw(devpriv->las0 + LAS0_IT); /* if interrupt was not caused by our board, or handled above */ @@ -842,57 +634,38 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ 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 (!(fifoStatus & FS_ADC_HEMPTY)) { /* 0 -> 1/2 full */ - /*DPRINTK("rtd520: Sample int, reading 1/2FIFO. fifo_status 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); */ - if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n", - devpriv->aiCount); + /* + * 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 (!(fifoStatus & FS_ADC_HEMPTY)) { + /* FIFO half full */ + if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) goto abortTransfer; - } - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK("rtd520: Samples Done (1/2). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ + + if (0 == devpriv->aiCount) goto transferDone; - } + comedi_event(dev, s); - } else if (devpriv->transCount > 0) { /* read often */ - /*DPRINTK("rtd520: Sample int, reading %d fifo_status 0x%x\n", - devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777); */ - if (fifoStatus & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */ - if (ai_read_n(dev, s, devpriv->transCount) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (N) with %ld to go!\n", - devpriv->aiCount); + } else if (devpriv->transCount > 0) { + if (fifoStatus & FS_ADC_NOT_EMPTY) { + /* FIFO not empty */ + if (ai_read_n(dev, s, devpriv->transCount) < 0) goto abortTransfer; - } - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK - ("rtd520: Samples Done (N). fifo_status was 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); + + if (0 == devpriv->aiCount) goto transferDone; - } + comedi_event(dev, s); } - } else { /* wait for 1/2 FIFO (old) */ - DPRINTK - ("rtd520: Sample int. Wait for 1/2. fifo_status 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); } - } else { - DPRINTK("rtd520: unknown interrupt source!\n"); } overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff; - if (overrun) { - DPRINTK - ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n", - devpriv->aiCount, overrun); + if (overrun) goto abortTransfer; - } /* clear the interrupt */ devpriv->intClearMask = status; @@ -913,23 +686,9 @@ transferDone: writel(0, devpriv->las0 + LAS0_ADC_CONVERSION); devpriv->intMask = 0; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { - writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; - /* if Using DMA, then we should have read everything by now */ - if (devpriv->aiCount > 0) { - DPRINTK("rtd520: Lost DMA data! %ld remain\n", - devpriv->aiCount); - } - } -#endif /* USE_DMA */ if (devpriv->aiCount > 0) { /* there shouldn't be anything left */ fifoStatus = readl(devpriv->las0 + LAS0_ADC); - DPRINTK("rtd520: Finishing up. %ld remain, fifoStat=%x\n", devpriv->aiCount, (fifoStatus ^ 0x6666) & 0x7777); /* should read all 0s */ ai_read_dregs(dev, s); /* read anything left in FIFO */ } @@ -944,25 +703,10 @@ transferDone: fifoStatus = readl(devpriv->las0 + LAS0_ADC); overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff; - DPRINTK - ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n", - devpriv->intCount, status, overrun); return IRQ_HANDLED; } -#if 0 -/* - return the number of samples available -*/ -static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) -{ - /* TODO: This needs to mask interrupts, read_dregs, and then re-enable */ - /* Not sure what to do if DMA is active */ - return s->async->buf_write_count - s->async->buf_read_count; -} -#endif - /* cmdtest tests a particular command to see if it is valid. Using the cmdtest ioctl, a user can create a valid cmd @@ -1001,103 +745,85 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { /* Note: these are time periods, not actual rates */ if (1 == cmd->chanlist_len) { /* no scanning */ - if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) { - cmd->scan_begin_arg = RTD_MAX_SPEED_1; + if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + RTD_MAX_SPEED_1)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) { - cmd->scan_begin_arg = RTD_MIN_SPEED_1; + if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + RTD_MIN_SPEED_1)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } else { - if (cmd->scan_begin_arg < RTD_MAX_SPEED) { - cmd->scan_begin_arg = RTD_MAX_SPEED; + if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + RTD_MAX_SPEED)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->scan_begin_arg > RTD_MIN_SPEED) { - cmd->scan_begin_arg = RTD_MIN_SPEED; + if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + RTD_MIN_SPEED)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } + if (cmd->convert_src == TRIG_TIMER) { if (1 == cmd->chanlist_len) { /* no scanning */ - if (cmd->convert_arg < RTD_MAX_SPEED_1) { - cmd->convert_arg = RTD_MAX_SPEED_1; + if (cfc_check_trigger_arg_min(&cmd->convert_arg, + RTD_MAX_SPEED_1)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->convert_arg > RTD_MIN_SPEED_1) { - cmd->convert_arg = RTD_MIN_SPEED_1; + if (cfc_check_trigger_arg_max(&cmd->convert_arg, + RTD_MIN_SPEED_1)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } else { - if (cmd->convert_arg < RTD_MAX_SPEED) { - cmd->convert_arg = RTD_MAX_SPEED; + if (cfc_check_trigger_arg_min(&cmd->convert_arg, + RTD_MAX_SPEED)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->convert_arg > RTD_MIN_SPEED) { - cmd->convert_arg = RTD_MIN_SPEED; + if (cfc_check_trigger_arg_max(&cmd->convert_arg, + RTD_MIN_SPEED)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); } -#if 0 - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } -#endif if (cmd->stop_src == TRIG_COUNT) { /* TODO check for rounding error due to counter wrap */ - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -1159,28 +885,8 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel(0, devpriv->las0 + LAS0_ADC_CONVERSION); devpriv->intMask = 0; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { /* cancel anything running */ - writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; - if (readl(devpriv->lcfg + LCFG_ITCSR) & ICS_DMA0_A) { - devpriv->dma0Control = PLX_CLEAR_DMA_INTR_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - } - } - writel(0, devpriv->las0 + LAS0_DMA0_RESET); -#endif /* USE_DMA */ writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); writel(0, devpriv->las0 + LAS0_OVERRUN); - devpriv->intCount = 0; - - if (!dev->irq) { /* we need interrupts for this */ - DPRINTK("rtd520: ERROR! No interrupt available!\n"); - return -ENXIO; - } /* start configuration */ /* load channel list and reset CGT */ @@ -1188,7 +894,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* setup the common case and override if needed */ if (cmd->chanlist_len > 1) { - /*DPRINTK ("rtd520: Multi channel setup\n"); */ /* pacer start source: SOFTWARE */ writel(0, devpriv->las0 + LAS0_PACER_START); /* burst trigger source: PACER */ @@ -1196,7 +901,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* ADC conversion trigger source: BURST */ writel(2, devpriv->las0 + LAS0_ADC_CONVERSION); } else { /* single channel */ - /*DPRINTK ("rtd520: single channel setup\n"); */ /* pacer start source: SOFTWARE */ writel(0, devpriv->las0 + LAS0_PACER_START); /* ADC conversion trigger source: PACER */ @@ -1208,8 +912,11 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* scan_begin_arg is in nanoseconds */ /* find out how many samples to wait before transferring */ if (cmd->flags & TRIG_WAKE_EOS) { - /* this may generate un-sustainable interrupt rates */ - /* the application is responsible for doing the right thing */ + /* + * this may generate un-sustainable interrupt rates + * the application is responsible for doing the + * right thing + */ devpriv->transCount = cmd->chanlist_len; devpriv->flags |= SEND_EOS; } else { @@ -1239,11 +946,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel((devpriv->transCount - 1) & 0xffff, devpriv->las0 + LAS0_ACNT); } - - DPRINTK - ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", - cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen, - cmd->scan_begin_arg, devpriv->flags); } else { /* unknown timing, just use 1/2 FIFO */ devpriv->transCount = 0; devpriv->flags &= ~SEND_EOS; @@ -1268,10 +970,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) case TRIG_NONE: /* stop when cancel is called */ devpriv->aiCount = -1; /* read forever */ break; - - default: - DPRINTK("rtd520: Warning! ignoring stop_src mode %d\n", - cmd->stop_src); } /* Scan timing */ @@ -1280,7 +978,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) timer = rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST); /* set PACER clock */ - /*DPRINTK ("rtd520: loading %d into pacer\n", timer); */ writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK); break; @@ -1289,20 +986,16 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* pacer start source: EXTERNAL */ writel(1, devpriv->las0 + LAS0_PACER_START); break; - - default: - DPRINTK("rtd520: Warning! ignoring scan_begin_src mode %d\n", - cmd->scan_begin_src); } /* Sample timing within a scan */ switch (cmd->convert_src) { case TRIG_TIMER: /* periodic */ - if (cmd->chanlist_len > 1) { /* only needed for multi-channel */ + if (cmd->chanlist_len > 1) { + /* only needed for multi-channel */ timer = rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST); /* setup BURST clock */ - /*DPRINTK ("rtd520: loading %d into burst\n", timer); */ writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK); } @@ -1312,10 +1005,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* burst trigger source: EXTERNAL */ writel(2, devpriv->las0 + LAS0_BURST_START); break; - - default: - DPRINTK("rtd520: Warning! ignoring convert_src mode %d\n", - cmd->convert_src); } /* end configuration */ @@ -1329,34 +1018,9 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->transCount > 0) { /* transfer every N samples */ devpriv->intMask = IRQM_ADC_ABOUT_CNT; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount); } else { /* 1/2 FIFO transfers */ -#ifdef USE_DMA - devpriv->flags |= DMA0_ACTIVE; - - /* point to first transfer in ring */ - devpriv->dma0Offset = 0; - writel(DMA_MODE_BITS, devpriv->lcfg + LCFG_DMAMODE0); - /* point to first block */ - writel(devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next, - devpriv->lcfg + LCFG_DMADPR0); - writel(DMAS_ADFIFO_HALF_FULL, devpriv->las0 + LAS0_DMA0_SRC); - writel(readl(devpriv->lcfg + LCFG_ITCSR) | ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - /* Must be 2 steps. See PLX app note about "Starting a DMA transfer" */ - devpriv->dma0Control = PLX_DMA_EN_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - devpriv->dma0Control |= PLX_DMA_START_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - DPRINTK("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n", - readl(devpriv->lcfg + LCFG_ITCSR), devpriv->intMask); -#else /* USE_DMA */ devpriv->intMask = IRQM_ADC_ABOUT_CNT; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - DPRINTK("rtd520: Transferring every 1/2 FIFO\n"); -#endif /* USE_DMA */ } /* BUG: start_src is ASSUMED to be TRIG_NOW */ @@ -1381,19 +1045,8 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->intMask = 0; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); devpriv->aiCount = 0; /* stop and don't transfer any more */ -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { - writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; - } -#endif /* USE_DMA */ status = readw(devpriv->las0 + LAS0_IT); overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff; - DPRINTK - ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n", - devpriv->intCount, status, overrun); return 0; } @@ -1430,14 +1083,11 @@ static int rtd_ao_winsn(struct comedi_device *dev, val = data[i] << 3; } - DPRINTK - ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n", - chan, range, data[i], val); - /* a typical programming sequence */ writew(val, devpriv->las1 + ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO)); - writew(0, devpriv->las0 + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2)); + writew(0, devpriv->las0 + + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2)); devpriv->aoValue[chan] = data[i]; /* save for read back */ @@ -1449,12 +1099,8 @@ static int rtd_ao_winsn(struct comedi_device *dev, break; WAIT_QUIETLY; } - if (ii >= RTD_DAC_TIMEOUT) { - DPRINTK - ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n", - stat ^ 0x6666); + if (ii >= RTD_DAC_TIMEOUT) return -ETIMEDOUT; - } } /* return the number of samples read/written */ @@ -1507,8 +1153,6 @@ static int rtd_dio_insn_bits(struct comedi_device *dev, * input lines. */ data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff; - /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]); */ - return insn->n; } @@ -1542,7 +1186,6 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return -EINVAL; } - DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits); /* TODO support digital match interrupts and strobes */ devpriv->dioStatus = 0x01; /* set direction */ writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS); @@ -1557,356 +1200,194 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return 1; } -static struct pci_dev *rtd_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) +static void rtd_reset(struct comedi_device *dev) +{ + struct rtdPrivate *devpriv = dev->private; + + writel(0, devpriv->las0 + LAS0_BOARD_RESET); + udelay(100); /* needed? */ + writel(0, devpriv->lcfg + LCFG_ITCSR); + devpriv->intMask = 0; + writew(devpriv->intMask, devpriv->las0 + LAS0_IT); + devpriv->intClearMask = ~0; + writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR); + readw(devpriv->las0 + LAS0_CLEAR); +} + +/* + * initialize board, per RTD spec + * also, initialize shadow registers + */ +static void rtd_init_board(struct comedi_device *dev) +{ + struct rtdPrivate *devpriv = dev->private; + + rtd_reset(dev); + + writel(0, devpriv->las0 + LAS0_OVERRUN); + writel(0, devpriv->las0 + LAS0_CGT_CLEAR); + writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); + writel(0, devpriv->las0 + LAS0_DAC1_RESET); + writel(0, devpriv->las0 + LAS0_DAC2_RESET); + /* clear digital IO fifo */ + devpriv->dioStatus = 0; + writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS); + devpriv->utcCtrl[0] = (0 << 6) | 0x30; + devpriv->utcCtrl[1] = (1 << 6) | 0x30; + devpriv->utcCtrl[2] = (2 << 6) | 0x30; + devpriv->utcCtrl[3] = (3 << 6) | 0x00; + writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL); + writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL); + writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL); + writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL); + /* 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 const void *rtd_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct rtdBoard *thisboard; - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; int i; - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_RTD) - continue; - if (bus || slot) { - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) { - thisboard = &rtd520Boards[i]; - if (pcidev->device == thisboard->device_id) { - dev->board_ptr = thisboard; - return pcidev; - } - } + for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) { + thisboard = &rtd520Boards[i]; + if (pcidev->device == thisboard->device_id) + return thisboard; } - dev_warn(dev->class_dev, - "no supported board found! (req. bus/slot: %d/%d)\n", - bus, slot); return NULL; } -static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ /* board name and options flags */ +static int rtd_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct rtdBoard *thisboard; struct rtdPrivate *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; - resource_size_t pci_base; int ret; -#ifdef USE_DMA - int index; -#endif - printk(KERN_INFO "comedi%d: rtd520 attaching.\n", dev->minor); - -#if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA) - /* You can set this a load time: modprobe comedi comedi_debug=1 */ - if (0 == comedi_debug) /* force DMA debug printks */ - comedi_debug = 1; -#endif + thisboard = rtd_find_boardinfo(dev, pcidev); + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; - /* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; - devpriv = dev->private; + dev->private = devpriv; - pcidev = rtd_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - - dev->board_name = thisboard->name; - - ret = comedi_pci_enable(pcidev, DRV_NAME); - if (ret < 0) { - printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) return ret; - } dev->iobase = 1; /* the "detach" needs this */ - /* Initialize the base addresses */ - pci_base = pci_resource_start(pcidev, LAS0_PCIINDEX); - devpriv->las0 = ioremap_nocache(pci_base, LAS0_PCISIZE); - pci_base = pci_resource_start(pcidev, LAS1_PCIINDEX); - devpriv->las1 = ioremap_nocache(pci_base, LAS1_PCISIZE); - pci_base = pci_resource_start(pcidev, LCFG_PCIINDEX); - devpriv->lcfg = ioremap_nocache(pci_base, LCFG_PCISIZE); + devpriv->las0 = ioremap_nocache(pci_resource_start(pcidev, 2), + pci_resource_len(pcidev, 2)); + devpriv->las1 = ioremap_nocache(pci_resource_start(pcidev, 3), + pci_resource_len(pcidev, 3)); + devpriv->lcfg = ioremap_nocache(pci_resource_start(pcidev, 0), + pci_resource_len(pcidev, 0)); if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) return -ENOMEM; - { /* The RTD driver does this */ - unsigned char pci_latency; - u16 revision; - /*uint32_t epld_version; */ - - pci_read_config_word(pcidev, PCI_REVISION_ID, - &revision); - DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision); - - pci_read_config_byte(pcidev, - PCI_LATENCY_TIMER, &pci_latency); - if (pci_latency < 32) { - printk(KERN_INFO "%s: PCI latency changed from %d to %d\n", - dev->board_name, pci_latency, 32); - pci_write_config_byte(pcidev, - PCI_LATENCY_TIMER, 32); - } else { - DPRINTK("rtd520: PCI latency = %d\n", pci_latency); - } + rtd_pci_latency_quirk(dev, pcidev); - /* - * Undocumented EPLD version (doesn't match RTD driver results) - */ - /*DPRINTK ("rtd520: Reading epld from %p\n", - devpriv->las0+0); - epld_version = readl (devpriv->las0+0); - if ((epld_version & 0xF0) >> 4 == 0x0F) { - DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version); - } else { - DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4); - } */ + if (pcidev->irq) { + ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; } - /* Show board configuration */ - printk(KERN_INFO "%s:", dev->board_name); - ret = comedi_alloc_subdevices(dev, 4); 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_COMMON | SDF_DIFF | SDF_CMD_READ; - s->n_chan = thisboard->aiChans; - s->maxdata = (1 << thisboard->aiBits) - 1; - if (thisboard->aiMaxGain <= 32) - s->range_table = &rtd_ai_7520_range; - else - s->range_table = &rtd_ai_4520_range; - - s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */ - s->insn_read = rtd_ai_rinsn; - s->do_cmd = rtd_ai_cmd; - s->do_cmdtest = rtd_ai_cmdtest; - s->cancel = rtd_ai_cancel; - /* s->poll = rtd_ai_poll; *//* not ready yet */ + 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 = thisboard->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 = (1 << thisboard->aiBits) - 1; - s->range_table = &rtd_ao_range; - s->insn_write = rtd_ao_winsn; - s->insn_read = rtd_ao_rinsn; + 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_winsn; + s->insn_read = rtd_ao_rinsn; s = &dev->subdevices[2]; /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + 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; + 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; /* timer/counter subdevices (not currently supported) */ s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 3; - s->maxdata = 0xffff; + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 3; + s->maxdata = 0xffff; - /* initialize board, per RTD spec */ - /* also, initialize shadow registers */ - writel(0, devpriv->las0 + LAS0_BOARD_RESET); - udelay(100); /* needed? */ - writel(0, devpriv->lcfg + LCFG_ITCSR); - devpriv->intMask = 0; - writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - devpriv->intClearMask = ~0; - writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR); - readw(devpriv->las0 + LAS0_CLEAR); - writel(0, devpriv->las0 + LAS0_OVERRUN); - writel(0, devpriv->las0 + LAS0_CGT_CLEAR); - writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); - writel(0, devpriv->las0 + LAS0_DAC1_RESET); - writel(0, devpriv->las0 + LAS0_DAC2_RESET); - /* clear digital IO fifo */ - devpriv->dioStatus = 0; - writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS); - devpriv->utcCtrl[0] = (0 << 6) | 0x30; - devpriv->utcCtrl[1] = (1 << 6) | 0x30; - devpriv->utcCtrl[2] = (2 << 6) | 0x30; - devpriv->utcCtrl[3] = (3 << 6) | 0x00; - writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL); - writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL); - writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL); - writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL); - /* TODO: set user out source ??? */ - - /* check if our interrupt is available and get it */ - ret = request_irq(pcidev->irq, rtd_interrupt, - IRQF_SHARED, DRV_NAME, dev); - - if (ret < 0) { - printk("Could not get interrupt! (%u)\n", - pcidev->irq); - return ret; - } - dev->irq = pcidev->irq; - printk(KERN_INFO "( irq=%u )", dev->irq); + rtd_init_board(dev); ret = rtd520_probe_fifo_depth(dev); if (ret < 0) return ret; - devpriv->fifoLen = ret; - printk("( fifoLen=%d )", devpriv->fifoLen); - -#ifdef USE_DMA - if (dev->irq > 0) { - printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT); - /* - * The PLX9080 has 2 DMA controllers, but there could be - * 4 sources: ADC, digital, DAC1, and DAC2. Since only the - * ADC supports cmd mode right now, this isn't an issue (yet) - */ - devpriv->dma0Offset = 0; - - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - devpriv->dma0Buff[index] = - pci_alloc_consistent(pcidev, - sizeof(u16) * - devpriv->fifoLen / 2, - &devpriv-> - dma0BuffPhysAddr[index]); - if (devpriv->dma0Buff[index] == NULL) { - ret = -ENOMEM; - goto rtd_attach_die_error; - } - /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n", - index, - devpriv->dma0Buff[index], - devpriv->dma0BuffPhysAddr[index]); */ - } - - /* - * setup DMA descriptor ring (use cpu_to_le32 for byte - * ordering?) - */ - devpriv->dma0Chain = - pci_alloc_consistent(pcidev, - sizeof(struct plx_dma_desc) * - DMA_CHAIN_COUNT, - &devpriv->dma0ChainPhysAddr); - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - devpriv->dma0Chain[index].pci_start_addr = - devpriv->dma0BuffPhysAddr[index]; - devpriv->dma0Chain[index].local_start_addr = - DMALADDR_ADC; - devpriv->dma0Chain[index].transfer_size = - sizeof(u16) * devpriv->fifoLen / 2; - devpriv->dma0Chain[index].next = - (devpriv->dma0ChainPhysAddr + ((index + - 1) % - (DMA_CHAIN_COUNT)) - * sizeof(devpriv->dma0Chain[0])) - | DMA_TRANSFER_BITS; - /*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n", - index, - ((long)devpriv->dma0ChainPhysAddr - + (index * sizeof(devpriv->dma0Chain[0]))), - devpriv->dma0Chain[index].pci_start_addr, - devpriv->dma0Chain[index].local_start_addr, - devpriv->dma0Chain[index].transfer_size, - devpriv->dma0Chain[index].next); */ - } - - if (devpriv->dma0Chain == NULL) { - ret = -ENOMEM; - goto rtd_attach_die_error; - } - - writel(DMA_MODE_BITS, devpriv->lcfg + LCFG_DMAMODE0); - /* set DMA trigger source */ - writel(DMAS_ADFIFO_HALF_FULL, devpriv->las0 + LAS0_DMA0_SRC); - } else { - printk(KERN_INFO "( no IRQ->no DMA )"); - } -#endif /* USE_DMA */ if (dev->irq) writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR); - printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); - return 1; + return 0; } static void rtd_detach(struct comedi_device *dev) { struct rtdPrivate *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); -#ifdef USE_DMA - int index; -#endif if (devpriv) { /* Shut down any board ops by resetting it */ -#ifdef USE_DMA - if (devpriv->lcfg) { - devpriv->dma0Control = 0; - devpriv->dma1Control = 0; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - writeb(devpriv->dma1Control, - devpriv->lcfg + LCFG_DMACSR1); - writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR); - } -#endif /* USE_DMA */ - if (devpriv->las0) { - writel(0, devpriv->las0 + LAS0_BOARD_RESET); - devpriv->intMask = 0; - writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - devpriv->intClearMask = ~0; - writew(devpriv->intClearMask, - devpriv->las0 + LAS0_CLEAR); - readw(devpriv->las0 + LAS0_CLEAR); - } -#ifdef USE_DMA - /* release DMA */ - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - if (NULL != devpriv->dma0Buff[index]) { - pci_free_consistent(pcidev, - sizeof(u16) * - devpriv->fifoLen / 2, - devpriv->dma0Buff[index], - devpriv-> - dma0BuffPhysAddr[index]); - devpriv->dma0Buff[index] = NULL; - } - } - if (NULL != devpriv->dma0Chain) { - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) * - DMA_CHAIN_COUNT, devpriv->dma0Chain, - devpriv->dma0ChainPhysAddr); - devpriv->dma0Chain = NULL; - } -#endif /* USE_DMA */ + if (devpriv->las0 && devpriv->lcfg) + rtd_reset(dev); if (dev->irq) { writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E), @@ -1923,24 +1404,23 @@ static void rtd_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver rtd520_driver = { .driver_name = "rtd520", .module = THIS_MODULE, - .attach = rtd_attach, + .auto_attach = rtd_auto_attach, .detach = rtd_detach, }; -static int __devinit rtd520_pci_probe(struct pci_dev *dev, +static int rtd520_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &rtd520_driver); } -static void __devexit rtd520_pci_remove(struct pci_dev *dev) +static void rtd520_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -1956,7 +1436,7 @@ static struct pci_driver rtd520_pci_driver = { .name = "rtd520", .id_table = rtd520_pci_table, .probe = rtd520_pci_probe, - .remove = __devexit_p(rtd520_pci_remove), + .remove = rtd520_pci_remove, }; module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver); diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h index a3ec259..25188a5 100644 --- a/drivers/staging/comedi/drivers/rtd520.h +++ b/drivers/staging/comedi/drivers/rtd520.h @@ -26,163 +26,132 @@ */ /* - LAS0 Runtime Area - Local Address Space 0 Offset Read Function Write Function -*/ -#define LAS0_SPARE_00 0x0000 /* - - */ -#define LAS0_SPARE_04 0x0004 /* - - */ -#define LAS0_USER_IO 0x0008 /* Read User Inputs Write User Outputs */ -#define LAS0_SPARE_0C 0x000C /* - - */ -#define LAS0_ADC 0x0010 /* Read FIFO Status Software A/D Start */ -#define LAS0_DAC1 0x0014 /* - Software D/A1 Update */ -#define LAS0_DAC2 0x0018 /* - Software D/A2 Update */ -#define LAS0_SPARE_1C 0x001C /* - - */ -#define LAS0_SPARE_20 0x0020 /* - - */ -#define LAS0_DAC 0x0024 /* - Software Simultaneous D/A1 and D/A2 Update */ -#define LAS0_PACER 0x0028 /* Software Pacer Start Software Pacer Stop */ -#define LAS0_TIMER 0x002C /* Read Timer Counters Status HDIN Software Trigger */ -#define LAS0_IT 0x0030 /* Read Interrupt Status Write Interrupt Enable Mask Register */ -#define LAS0_CLEAR 0x0034 /* Clear ITs set by Clear Mask Set Interrupt Clear Mask */ -#define LAS0_OVERRUN 0x0038 /* Read pending interrupts Clear Overrun Register */ -#define LAS0_SPARE_3C 0x003C /* - - */ + * Local Address Space 0 Offsets + */ +#define LAS0_USER_IO 0x0008 /* User I/O */ +#define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */ +#define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */ +#define LAS0_DAC2 0x0018 /* Software D/A2 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 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_UTC0 0x0060 /* 8254 TC Counter 0 */ +#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */ +#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */ +#define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */ +#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_DAC1_CTRL 0x0150 /* D/A1 output type/range */ +#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */ +#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */ +#define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */ +#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */ +#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */ +#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */ +#define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */ +#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */ +#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 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_UTC0_CLOCK 0x01ac /* UTC0 Clock select */ +#define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */ +#define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */ +#define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */ +#define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */ +#define LAS0_UTC2_GATE 0x01c0 /* UTC2 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 */ /* - LAS0 Runtime Area Timer/Counter,Dig.IO - Name Local Address Function -*/ -#define LAS0_PCLK 0x0040 /* Pacer Clock value (24bit) Pacer Clock load (24bit) */ -#define LAS0_BCLK 0x0044 /* Burst Clock value (10bit) Burst Clock load (10bit) */ -#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter value (10bit) A/D Sample counter load (10bit) */ -#define LAS0_DAC1_UCNT 0x004C /* D/A1 Update counter value (10 bit) D/A1 Update counter load (10bit) */ -#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter value (10 bit) D/A2 Update counter load (10bit) */ -#define LAS0_DCNT 0x0054 /* Delay counter value (16 bit) Delay counter load (16bit) */ -#define LAS0_ACNT 0x0058 /* About counter value (16 bit) About counter load (16bit) */ -#define LAS0_DAC_CLK 0x005C /* DAC clock value (16bit) DAC clock load (16bit) */ -#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 User TC 0 value Load count in TC Counter 0 */ -#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 User TC 1 value Load count in TC Counter 1 */ -#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 User TC 2 value Load count in TC Counter 2 */ -#define LAS0_UTC_CTRL 0x006C /* 8254 TC Control Word Program counter mode for TC */ -#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 Read Port Digital I/O Port 0 Write Port */ -#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 Read Port Digital I/O Port 1 Write Port */ -#define LAS0_DIO0_CTRL 0x0078 /* Clear digital IRQ status flag/read Clear digital chip/program Port 0 */ -#define LAS0_DIO_STATUS 0x007C /* Read Digital I/O Status word Program digital control register & */ - -/* - LAS0 Setup Area - Name Local Address Function -*/ -#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 /* High Speed Digital Input 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_DAC1_CTRL 0x0150 /* D/A1 output type/range */ -#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */ -#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */ -#define LAS0_DAC1_RESET 0x015C /* D/A1 FIFO reset */ -#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */ -#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */ -#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */ -#define LAS0_DAC2_CYCLE 0x016C /* D/A2 cycle mode */ -#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */ -#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 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 /* External Trigger polarity select */ -#define LAS0_EINT_POLARITY 0x01A8 /* External Interrupt polarity select */ -#define LAS0_UTC0_CLOCK 0x01AC /* UTC0 Clock select */ -#define LAS0_UTC0_GATE 0x01B0 /* UTC0 Gate select */ -#define LAS0_UTC1_CLOCK 0x01B4 /* UTC1 Clock select */ -#define LAS0_UTC1_GATE 0x01B8 /* UTC1 Gate select */ -#define LAS0_UTC2_CLOCK 0x01BC /* UTC2 Clock select */ -#define LAS0_UTC2_GATE 0x01C0 /* UTC2 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_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */ +#define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */ /* - LAS1 - Name Local Address Function -*/ -#define LAS1_ADC_FIFO 0x0000 /* Read A/D FIFO (16bit) - */ -#define LAS1_HDIO_FIFO 0x0004 /* Read High Speed Digital Input FIFO (16bit) - */ -#define LAS1_DAC1_FIFO 0x0008 /* - Write D/A1 FIFO (16bit) */ -#define LAS1_DAC2_FIFO 0x000C /* - Write D/A2 FIFO (16bit) */ - -/* - LCFG: PLX 9080 local config & runtime registers - Name Local Address Function -*/ -#define LCFG_ITCSR 0x0068 /* INTCSR, Interrupt Control/Status Register */ -#define LCFG_DMAMODE0 0x0080 /* DMA Channel 0 Mode Register */ -#define LCFG_DMAPADR0 0x0084 /* DMA Channel 0 PCI Address Register */ -#define LCFG_DMALADR0 0x0088 /* DMA Channel 0 Local Address Reg */ -#define LCFG_DMASIZ0 0x008C /* DMA Channel 0 Transfer Size (Bytes) Register */ -#define LCFG_DMADPR0 0x0090 /* DMA Channel 0 Descriptor Pointer Register */ -#define LCFG_DMAMODE1 0x0094 /* DMA Channel 1 Mode Register */ -#define LCFG_DMAPADR1 0x0098 /* DMA Channel 1 PCI Address Register */ -#define LCFG_DMALADR1 0x009C /* DMA Channel 1 Local Address Register */ -#define LCFG_DMASIZ1 0x00A0 /* DMA Channel 1 Transfer Size (Bytes) Register */ -#define LCFG_DMADPR1 0x00A4 /* DMA Channel 1 Descriptor Pointer Register */ -#define LCFG_DMACSR0 0x00A8 /* DMA Channel 0 Command/Status Register */ -#define LCFG_DMACSR1 0x00A9 /* DMA Channel 0 Command/Status Register */ -#define LCFG_DMAARB 0x00AC /* DMA Arbitration Register */ -#define LCFG_DMATHR 0x00B0 /* DMA Threshold Register */ - -/*====================================================================== - Resister bit definitions -======================================================================*/ + * PLX 9080 local config & runtime registers + */ +#define LCFG_ITCSR 0x0068 /* Interrupt Control/Status */ +#define LCFG_DMAMODE0 0x0080 /* DMA0 Mode */ +#define LCFG_DMAPADR0 0x0084 /* DMA0 PCI Address */ +#define LCFG_DMALADR0 0x0088 /* DMA0 Local Address */ +#define LCFG_DMASIZ0 0x008c /* DMA0 Transfer Size (Bytes) */ +#define LCFG_DMADPR0 0x0090 /* DMA0 Descriptor Pointer */ +#define LCFG_DMAMODE1 0x0094 /* DMA1 Mode */ +#define LCFG_DMAPADR1 0x0098 /* DMA1 PCI Address */ +#define LCFG_DMALADR1 0x009c /* DMA1 Local Address */ +#define LCFG_DMASIZ1 0x00a0 /* DMA1 Transfer Size (Bytes) */ +#define LCFG_DMADPR1 0x00a4 /* DMA1 Descriptor Pointer */ +#define LCFG_DMACSR0 0x00a8 /* DMA0 Command/Status */ +#define LCFG_DMACSR1 0x00a9 /* DMA0 Command/Status */ +#define LCFG_DMAARB 0x00ac /* DMA Arbitration */ +#define LCFG_DMATHR 0x00b0 /* DMA Threshold */ /* FIFO Status Word Bits (RtdFifoStatus) */ -#define FS_DAC1_NOT_EMPTY 0x0001 /* D0 - DAC1 FIFO not empty */ -#define FS_DAC1_HEMPTY 0x0002 /* D1 - DAC1 FIFO half empty */ -#define FS_DAC1_NOT_FULL 0x0004 /* D2 - DAC1 FIFO not full */ -#define FS_DAC2_NOT_EMPTY 0x0010 /* D4 - DAC2 FIFO not empty */ -#define FS_DAC2_HEMPTY 0x0020 /* D5 - DAC2 FIFO half empty */ -#define FS_DAC2_NOT_FULL 0x0040 /* D6 - DAC2 FIFO not full */ -#define FS_ADC_NOT_EMPTY 0x0100 /* D8 - ADC FIFO not empty */ -#define FS_ADC_HEMPTY 0x0200 /* D9 - ADC FIFO half empty */ -#define FS_ADC_NOT_FULL 0x0400 /* D10 - ADC FIFO not full */ -#define FS_DIN_NOT_EMPTY 0x1000 /* D12 - DIN FIFO not empty */ -#define FS_DIN_HEMPTY 0x2000 /* D13 - DIN FIFO half empty */ -#define FS_DIN_NOT_FULL 0x4000 /* D14 - DIN FIFO not full */ +#define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */ +#define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */ +#define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */ +#define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */ +#define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */ +#define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */ +#define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */ +#define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */ +#define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */ +#define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */ +#define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */ +#define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */ /* Timer Status Word Bits (GetTimerStatus) */ -#define TS_PCLK_GATE 0x0001 -/* D0 - Pacer Clock Gate [0 - gated, 1 - enabled] */ -#define TS_BCLK_GATE 0x0002 -/* D1 - Burst Clock Gate [0 - disabled, 1 - running] */ -#define TS_DCNT_GATE 0x0004 -/* D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in */ -/* progress] */ -#define TS_ACNT_GATE 0x0008 -/* D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress] */ -#define TS_PCLK_RUN 0x0010 -/* D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start */ -/* triggered only by Software Pacer Start Command, 1 - Pacer Clock can */ -/* be start triggered] */ +#define TS_PCLK_GATE (1 << 0) /* Pacer Clock Gate enabled */ +#define TS_BCLK_GATE (1 << 1) /* Burst Clock Gate running */ +#define TS_DCNT_GATE (1 << 2) /* Pacer Clock Delayed Start Trig. */ +#define TS_ACNT_GATE (1 << 3) /* Pacer Clock About Trig. */ +#define TS_PCLK_RUN (1 << 4) /* Pacer Clock Shutdown Flag */ /* External Trigger polarity select */ /* External Interrupt polarity select */ diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 137885b..7e577e4 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -161,8 +161,6 @@ struct rti800_private { int muxgain_bits; }; -#define devpriv ((struct rti800_private *)dev->private) - #define RTI800_TIMEOUT 100 static irqreturn_t rti800_interrupt(int irq, void *dev) @@ -177,6 +175,7 @@ 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; int i, t; int status; int chan = CR_CHAN(insn->chanspec); @@ -229,6 +228,7 @@ static int rti800_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct rti800_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -242,6 +242,7 @@ 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; int chan = CR_CHAN(insn->chanspec); int d; int i; @@ -303,6 +304,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev, static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct rti800_board *board = comedi_board(dev); + struct rti800_private *devpriv; unsigned int irq; unsigned long iobase; int ret; @@ -347,9 +349,10 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct rti800_private)); - if (ret < 0) - return ret; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; devpriv->adc_mux = it->options[2]; devpriv->adc_range = it->options[3]; diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 3f9d027..2185ca1 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -55,12 +55,11 @@ struct rti802_private { unsigned int ao_readback[8]; }; -#define devpriv ((struct rti802_private *)dev->private) - static int rti802_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct rti802_private *devpriv = dev->private; int i; for (i = 0; i < insn->n; i++) @@ -73,6 +72,7 @@ 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; int i, d; int chan = CR_CHAN(insn->chanspec); @@ -89,6 +89,7 @@ static int rti802_ao_insn_write(struct comedi_device *dev, static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct rti802_private *devpriv; struct comedi_subdevice *s; int i; unsigned long iobase; @@ -104,8 +105,10 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = "rti802"; - if (alloc_private(dev, sizeof(struct rti802_private))) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index a1e2562..39232b35 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -564,10 +564,10 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 551d68b..6dc1d28 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -161,7 +161,6 @@ static struct dio_private *dio_private_word[]={ }; */ -#define devpriv ((struct s626_private *)dev->private) #define diopriv ((struct dio_private *)s->private) /* COUNTER OBJECT ------------------------------------------------ */ @@ -232,6 +231,8 @@ static const struct comedi_lrange s626_range_table = { 2, { /* critical section. */ static void DEBItransfer(struct comedi_device *dev) { + struct s626_private *devpriv = dev->private; + /* Initiate upload of shadow RAM to DEBI control register. */ MC_ENABLE(P_MC2, MC2_UPLD_DEBI); @@ -249,6 +250,7 @@ static void DEBItransfer(struct comedi_device *dev) static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) { + struct s626_private *devpriv = dev->private; uint16_t retval; /* Set up DEBI control register value in shadow RAM. */ @@ -267,6 +269,7 @@ static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) /* Write a value to a gate array register. */ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) { + struct s626_private *devpriv = dev->private; /* Set up DEBI control register value in shadow RAM. */ WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); @@ -283,6 +286,7 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, uint16_t wdata) { + struct s626_private *devpriv = dev->private; /* Copy target gate array register into P_DEBIAD register. */ WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); @@ -302,6 +306,8 @@ static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) { + struct s626_private *devpriv = dev->private; + /* Write I2C command to I2C Transfer Control shadow register. */ WR7146(P_I2CCTRL, val); @@ -324,6 +330,7 @@ static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) /* Read uint8_t from EEPROM. */ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) { + struct s626_private *devpriv = dev->private; uint8_t rtnval; /* Send EEPROM target address. */ @@ -375,6 +382,7 @@ static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x */ static void SendDAC(struct comedi_device *dev, uint32_t val) { + struct s626_private *devpriv = dev->private; /* START THE SERIAL CLOCK RUNNING ------------- */ @@ -496,6 +504,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) /* Private helper function: Write setpoint to an application DAC channel. */ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) { + struct s626_private *devpriv = dev->private; register uint16_t signmask; register uint32_t WSImage; @@ -553,6 +562,7 @@ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, uint8_t DacData) { + struct s626_private *devpriv = dev->private; uint32_t chan; /* Save the new setpoint in case the application needs to read it back later. */ @@ -735,6 +745,7 @@ static int s626_dio_clear_irq(struct comedi_device *dev) static irqreturn_t s626_irq_handler(int irq, void *d) { struct comedi_device *dev = d; + struct s626_private *devpriv = dev->private; struct comedi_subdevice *s; struct comedi_cmd *cmd; struct enc_private *k; @@ -968,6 +979,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) */ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) { + struct s626_private *devpriv = dev->private; register uint32_t *pRPS; uint32_t JmpAdrs; uint16_t i; @@ -1163,6 +1175,7 @@ static int s626_ai_insn_config(struct comedi_device *dev, /* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */ /* { */ +/* struct s626_private *devpriv = dev->private; */ /* register uint8_t i; */ /* register int32_t *readaddr; */ @@ -1191,6 +1204,7 @@ static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s626_private *devpriv = dev->private; uint16_t chan = CR_CHAN(insn->chanspec); uint16_t range = CR_RANGE(insn->chanspec); uint16_t AdcSpec = 0; @@ -1302,6 +1316,8 @@ static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd) static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct s626_private *devpriv = dev->private; + if (trignum != 0) return -EINVAL; @@ -1378,7 +1394,7 @@ static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, /* TO COMPLETE */ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - + struct s626_private *devpriv = dev->private; uint8_t ppl[16]; struct comedi_cmd *cmd = &s->async->cmd; struct enc_private *k; @@ -1533,80 +1549,46 @@ static int s626_ai_cmdtest(struct comedi_device *dev, /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_src != TRIG_EXT && cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + if (cmd->start_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + if (cmd->start_src == TRIG_EXT) + err |= cfc_check_trigger_arg_max(&cmd->start_arg, 39); - if (cmd->start_src == TRIG_EXT && cmd->start_arg > 39) { - cmd->start_arg = 39; - err++; - } + if (cmd->scan_begin_src == TRIG_EXT) + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 39); - if (cmd->scan_begin_src == TRIG_EXT && cmd->scan_begin_arg > 39) { - cmd->scan_begin_arg = 39; - err++; - } + if (cmd->convert_src == TRIG_EXT) + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 39); - if (cmd->convert_src == TRIG_EXT && cmd->convert_arg > 39) { - cmd->convert_arg = 39; - err++; - } #define MAX_SPEED 200000 /* in nanoseconds */ #define MIN_SPEED 2000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ -/* if(cmd->scan_begin_arg>9){ */ -/* cmd->scan_begin_arg=9; */ -/* err++; */ -/* } */ +/* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */ } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED); } else { /* external trigger */ /* see above */ -/* if(cmd->convert_arg>9){ */ -/* cmd->convert_arg=9; */ -/* err++; */ -/* } */ +/* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */ } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1643,6 +1625,8 @@ static int s626_ai_cmdtest(struct comedi_device *dev, 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. */ MC_DISABLE(P_MC1, MC1_ERPS1); @@ -1657,7 +1641,7 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct s626_private *devpriv = dev->private; int i; uint16_t chan = CR_CHAN(insn->chanspec); int16_t dacdata; @@ -1676,6 +1660,7 @@ static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s626_private *devpriv = dev->private; int i; for (i = 0; i < insn->n; i++) @@ -1974,6 +1959,7 @@ static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k) static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup, uint16_t DisableIntSrc) { + struct s626_private *devpriv = dev->private; register uint16_t cra; register uint16_t crb; register uint16_t setup = Setup; /* Cache the Standard Setup. */ @@ -2032,6 +2018,7 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k, static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup, uint16_t DisableIntSrc) { + struct s626_private *devpriv = dev->private; register uint16_t cra; register uint16_t crb; register uint16_t setup = Setup; /* Cache the Standard Setup. */ @@ -2165,6 +2152,8 @@ static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k) static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, uint16_t IntSource) { + struct s626_private *devpriv = dev->private; + /* Reset any pending counter overflow or index captures. */ DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); @@ -2182,6 +2171,7 @@ static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k, uint16_t IntSource) { + struct s626_private *devpriv = dev->private; uint16_t crb; /* Cache writeable CRB register image. */ @@ -2412,6 +2402,7 @@ static void CountersInit(struct comedi_device *dev) 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; @@ -2432,6 +2423,7 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev) static void s626_initialize(struct comedi_device *dev) { + struct s626_private *devpriv = dev->private; dma_addr_t pPhysBuf; uint16_t chan; int i; @@ -2665,16 +2657,20 @@ static void s626_initialize(struct comedi_device *dev) /* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */ } -static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +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; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - if (alloc_private(dev, sizeof(struct s626_private)) < 0) + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -2794,6 +2790,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) static void s626_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct s626_private *devpriv = dev->private; if (devpriv) { /* stop ai_command */ @@ -2829,17 +2826,17 @@ static void s626_detach(struct comedi_device *dev) static struct comedi_driver s626_driver = { .driver_name = "s626", .module = THIS_MODULE, - .attach_pci = s626_attach_pci, + .auto_attach = s626_auto_attach, .detach = s626_detach, }; -static int __devinit s626_pci_probe(struct pci_dev *dev, +static int s626_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &s626_driver); } -static void __devexit s626_pci_remove(struct pci_dev *dev) +static void s626_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } @@ -2860,7 +2857,7 @@ static struct pci_driver s626_pci_driver = { .name = "s626", .id_table = s626_pci_table, .probe = s626_pci_probe, - .remove = __devexit_p(s626_pci_remove), + .remove = s626_pci_remove, }; module_comedi_pci_driver(s626_driver, s626_pci_driver); diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 5bf84cf..e6177b4 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -31,6 +31,8 @@ Status: in development */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include <linux/delay.h> @@ -43,10 +45,6 @@ Status: in development #include <linux/serial.h> #include <linux/poll.h> -struct serial2002_board { - const char *name; -}; - struct serial2002_range_table_t { /* HACK... */ @@ -68,12 +66,6 @@ struct serial2002_private { struct serial2002_range_table_t in_range[32], out_range[32]; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct serial2002_private *)dev->private) - struct serial_data { enum { is_invalid, is_digital, is_channel } kind; int index; @@ -282,7 +274,7 @@ static struct serial_data serial_read(struct file *f, int timeout) length++; if (data < 0) { - printk(KERN_ERR "serial2002 error\n"); + pr_err("Failed to read serial.\n"); break; } else if (data & 0x80) { result.value = (result.value << 7) | (data & 0x7f); @@ -348,6 +340,7 @@ static void serial_write(struct file *f, struct serial_data data) static int serial_2002_open(struct comedi_device *dev) { + struct serial2002_private *devpriv = dev->private; int result; char port[20]; @@ -355,7 +348,7 @@ static int serial_2002_open(struct comedi_device *dev) devpriv->tty = filp_open(port, O_RDWR, 0); if (IS_ERR(devpriv->tty)) { result = (int)PTR_ERR(devpriv->tty); - printk(KERN_ERR "serial_2002: file open error = %d\n", result); + dev_err(dev->class_dev, "file open error = %d\n", result); } else { struct config_t { @@ -655,6 +648,8 @@ err_alloc_configs: static void serial_2002_close(struct comedi_device *dev) { + struct serial2002_private *devpriv = dev->private; + if (!IS_ERR(devpriv->tty) && devpriv->tty) filp_close(devpriv->tty, NULL); } @@ -663,6 +658,7 @@ static int serial2002_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -685,6 +681,7 @@ static int serial2002_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -704,6 +701,7 @@ static int serial2002_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -726,6 +724,7 @@ static int serial2002_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -746,6 +745,7 @@ static int serial2002_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -759,6 +759,7 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -780,14 +781,18 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, static int serial2002_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct serial2002_board *board = comedi_board(dev); + struct serial2002_private *devpriv; struct comedi_subdevice *s; int ret; dev_dbg(dev->class_dev, "serial2002: attach\n"); - dev->board_name = board->name; - if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) + dev->board_name = dev->driver->driver_name; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) return -ENOMEM; + dev->private = devpriv; + dev->open = serial_2002_open; dev->close = serial_2002_close; devpriv->port = it->options[0]; @@ -860,20 +865,11 @@ static void serial2002_detach(struct comedi_device *dev) } } -static const struct serial2002_board serial2002_boards[] = { - { - .name = "serial2002" - }, -}; - static struct comedi_driver serial2002_driver = { .driver_name = "serial2002", .module = THIS_MODULE, .attach = serial2002_attach, .detach = serial2002_detach, - .board_name = &serial2002_boards[0].name, - .offset = sizeof(struct serial2002_board), - .num_names = ARRAY_SIZE(serial2002_boards), }; module_comedi_driver(serial2002_driver); diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index b70cdf3..e2d7970 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -92,6 +92,7 @@ Configuration Options: */ struct skel_board { const char *name; + unsigned int devid; int ai_chans; int ai_bits; int have_dio; @@ -100,36 +101,20 @@ struct skel_board { static const struct skel_board skel_boards[] = { { .name = "skel-100", + .devid = 0x100, .ai_chans = 16, .ai_bits = 12, .have_dio = 1, }, { .name = "skel-200", + .devid = 0x200, .ai_chans = 8, .ai_bits = 16, .have_dio = 0, }, }; -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded - * upstream. */ -#define PCI_VENDOR_ID_SKEL 0xdafe -static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) }, - { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, skel_pci_table); - -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct skel_board *)dev->board_ptr) - /* 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. @@ -138,165 +123,25 @@ struct skel_private { int data; - /* would be useful for a PCI device */ - struct pci_dev *pci_dev; - /* Used for AO readback */ unsigned int ao_readback[2]; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct skel_private *)dev->private) - -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static void skel_detach(struct comedi_device *dev); -static struct comedi_driver driver_skel = { - .driver_name = "dummy", - .module = THIS_MODULE, - .attach = skel_attach, - .detach = skel_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in skel_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &skel_boards[0].name, - .offset = sizeof(struct skel_board), - .num_names = ARRAY_SIZE(skel_boards), -}; - -static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd); -static int skel_ns_to_timer(unsigned int *ns, int round); - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) +/* 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 skel_ns_to_timer(unsigned int *ns, int round) { - struct comedi_subdevice *s; - int ret; - - pr_info("comedi%d: skel: ", dev->minor); - -/* - * If you can probe the device to determine what device in a series - * it is, this is the place to do it. Otherwise, dev->board_ptr - * should already be initialized. - */ - /* dev->board_ptr = skel_probe(dev, it); */ - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct skel_private)) < 0) - return -ENOMEM; - - ret = comedi_alloc_subdevices(dev, 3); - if (ret) - return ret; - - s = &dev->subdevices[0]; - /* dev->read_subdev=s; */ - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - /* we support single-ended (ground) and differential */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = &range_bipolar10; - s->len_chanlist = 16; /* This is the maximum chanlist length that - the board can handle */ - s->insn_read = skel_ai_rinsn; -/* -* s->subdev_flags |= SDF_CMD_READ; -* s->do_cmd = skel_ai_cmd; -*/ - s->do_cmdtest = skel_ai_cmdtest; - - s = &dev->subdevices[1]; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 1; - s->maxdata = 0xffff; - s->range_table = &range_bipolar5; - s->insn_write = skel_ao_winsn; - s->insn_read = skel_ao_rinsn; - - s = &dev->subdevices[2]; - /* digital i/o subdevice */ - if (thisboard->have_dio) { - 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 = skel_dio_insn_bits; - s->insn_config = skel_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - pr_info("attached\n"); - - return 0; -} + /* trivial timer */ + /* if your timing is done through two cascaded timers, the + * i8253_cascade_ns_to_timer() function in 8253.h can be + * very helpful. There are also i8254_load() and i8254_mm_load() + * which can be used to load values into the ubiquitous 8254 counters + */ -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static void skel_detach(struct comedi_device *dev) -{ + return *ns; } /* @@ -306,6 +151,7 @@ static void skel_detach(struct comedi_device *dev) static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct skel_board *thisboard = comedi_board(dev); int n, i; unsigned int d; unsigned int status; @@ -331,9 +177,7 @@ static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, break; } if (i == TIMEOUT) { - /* printk() should be used instead of printk() - * whenever the code can be called from real-time. */ - pr_info("timeout\n"); + dev_warn(dev->class_dev, "ai timeout\n"); return -ETIMEDOUT; } @@ -389,67 +233,40 @@ static int skel_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED 10000 /* in nanoseconds */ #define MIN_SPEED 1000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } + if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED); } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -484,30 +301,13 @@ static int skel_ai_cmdtest(struct comedi_device *dev, return 0; } -/* 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 skel_ns_to_timer(unsigned int *ns, int round) -{ - /* trivial timer */ - /* if your timing is done through two cascaded timers, the - * i8253_cascade_ns_to_timer() function in 8253.h can be - * very helpful. There are also i8254_load() and i8254_mm_load() - * which can be used to load values into the ubiquitous 8254 counters - */ - - return *ns; -} - static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct skel_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); - pr_info("skel_ao_winsn\n"); /* Writing a list of values to an AO channel is probably not * very useful, but that's how the interface is defined. */ for (i = 0; i < insn->n; i++) { @@ -525,6 +325,7 @@ static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct skel_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -593,57 +394,332 @@ static int skel_dio_insn_config(struct comedi_device *dev, return insn->n; } -#ifdef CONFIG_COMEDI_PCI_DRIVERS -static int __devinit driver_skel_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static const struct skel_board *skel_find_pci_board(struct pci_dev *pcidev) { - return comedi_pci_auto_config(dev, &driver_skel); + unsigned int i; + +/* + * This example code assumes all the entries in skel_boards[] are PCI boards + * and all use the same PCI vendor ID. If skel_boards[] contains a mixture + * of PCI and non-PCI boards, this loop should skip over the non-PCI boards. + */ + for (i = 0; i < ARRAY_SIZE(skel_boards); i++) + if (/* skel_boards[i].bustype == pci_bustype && */ + pcidev->device == skel_boards[i].devid) + return &skel_boards[i]; + return NULL; } -static void __devexit driver_skel_pci_remove(struct pci_dev *dev) +/* + * Handle common part of skel_attach() and skel_auto_attach(). + */ +static int skel_common_attach(struct comedi_device *dev) { - comedi_pci_auto_unconfig(dev); + const struct skel_board *thisboard = comedi_board(dev); + struct comedi_subdevice *s; + int ret; + + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; + + s = &dev->subdevices[0]; + /* dev->read_subdev=s; */ + /* analog input subdevice */ + s->type = COMEDI_SUBD_AI; + /* we support single-ended (ground) and differential */ + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->n_chan = thisboard->ai_chans; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = &range_bipolar10; + s->len_chanlist = 16; /* This is the maximum chanlist length that + the board can handle */ + s->insn_read = skel_ai_rinsn; +/* +* s->subdev_flags |= SDF_CMD_READ; +* s->do_cmd = skel_ai_cmd; +*/ + s->do_cmdtest = skel_ai_cmdtest; + + s = &dev->subdevices[1]; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 1; + s->maxdata = 0xffff; + s->range_table = &range_bipolar5; + s->insn_write = skel_ao_winsn; + s->insn_read = skel_ao_rinsn; + + s = &dev->subdevices[2]; + /* digital i/o subdevice */ + if (thisboard->have_dio) { + 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 = skel_dio_insn_bits; + s->insn_config = skel_dio_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + dev_info(dev->class_dev, "skel: attached\n"); + + return 0; } -static struct pci_driver driver_skel_pci_driver = { - .id_table = skel_pci_table, - .probe = &driver_skel_pci_probe, - .remove = __devexit_p(&driver_skel_pci_remove) -}; +/* + * _attach is called by the Comedi core to configure the driver + * for a particular board in response to the COMEDI_DEVCONFIG ioctl for + * a matching board or driver name. If you specified a board_name array + * in the driver structure, dev->board_ptr contains that address. + * + * Drivers that handle only PCI or USB devices do not usually support + * manual attachment of those devices via the COMEDI_DEVCONFIG ioctl, so + * those drivers do not have an _attach function; they just have an + * _auto_attach function instead. (See skel_auto_attach() for an example + * of such a function.) + */ +static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct skel_board *thisboard; + struct skel_private *devpriv; + +/* + * If you can probe the device to determine what device in a series + * it is, this is the place to do it. Otherwise, dev->board_ptr + * should already be initialized. + */ + /* dev->board_ptr = skel_probe(dev, it); */ + + thisboard = comedi_board(dev); + +/* + * Initialize dev->board_name. + */ + dev->board_name = thisboard->name; + + /* Allocate the private data */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + +/* + * Supported boards are usually either auto-attached via the + * Comedi driver's _auto_attach routine, or manually attached via the + * Comedi driver's _attach routine. In most cases, attempts to + * manual attach boards that are usually auto-attached should be + * rejected by this function. + */ +/* + * if (thisboard->bustype == pci_bustype) { + * dev_err(dev->class_dev, + * "Manual attachment of PCI board '%s' not supported\n", + * thisboard->name); + * } + */ + +/* + * For ISA boards, get the i/o base address from it->options[], + * request the i/o region and set dev->iobase * from it->options[]. + * If using interrupts, get the IRQ number from it->options[]. + */ + + /* + * Call a common function to handle the remaining things to do for + * attaching ISA or PCI boards. (Extra parameters could be added + * to pass additional information such as IRQ number.) + */ + return skel_common_attach(dev); +} -static int __init driver_skel_init_module(void) +/* + * _auto_attach is called via comedi_pci_auto_config() (or + * comedi_usb_auto_config(), etc.) to handle devices that can be attached + * to the Comedi core automatically without the COMEDI_DEVCONFIG ioctl. + * + * The context parameter is usually unused, but if the driver called + * comedi_auto_config() directly instead of the comedi_pci_auto_config() + * wrapper function, this will be a copy of the context passed to + * comedi_auto_config(). + */ +static int skel_auto_attach(struct comedi_device *dev, + unsigned long context) { - int retval; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct skel_board *thisboard; + struct skel_private *devpriv; + int ret; + + /* Hack to allow unused code to be optimized out. */ + if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) + return -EINVAL; + + /* Find a matching board in skel_boards[]. */ + thisboard = skel_find_pci_board(pcidev); + if (!thisboard) { + dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); + return -EINVAL; + } + + /* + * Point the struct comedi_device to the matching board info + * and set the board name. + */ + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + + /* Allocate the private data */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; - retval = comedi_driver_register(&driver_skel); - if (retval < 0) - return retval; + /* Enable the PCI device. */ + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + + /* + * Record the fact that the PCI device is enabled so that it can + * be disabled during _detach(). + * + * For this example driver, we assume PCI BAR 0 is the main I/O + * region for the board registers and use dev->iobase to hold the + * I/O base address and to indicate that the PCI device has been + * enabled. + * + * (For boards with memory-mapped registers, dev->iobase is not + * usually needed for register access, so can just be set to 1 + * to indicate that the PCI device has been enabled.) + */ + dev->iobase = pci_resource_start(pcidev, 0); - driver_skel_pci_driver.name = (char *)driver_skel.driver_name; - return pci_register_driver(&driver_skel_pci_driver); + /* + * Call a common function to handle the remaining things to do for + * attaching ISA or PCI boards. (Extra parameters could be added + * to pass additional information such as IRQ number.) + */ + return skel_common_attach(dev); } -static void __exit driver_skel_cleanup_module(void) +/* + * _detach is called to deconfigure a device. It should deallocate + * resources. + * This function is also called when _attach() fails, so it should be + * careful not to release resources that were not necessarily + * allocated by _attach(). dev->private and dev->subdevices are + * deallocated automatically by the core. + */ +static void skel_detach(struct comedi_device *dev) { - pci_unregister_driver(&driver_skel_pci_driver); - comedi_driver_unregister(&driver_skel); + const struct skel_board *thisboard = comedi_board(dev); + struct skel_private *devpriv = dev->private; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (!thisboard || !devpriv) + return; + +/* + * Do common stuff such as freeing IRQ, unmapping remapped memory + * regions, etc., being careful to check that the stuff is valid given + * that _detach() is called even when _attach() or _auto_attach() return + * an error. + */ + + if (IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS) /* && + thisboard->bustype == pci_bustype */) { + /* + * PCI board + * + * If PCI device enabled by _auto_attach() (or _attach()), + * disable it here. + */ + if (pcidev && dev->iobase) + comedi_pci_disable(pcidev); + } else { + /* + * ISA board + * + * If I/O regions successfully requested by _attach(), + * release them here. + */ + if (dev->iobase) + release_region(dev->iobase, SKEL_SIZE); + } } -module_init(driver_skel_init_module); -module_exit(driver_skel_cleanup_module); -#else -static int __init driver_skel_init_module(void) +/* + * The struct comedi_driver structure tells the Comedi core module + * which functions to call to configure/deconfigure (attach/detach) + * the board, and also about the kernel module that contains + * the device code. + */ +static struct comedi_driver skel_driver = { + .driver_name = "dummy", + .module = THIS_MODULE, + .attach = skel_attach, + .auto_attach = skel_auto_attach, + .detach = skel_detach, +/* It is not necessary to implement the following members if you are + * writing a driver for a ISA PnP or PCI card */ + /* Most drivers will support multiple types of boards by + * having an array of board structures. These were defined + * in skel_boards[] above. Note that the element 'name' + * was first in the structure -- Comedi uses this fact to + * extract the name of the board without knowing any details + * about the structure except for its length. + * When a device is attached (by comedi_config), the name + * of the device is given to Comedi, and Comedi tries to + * match it by going through the list of board names. If + * there is a match, the address of the pointer is put + * into dev->board_ptr and driver->attach() is called. + * + * Note that these are not necessary if you can determine + * the type of board in software. ISA PnP, PCI, and PCMCIA + * devices are such boards. + */ + .board_name = &skel_boards[0].name, + .offset = sizeof(struct skel_board), + .num_names = ARRAY_SIZE(skel_boards), +}; + +#ifdef CONFIG_COMEDI_PCI_DRIVERS + +/* This is used by modprobe to translate PCI IDs to drivers. Should + * only be used for PCI and ISA-PnP devices */ +/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded + * upstream. */ +#define PCI_VENDOR_ID_SKEL 0xdafe +static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) }, + { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, skel_pci_table); + +static int skel_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_driver_register(&driver_skel); + return comedi_pci_auto_config(dev, &skel_driver); } -static void __exit driver_skel_cleanup_module(void) +static void skel_pci_remove(struct pci_dev *dev) { - comedi_driver_unregister(&driver_skel); + comedi_pci_auto_unconfig(dev); } -module_init(driver_skel_init_module); -module_exit(driver_skel_cleanup_module); +static struct pci_driver skel_pci_driver = { + .id_table = skel_pci_table, + .probe = &skel_pci_probe, + .remove = &skel_pci_remove +}; +module_comedi_pci_driver(skel_driver, skel_pci_driver); +#else +module_comedi_driver(skel_driver); #endif MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index ae3aa1c..afa4016 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -50,15 +50,6 @@ Status: unknown #define PCMR 0xa3 /* Port C Mode Register */ #define PCDR 0xa7 /* Port C Data Register */ -/* This data structure holds information about the supported boards -------- */ - -struct dnp_board { - const char *name; - int ai_chans; - int ai_bits; - int have_dio; -}; - /* ------------------------------------------------------------------------- */ /* The insn_bits interface allows packed reading/writing of DIO channels. */ /* The comedi core can convert between insn_bits and insn_read/write, so you */ @@ -173,11 +164,10 @@ static int dnp_dio_insn_config(struct comedi_device *dev, static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct dnp_board *board = comedi_board(dev); struct comedi_subdevice *s; int ret; - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; ret = comedi_alloc_subdevices(dev, 1); if (ret) @@ -219,23 +209,11 @@ static void dnp_detach(struct comedi_device *dev) outb((inb(CSCDR) & 0xAA), CSCDR); } -static const struct dnp_board dnp_boards[] = { - { - .name = "dnp-1486", - .ai_chans = 16, - .ai_bits = 12, - .have_dio = 1, - }, -}; - static struct comedi_driver dnp_driver = { - .driver_name = "ssv_dnp", + .driver_name = "dnp-1486", .module = THIS_MODULE, .attach = dnp_attach, .detach = dnp_detach, - .board_name = &dnp_boards[0].name, - .offset = sizeof(struct dnp_board), - .num_names = ARRAY_SIZE(dnp_boards), }; module_comedi_driver(dnp_driver); diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 9f1fdec..c9ded93 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -42,6 +42,8 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5), */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include <linux/ioport.h> #include <linux/slab.h> @@ -144,8 +146,7 @@ static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", minor, channel); return 0; } @@ -171,8 +172,7 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, /* defining if given module can work on input */ if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) { - printk(KERN_ERR - "comedi%d: module in position %d with id 0x%02x is for output only", + pr_err("comedi%d: module in position %d with id 0x%02x is for output only", minor, module_no, usp->usp_module_type[module_no]); return 0; } @@ -209,8 +209,7 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", minor, channel); return 0; } @@ -240,8 +239,7 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, /* defining if given module can work on output */ if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) { - printk(KERN_ERR - "comedi%d: module in position %d with id 0x%0x is for input only!\n", + pr_err("comedi%d: module in position %d with id 0x%0x is for input only!\n", minor, module, usp->usp_module_type[module]); return 0; } @@ -323,17 +321,17 @@ static int unioxx5_insn_config(struct comedi_device *dev, type = usp->usp_module_type[channel / 2]; if (type != MODULE_DIGITAL) { - printk(KERN_ERR - "comedi%d: channel configuration accessible only for digital modules\n", - dev->minor); + dev_err(dev->class_dev, + "comedi%d: channel configuration accessible only for digital modules\n", + dev->minor); return -1; } channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", - dev->minor, channel); + dev_err(dev->class_dev, + "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + dev->minor, channel); return -1; } @@ -348,7 +346,8 @@ static int unioxx5_insn_config(struct comedi_device *dev, flags |= mask; break; default: - printk(KERN_ERR "comedi%d: unknown flag\n", dev->minor); + dev_err(dev->class_dev, + "comedi%d: unknown flag\n", dev->minor); return -1; } @@ -375,19 +374,21 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, int i, to, ndef_flag = 0; if (!request_region(subdev_iobase, UNIOXX5_SIZE, DRIVER_NAME)) { - printk(KERN_ERR "comedi%d: I/O port conflict\n", minor); + dev_err(subdev->class_dev, + "comedi%d: I/O port conflict\n", minor); return -EIO; } usp = kzalloc(sizeof(*usp), GFP_KERNEL); if (usp == NULL) { - printk(KERN_ERR "comedi%d: error! --> out of memory!\n", minor); + dev_err(subdev->class_dev, + "comedi%d: error! --> out of memory!\n", minor); return -1; } usp->usp_iobase = subdev_iobase; - printk(KERN_INFO "comedi%d: |", minor); + dev_info(subdev->class_dev, "comedi%d: |", minor); /* defining modules types */ for (i = 0; i < 12; i++) { @@ -433,8 +434,6 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, /* for digital modules only!!! */ subdev->insn_config = unioxx5_insn_config; - printk(KERN_INFO "subdevice configured\n"); - return 0; } @@ -464,8 +463,8 @@ static int unioxx5_attach(struct comedi_device *dev, /* unioxx5 can has from two to four subdevices */ if (n_subd < 2) { - printk(KERN_ERR - "your card must has at least 2 'g01' subdevices\n"); + dev_err(dev->class_dev, + "your card must has at least 2 'g01' subdevices\n"); return -1; } @@ -480,7 +479,6 @@ static int unioxx5_attach(struct comedi_device *dev, return -1; } - printk(KERN_INFO "attached\n"); return 0; } diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index c484a73..17b45eb 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -938,9 +938,6 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (!(this_usbduxsub->probed)) return -ENODEV; - dev_dbg(&this_usbduxsub->interface->dev, - "comedi%d: usbdux_ai_cmdtest\n", dev->minor); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); @@ -962,19 +959,12 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { if (this_usbduxsub->high_speed) { @@ -989,51 +979,35 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, while (i < (cmd->chanlist_len)) i = i * 2; - if (cmd->scan_begin_arg < (1000000 / 8 * i)) { - cmd->scan_begin_arg = 1000000 / 8 * i; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000 / 8 * i); /* now calc the real sampling rate with all the * rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 125000)) * 125000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } else { /* full speed */ /* 1kHz scans every USB frame */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); /* * calc the real sampling rate with the rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 1000000)) * 1000000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } - } - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, + tmpTimer); } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -1472,9 +1446,6 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, if (!(this_usbduxsub->probed)) return -ENODEV; - dev_dbg(&this_usbduxsub->interface->dev, - "comedi%d: usbdux_ao_cmdtest\n", dev->minor); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); @@ -1519,57 +1490,30 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); - if (cmd->scan_begin_src == TRIG_TIMER) { - /* timer */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } - } /* not used now, is for later use */ - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < 125000) { - cmd->convert_arg = 125000; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000); - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } - dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, " - "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, " - "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src, - cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg); - if (err) return 3; @@ -2375,9 +2319,10 @@ static int usbdux_attach_common(struct comedi_device *dev, return 0; } -static int usbdux_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) +static int usbdux_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct usb_interface *uinterf = comedi_to_usb_interface(dev); int ret; struct usbduxsub *this_usbduxsub; @@ -2386,14 +2331,12 @@ static int usbdux_attach_usb(struct comedi_device *dev, down(&start_stop_sem); this_usbduxsub = usb_get_intfdata(uinterf); if (!this_usbduxsub || !this_usbduxsub->probed) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach_usb failed, not connected\n", - dev->minor); + dev_err(dev->class_dev, + "usbdux: error: auto_attach failed, not connected\n"); ret = -ENODEV; } else if (this_usbduxsub->attached) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach_usb failed, already attached\n", - dev->minor); + dev_err(dev->class_dev, + "error: auto_attach failed, already attached\n"); ret = -ENODEV; } else ret = usbdux_attach_common(dev, this_usbduxsub); @@ -2417,7 +2360,7 @@ static void usbdux_detach(struct comedi_device *dev) static struct comedi_driver usbdux_driver = { .driver_name = "usbdux", .module = THIS_MODULE, - .attach_usb = usbdux_attach_usb, + .auto_attach = usbdux_auto_attach, .detach = usbdux_detach, }; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 1154a7e..4e19f61 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -37,6 +37,8 @@ * udev coldplug problem */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/firmware.h> #include <linux/module.h> @@ -216,8 +218,9 @@ static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type) usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP), udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000); if (tmp < 0) - printk(KERN_ERR "comedi%d: could not transmit dux_commands to" - "the usb-device, err=%d\n", udfs->comedidev->minor, tmp); + dev_err(&udfs->interface->dev, + "could not transmit dux_commands to the usb-device, err=%d\n", + tmp); return tmp; } @@ -252,7 +255,7 @@ static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink) int ret = 0; if (!udfs) { - printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n"); + pr_err("%s: udfs=NULL!\n", __func__); return -EFAULT; } #ifdef CONFIG_COMEDI_DEBUG @@ -284,7 +287,7 @@ static int usbduxfast_ai_cancel(struct comedi_device *dev, #endif udfs = dev->private; if (!udfs) { - printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n"); + dev_err(dev->class_dev, "%s: udfs=NULL\n", __func__); return -EFAULT; } down(&udfs->sem); @@ -309,26 +312,22 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) struct usbduxfastsub_s *udfs; struct comedi_device *this_comedidev; struct comedi_subdevice *s; - uint16_t *p; /* sanity checks - is the urb there? */ if (!urb) { - printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called " - "with urb=NULL!\n"); + pr_err("ao int-handler called with urb=NULL!\n"); return; } /* the context variable points to the subdevice */ this_comedidev = urb->context; if (!this_comedidev) { - printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL " - "pointer!\n"); + pr_err("urb context is a NULL pointer!\n"); return; } /* the private structure of the subdevice is usbduxfastsub_s */ udfs = this_comedidev->private; if (!udfs) { - printk(KERN_ERR "comedi_: usbduxfast_: private of comedi " - "subdev is a NULL pointer!\n"); + pr_err("private of comedi subdev is a NULL pointer!\n"); return; } /* are we running a command? */ @@ -370,9 +369,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) return; default: - printk("comedi%d: usbduxfast: non-zero urb status received in " - "ai intr context: %d\n", - udfs->comedidev->minor, urb->status); + pr_err("non-zero urb status received in ai intr context: %d\n", + urb->status); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; comedi_event(udfs->comedidev, s); @@ -380,7 +378,6 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) return; } - p = urb->transfer_buffer; if (!udfs->ignore) { if (!udfs->ai_continous) { /* not continuous, fixed number of samples */ @@ -427,8 +424,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) urb->status = 0; err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d", - udfs->comedidev->minor, err); + dev_err(&urb->dev->dev, + "urb resubm failed: %d", err); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; comedi_event(udfs->comedidev, s); @@ -454,7 +451,8 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) 1, /* Length */ EZTIMEOUT); /* Timeout */ if (ret < 0) { - printk("comedi_: usbduxfast_: control msg failed (start)\n"); + dev_err(&udfs->interface->dev, + "control msg failed (start)\n"); return ret; } @@ -477,8 +475,8 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) local_transfer_buffer, 1, /* Length */ EZTIMEOUT); /* Timeout */ if (ret < 0) { - printk(KERN_ERR "comedi_: usbduxfast: control msg failed " - "(stop)\n"); + dev_err(&udfs->interface->dev, + "control msg failed (stop)\n"); return ret; } @@ -512,7 +510,7 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, #endif if (ret < 0) { - printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n"); + dev_err(&udfs->interface->dev, "uppload failed\n"); return ret; } @@ -538,8 +536,8 @@ static int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs) #endif ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC); if (ret) { - printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error" - " %d\n", ret); + dev_err(&udfs->interface->dev, + "ai: usb_submit_urb error %d\n", ret); return ret; } return 0; @@ -557,12 +555,6 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, if (!udfs->probed) return -ENODEV; -#ifdef CONFIG_COMEDI_DEBUG - printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor); - printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u " - "scan_begin_arg=%u\n", - dev->minor, cmd->convert_arg, cmd->scan_begin_arg); -#endif /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, @@ -592,20 +584,15 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_src == TRIG_NOW && cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + if (cmd->start_src == TRIG_NOW) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (!cmd->chanlist_len) - err++; + err |= -EINVAL; - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->chanlist_len == 1) minSamplPer = 1; @@ -622,28 +609,19 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, /* calc arg again */ tmp = steps / 30; - if (cmd->convert_arg != tmp) { - cmd->convert_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp); } if (cmd->scan_begin_src == TRIG_TIMER) - err++; + err |= -EINVAL; /* stop source */ switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; /* * TRIG_EXT doesn't care since it doesn't trigger @@ -682,8 +660,7 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev, #endif if (trignum != 0) { - printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid" - " trignum\n", dev->minor); + dev_err(dev->class_dev, "%s: invalid trignum\n", __func__); up(&udfs->sem); return -EINVAL; } @@ -691,16 +668,16 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev, udfs->ai_cmd_running = 1; ret = usbduxfastsub_submit_InURBs(udfs); if (ret < 0) { - printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: " - "urbSubmit: err=%d\n", dev->minor, ret); + dev_err(dev->class_dev, + "%s: urbSubmit: err=%d\n", __func__, ret); udfs->ai_cmd_running = 0; up(&udfs->sem); return ret; } s->async->inttrig = NULL; } else { - printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already" - " running\n", dev->minor); + dev_err(dev->class_dev, + "ai_inttrig but acqu is already running\n"); } up(&udfs->sem); return 1; @@ -738,8 +715,8 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, return -ENODEV; } if (udfs->ai_cmd_running) { - printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd" - " is running.\n", dev->minor); + dev_err(dev->class_dev, + "ai_cmd not possible. Another ai_cmd is running.\n"); up(&udfs->sem); return -EBUSY; } @@ -757,31 +734,29 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, for (i = 0; i < cmd->chanlist_len; ++i) { chan = CR_CHAN(cmd->chanlist[i]); if (chan != i) { - printk(KERN_ERR "comedi%d: cmd is accepting " - "only consecutive channels.\n", - dev->minor); + dev_err(dev->class_dev, + "cmd is accepting only consecutive channels.\n"); up(&udfs->sem); return -EINVAL; } if ((gain != CR_RANGE(cmd->chanlist[i])) && (cmd->chanlist_len > 3)) { - printk(KERN_ERR "comedi%d: the gain must be" - " the same for all channels.\n", - dev->minor); + dev_err(dev->class_dev, + "the gain must be the same for all channels.\n"); up(&udfs->sem); return -EINVAL; } if (i >= NUMCHANNELS) { - printk(KERN_ERR "comedi%d: channel list too" - " long\n", dev->minor); + dev_err(dev->class_dev, + "channel list too long\n"); break; } } } steps = 0; if (cmd->scan_begin_src == TRIG_TIMER) { - printk(KERN_ERR "comedi%d: usbduxfast: " - "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor); + dev_err(dev->class_dev, + "scan_begin_src==TRIG_TIMER not valid.\n"); up(&udfs->sem); return -EINVAL; } @@ -789,22 +764,21 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, steps = (cmd->convert_arg * 30) / 1000; if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) { - printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, " - "scan_begin_arg=%d. Not properly tested by cmdtest?\n", - dev->minor, steps, cmd->scan_begin_arg); + dev_err(dev->class_dev, + "ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", + steps, cmd->scan_begin_arg); up(&udfs->sem); return -EINVAL; } if (steps > MAX_SAMPLING_PERIOD) { - printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate " - "too low.\n", dev->minor); + dev_err(dev->class_dev, "ai_cmd: sampling rate too low.\n"); up(&udfs->sem); return -EINVAL; } if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1) && (cmd->chanlist_len != 16)) { - printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only" - " with 1 or 16 channels possible.\n", dev->minor); + dev_err(dev->class_dev, + "ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n"); up(&udfs->sem); return -EINVAL; } @@ -1121,8 +1095,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, break; default: - printk(KERN_ERR "comedi %d: unsupported combination of " - "channels\n", dev->minor); + dev_err(dev->class_dev, "unsupported combination of channels\n"); up(&udfs->sem); return -EFAULT; } @@ -1134,17 +1107,16 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, /* 0 means that the AD commands are sent */ result = send_dux_commands(udfs, SENDADCOMMANDS); if (result < 0) { - printk(KERN_ERR "comedi%d: adc command could not be submitted." - "Aborting...\n", dev->minor); + dev_err(dev->class_dev, + "adc command could not be submitted. Aborting...\n"); up(&udfs->sem); return result; } if (cmd->stop_src == TRIG_COUNT) { udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg; if (udfs->ai_sample_count < 1) { - printk(KERN_ERR "comedi%d: " - "(cmd->stop_arg)*(cmd->scan_end_arg)<1, " - "aborting.\n", dev->minor); + dev_err(dev->class_dev, + "(cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n"); up(&udfs->sem); return -EFAULT; } @@ -1193,8 +1165,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, udfs = dev->private; if (!udfs) { - printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n", - dev->minor); + dev_err(dev->class_dev, "%s: no usb dev.\n", __func__); return -ENODEV; } #ifdef CONFIG_COMEDI_DEBUG @@ -1207,8 +1178,8 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, return -ENODEV; } if (udfs->ai_cmd_running) { - printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async " - "Command is running.\n", dev->minor); + dev_err(dev->class_dev, + "ai_insn_read not possible. Async Command is running.\n"); up(&udfs->sem); return -EBUSY; } @@ -1268,8 +1239,8 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, /* 0 means that the AD commands are sent */ err = send_dux_commands(udfs, SENDADCOMMANDS); if (err < 0) { - printk(KERN_ERR "comedi%d: adc command could not be submitted." - "Aborting...\n", dev->minor); + dev_err(dev->class_dev, + "adc command could not be submitted. Aborting...\n"); up(&udfs->sem); return err; } @@ -1284,8 +1255,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, udfs->transfer_buffer, SIZEINBUF, &actual_length, 10000); if (err < 0) { - printk(KERN_ERR "comedi%d: insn timeout. No data.\n", - dev->minor); + dev_err(dev->class_dev, "insn timeout. No data.\n"); up(&udfs->sem); return err; } @@ -1297,15 +1267,13 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, udfs->transfer_buffer, SIZEINBUF, &actual_length, 10000); if (err < 0) { - printk(KERN_ERR "comedi%d: insn data error: %d\n", - dev->minor, err); + dev_err(dev->class_dev, "insn data error: %d\n", err); up(&udfs->sem); return err; } n = actual_length / sizeof(uint16_t); if ((n % 16) != 0) { - printk(KERN_ERR "comedi%d: insn data packet " - "corrupted.\n", dev->minor); + dev_err(dev->class_dev, "insn data packet corrupted.\n"); up(&udfs->sem); return -EINVAL; } @@ -1454,9 +1422,10 @@ static int usbduxfast_attach_common(struct comedi_device *dev, return 0; } -static int usbduxfast_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) +static int usbduxfast_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct usb_interface *uinterf = comedi_to_usb_interface(dev); int ret; struct usbduxfastsub_s *udfs; @@ -1465,11 +1434,11 @@ static int usbduxfast_attach_usb(struct comedi_device *dev, udfs = usb_get_intfdata(uinterf); if (!udfs || !udfs->probed) { dev_err(dev->class_dev, - "usbduxfast: error: attach_usb failed, not connected\n"); + "usbduxfast: error: auto_attach failed, not connected\n"); ret = -ENODEV; } else if (udfs->attached) { dev_err(dev->class_dev, - "usbduxfast: error: attach_usb failed, already attached\n"); + "usbduxfast: error: auto_attach failed, already attached\n"); ret = -ENODEV; } else ret = usbduxfast_attach_common(dev, udfs); @@ -1495,7 +1464,7 @@ static void usbduxfast_detach(struct comedi_device *dev) static struct comedi_driver usbduxfast_driver = { .driver_name = "usbduxfast", .module = THIS_MODULE, - .attach_usb = usbduxfast_attach_usb, + .auto_attach = usbduxfast_auto_attach, .detach = usbduxfast_detach, }; @@ -1535,8 +1504,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, int ret; if (udev->speed != USB_SPEED_HIGH) { - printk(KERN_ERR "comedi_: usbduxfast_: This driver needs" - "USB 2.0 to operate. Aborting...\n"); + dev_err(&uinterf->dev, + "This driver needs USB 2.0 to operate. Aborting...\n"); return -ENODEV; } #ifdef CONFIG_COMEDI_DEBUG @@ -1555,7 +1524,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, /* no more space */ if (index == -1) { - printk(KERN_ERR "Too many usbduxfast-devices connected.\n"); + dev_err(&uinterf->dev, + "Too many usbduxfast-devices connected.\n"); up(&start_stop_sem); return -EMFILE; } @@ -1586,8 +1556,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER, GFP_KERNEL); if (!usbduxfastsub[index].dux_commands) { - printk(KERN_ERR "comedi_: usbduxfast: error alloc space for " - "dac commands\n"); + dev_err(&uinterf->dev, + "error alloc space for dac commands\n"); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; @@ -1595,8 +1565,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, /* create space of the instruction buffer */ usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL); if (!usbduxfastsub[index].insnBuffer) { - printk(KERN_ERR "comedi_: usbduxfast: could not alloc space " - "for insnBuffer\n"); + dev_err(&uinterf->dev, + "could not alloc space for insnBuffer\n"); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; @@ -1605,24 +1575,25 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, i = usb_set_interface(usbduxfastsub[index].usbdev, usbduxfastsub[index].ifnum, 1); if (i < 0) { - printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to " - "alternate setting 1.\n", index); + dev_err(&uinterf->dev, + "usbduxfast%d: could not switch to alternate setting 1.\n", + index); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENODEV; } usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL); if (!usbduxfastsub[index].urbIn) { - printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc." - "urb\n", index); + dev_err(&uinterf->dev, + "usbduxfast%d: Could not alloc. urb\n", index); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; } usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL); if (!usbduxfastsub[index].transfer_buffer) { - printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. " - "transb.\n", index); + dev_err(&uinterf->dev, + "usbduxfast%d: could not alloc. transb.\n", index); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; @@ -1640,12 +1611,12 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, usbduxfast_firmware_request_complete_handler); if (ret) { - dev_err(&udev->dev, "could not load firmware (err=%d)\n", ret); + dev_err(&uinterf->dev, "could not load firmware (err=%d)\n", ret); return ret; } - printk(KERN_INFO "comedi_: usbduxfast%d has been successfully " - "initialized.\n", index); + dev_info(&uinterf->dev, + "usbduxfast%d has been successfully initialized.\n", index); /* success */ return 0; } @@ -1656,13 +1627,11 @@ static void usbduxfast_usb_disconnect(struct usb_interface *intf) struct usb_device *udev = interface_to_usbdev(intf); if (!udfs) { - printk(KERN_ERR "comedi_: usbduxfast: disconnect called with " - "null pointer.\n"); + dev_err(&intf->dev, "disconnect called with null pointer.\n"); return; } if (udfs->usbdev != udev) { - printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong " - "ptr!!!\n"); + dev_err(&intf->dev, "BUG! called with wrong ptr!!!\n"); return; } diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index b169412..cdd279b 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -904,9 +904,6 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (!(this_usbduxsub->probed)) return -ENODEV; - dev_dbg(&this_usbduxsub->interface->dev, - "comedi%d: usbdux_ai_cmdtest\n", dev->minor); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); @@ -928,19 +925,12 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { if (this_usbduxsub->high_speed) { @@ -951,51 +941,35 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, * are in the channel list the more time we need. */ i = chanToInterval(cmd->chanlist_len); - if (cmd->scan_begin_arg < (1000000 / 8 * i)) { - cmd->scan_begin_arg = 1000000 / 8 * i; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + (1000000 / 8 * i)); /* now calc the real sampling rate with all the * rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 125000)) * 125000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } else { /* full speed */ /* 1kHz scans every USB frame */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); /* * calc the real sampling rate with the rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 1000000)) * 1000000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, + tmpTimer); } - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -1576,57 +1550,30 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); - if (cmd->scan_begin_src == TRIG_TIMER) { - /* timer */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } - } /* not used now, is for later use */ - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < 125000) { - cmd->convert_arg = 125000; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000); - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } - dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, " - "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, " - "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src, - cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg); - if (err) return 3; @@ -2359,9 +2306,10 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, return 0; } -static int usbduxsigma_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) +static int usbduxsigma_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct usb_interface *uinterf = comedi_to_usb_interface(dev); int ret; struct usbduxsub *uds; @@ -2370,11 +2318,11 @@ static int usbduxsigma_attach_usb(struct comedi_device *dev, uds = usb_get_intfdata(uinterf); if (!uds || !uds->probed) { dev_err(dev->class_dev, - "usbduxsigma: error: attach_usb failed, not connected\n"); + "usbduxsigma: error: auto_attach failed, not connected\n"); ret = -ENODEV; } else if (uds->attached) { dev_err(dev->class_dev, - "usbduxsigma: error: attach_usb failed, already attached\n"); + "usbduxsigma: error: auto_attach failed, already attached\n"); ret = -ENODEV; } else ret = usbduxsigma_attach_common(dev, uds); @@ -2398,7 +2346,7 @@ static void usbduxsigma_detach(struct comedi_device *dev) static struct comedi_driver usbduxsigma_driver = { .driver_name = "usbduxsigma", .module = THIS_MODULE, - .attach_usb = usbduxsigma_attach_usb, + .auto_attach = usbduxsigma_auto_attach, .detach = usbduxsigma_detach, }; diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index df277aa..609dc69 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1209,9 +1209,10 @@ static int vmk80xx_attach(struct comedi_device *cdev, } /* called via comedi_usb_auto_config() */ -static int vmk80xx_attach_usb(struct comedi_device *cdev, - struct usb_interface *intf) +static int vmk80xx_auto_attach(struct comedi_device *cdev, + unsigned long context_unused) { + struct usb_interface *intf = comedi_to_usb_interface(cdev); int i; int ret; @@ -1246,7 +1247,7 @@ static struct comedi_driver vmk80xx_driver = { .driver_name = "vmk80xx", .attach = vmk80xx_attach, .detach = vmk80xx_detach, - .attach_usb = vmk80xx_attach_usb, + .auto_attach = vmk80xx_auto_attach, }; static int vmk80xx_usb_probe(struct usb_interface *intf, @@ -1371,12 +1372,11 @@ static int vmk80xx_usb_probe(struct usb_interface *intf, if (dev->board.model == VMK8061_MODEL) { vmk80xx_read_eeprom(dev, IC3_VERSION); - printk(KERN_INFO "comedi#: vmk80xx: %s\n", dev->fw.ic3_vers); + dev_info(&intf->dev, "%s\n", dev->fw.ic3_vers); if (vmk80xx_check_data_link(dev)) { vmk80xx_read_eeprom(dev, IC6_VERSION); - printk(KERN_INFO "comedi#: vmk80xx: %s\n", - dev->fw.ic6_vers); + dev_info(&intf->dev, "%s\n", dev->fw.ic6_vers); } else { dbgcm("comedi#: vmk80xx: no conn. to CPU\n"); } @@ -1387,8 +1387,8 @@ static int vmk80xx_usb_probe(struct usb_interface *intf, dev->probed = 1; - printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now attached\n", - dev->count, dev->board.name); + dev_info(&intf->dev, "board #%d [%s] now attached\n", + dev->count, dev->board.name); mutex_unlock(&glb_mutex); @@ -1422,8 +1422,8 @@ static void vmk80xx_usb_disconnect(struct usb_interface *intf) kfree(dev->usb_rx_buf); kfree(dev->usb_tx_buf); - printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now detached\n", - dev->count, dev->board.name); + dev_info(&intf->dev, "board #%d [%s] now detached\n", + dev->count, dev->board.name); up(&dev->limit_sem); mutex_unlock(&glb_mutex); diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 3f20ea5..4dc09a2 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -21,7 +21,6 @@ */ -#define __NO_VERSION__ #include <linux/module.h> #include <linux/errno.h> @@ -95,7 +94,8 @@ static int comedi_do_insn(struct comedi_device *dev, s = &dev->subdevices[insn->subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - printk(KERN_ERR "%d not useable subdevice\n", insn->subdev); + dev_err(dev->class_dev, + "%d not useable subdevice\n", insn->subdev); ret = -EIO; goto error; } @@ -104,7 +104,7 @@ static int comedi_do_insn(struct comedi_device *dev, ret = comedi_check_chanlist(s, 1, &insn->chanspec); if (ret < 0) { - printk(KERN_ERR "bad chanspec\n"); + dev_err(dev->class_dev, "bad chanspec\n"); ret = -EINVAL; goto error; } diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index bb7e70e..01acbe9 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -28,7 +28,6 @@ was cool. */ -#define __NO_VERSION__ #include "comedidev.h" #include "comedi_internal.h" #include <linux/proc_fs.h> |