diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c')
-rw-r--r-- | drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c | 181 |
1 files changed, 49 insertions, 132 deletions
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 8a613ae0acba..98de96953a29 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -1,28 +1,3 @@ -/* - * 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. - * - */ - -#define APCI1564_ADDRESS_RANGE 128 - /* Digital Input IRQ Function Selection */ #define APCI1564_DI_INT_OR (0 << 1) #define APCI1564_DI_INT_AND (1 << 1) @@ -32,10 +7,10 @@ #define APCI1564_DI_INT_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 +#define APCI1564_DO_VCC_INT_ENABLE 0x1 +#define APCI1564_DO_VCC_INT_DISABLE 0xfffffffe +#define APCI1564_DO_CC_INT_ENABLE 0x2 +#define APCI1564_DO_CC_INT_DISABLE 0xfffffffd /* TIMER COUNTER WATCHDOG DEFINES */ #define ADDIDATA_TIMER 0 @@ -76,55 +51,21 @@ #define APCI1564_TIMER_WARN_TIMEBASE_REG 0x64 /* - * dev>iobase Register Map + * dev->iobase Register Map */ -#define APCI1564_TCW_REG(x) (0x00 + ((x) * 0x20)) -#define APCI1564_TCW_RELOAD_REG(x) (0x04 + ((x) * 0x20)) -#define APCI1564_TCW_TIMEBASE_REG(x) (0x08 + ((x) * 0x20)) -#define APCI1564_TCW_CTRL_REG(x) (0x0c + ((x) * 0x20)) -#define APCI1564_TCW_STATUS_REG(x) (0x10 + ((x) * 0x20)) -#define APCI1564_TCW_IRQ_REG(x) (0x14 + ((x) * 0x20)) -#define APCI1564_TCW_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20)) -#define APCI1564_TCW_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20)) - -/* - * Configures The Digital Output Subdevice. - * - * data[1] 0 = Disable VCC Interrupt, 1 = Enable VCC Interrupt - * data[2] 0 = Disable CC Interrupt, 1 = Enable CC Interrupt - */ -static int apci1564_do_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci1564_private *devpriv = dev->private; - unsigned int ul_Command = 0; - - if ((data[0] != 0) && (data[0] != 1)) { - dev_err(dev->class_dev, "Data should be 1 or 0\n"); - return -EINVAL; - } - - if (data[1] == 1) - ul_Command = ul_Command | 0x1; - else - ul_Command = ul_Command & 0xFFFFFFFE; - - if (data[2] == 1) - ul_Command = ul_Command | 0x2; - else - ul_Command = ul_Command & 0xFFFFFFFD; - - outl(ul_Command, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG); - devpriv->tsk_current = current; - return insn->n; -} +#define APCI1564_COUNTER_REG(x) (0x00 + ((x) * 0x20)) +#define APCI1564_COUNTER_RELOAD_REG(x) (0x04 + ((x) * 0x20)) +#define APCI1564_COUNTER_TIMEBASE_REG(x) (0x08 + ((x) * 0x20)) +#define APCI1564_COUNTER_CTRL_REG(x) (0x0c + ((x) * 0x20)) +#define APCI1564_COUNTER_STATUS_REG(x) (0x10 + ((x) * 0x20)) +#define APCI1564_COUNTER_IRQ_REG(x) (0x14 + ((x) * 0x20)) +#define APCI1564_COUNTER_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20)) +#define APCI1564_COUNTER_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20)) /* - * Configures The Timer, Counter or Watchdog + * Configures The Timer or Counter * - * data[0] Configure as: 0 = Timer, 1 = Counter, 2 = Watchdog + * data[0] Configure as: 0 = Timer, 1 = Counter * data[1] 1 = Enable Interrupt, 0 = Disable Interrupt * data[2] Time Unit * data[3] Reload Value @@ -141,14 +82,7 @@ static int apci1564_timer_config(struct comedi_device *dev, unsigned int ul_Command1 = 0; devpriv->tsk_current = current; - if (data[0] == ADDIDATA_WATCHDOG) { - devpriv->timer_select_mode = ADDIDATA_WATCHDOG; - - /* Disable the watchdog */ - outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - /* Loading the Reload value */ - outl(data[3], devpriv->amcc_iobase + APCI1564_WDOG_RELOAD_REG); - } else if (data[0] == ADDIDATA_TIMER) { + if (data[0] == ADDIDATA_TIMER) { /* First Stop The Timer */ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; @@ -162,14 +96,14 @@ static int apci1564_timer_config(struct comedi_device *dev, outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG); outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER1)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER2)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER3)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER4)); } else { /* disable Timer interrupt */ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); @@ -190,13 +124,16 @@ static int apci1564_timer_config(struct comedi_device *dev, devpriv->mode_select_register = data[5]; /* First Stop The Counter */ - ul_Command1 = inl(dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + ul_Command1 = inl(dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; /* Stop The Timer */ - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); /* Set the reload value */ - outl(data[3], dev->iobase + APCI1564_TCW_RELOAD_REG(data[5] - 1)); + outl(data[3], dev->iobase + + APCI1564_COUNTER_RELOAD_REG(data[5] - 1)); /* Set the mode : */ /* - Disable the hardware */ @@ -209,26 +146,28 @@ static int apci1564_timer_config(struct comedi_device *dev, ul_Command1 = (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL | (unsigned int) ((unsigned int) data[4] << 16UL); - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); /* Enable or Disable Interrupt */ ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1); - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); /* Set the Up/Down selection */ ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18); - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); } else { dev_err(dev->class_dev, "Invalid subdevice.\n"); } - return insn->n; } /* - * Start / Stop The Selected Timer, Counter or Watchdog + * Start / Stop The Selected Timer or Counter * - * data[0] Configure as: 0 = Timer, 1 = Counter, 2 = Watchdog + * data[0] Configure as: 0 = Timer, 1 = Counter * data[1] 0 = Stop, 1 = Start, 2 = Trigger Clear (Only Counter) */ static int apci1564_timer_write(struct comedi_device *dev, @@ -239,23 +178,6 @@ static int apci1564_timer_write(struct comedi_device *dev, struct apci1564_private *devpriv = dev->private; unsigned int ul_Command1 = 0; - if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) { - switch (data[1]) { - case 0: /* stop the watchdog */ - /* disable the watchdog */ - outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - break; - case 1: /* start the watchdog */ - outl(0x0001, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - break; - case 2: /* Software trigger */ - outl(0x0201, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - break; - default: - dev_err(dev->class_dev, "Specified functionality does not exist.\n"); - return -EINVAL; - } - } if (devpriv->timer_select_mode == ADDIDATA_TIMER) { if (data[1] == 1) { ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); @@ -270,11 +192,10 @@ static int apci1564_timer_write(struct comedi_device *dev, ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); } - } - if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { + } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { ul_Command1 = inl(dev->iobase + - APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); if (data[1] == 1) { /* Start the Counter subdevice */ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; @@ -287,13 +208,15 @@ static int apci1564_timer_write(struct comedi_device *dev, ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400; } outl(ul_Command1, dev->iobase + - APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); + } else { + dev_err(dev->class_dev, "Invalid subdevice.\n"); } return insn->n; } /* - * Read The Selected Timer, Counter or Watchdog + * Read The Selected Timer or Counter */ static int apci1564_timer_read(struct comedi_device *dev, struct comedi_subdevice *s, @@ -303,11 +226,7 @@ static int apci1564_timer_read(struct comedi_device *dev, struct apci1564_private *devpriv = dev->private; unsigned int ul_Command1 = 0; - if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) { - /* Stores the status of the Watchdog */ - data[0] = inl(devpriv->amcc_iobase + APCI1564_WDOG_STATUS_REG) & 0x1; - data[1] = inl(devpriv->amcc_iobase + APCI1564_WDOG_REG); - } else if (devpriv->timer_select_mode == ADDIDATA_TIMER) { + if (devpriv->timer_select_mode == ADDIDATA_TIMER) { /* Stores the status of the Timer */ data[0] = inl(devpriv->amcc_iobase + APCI1564_TIMER_STATUS_REG) & 0x1; @@ -317,10 +236,10 @@ static int apci1564_timer_read(struct comedi_device *dev, /* Read the Counter Actual Value. */ data[0] = inl(dev->iobase + - APCI1564_TCW_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_REG(devpriv->mode_select_register - 1)); ul_Command1 = inl(dev->iobase + - APCI1564_TCW_STATUS_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_STATUS_REG(devpriv->mode_select_register - 1)); /* Get the software trigger status */ data[1] = (unsigned char) ((ul_Command1 >> 1) & 1); @@ -333,10 +252,8 @@ static int apci1564_timer_read(struct comedi_device *dev, /* Get the overflow status */ data[4] = (unsigned char) ((ul_Command1 >> 0) & 1); - } else if ((devpriv->timer_select_mode != ADDIDATA_TIMER) - && (devpriv->timer_select_mode != ADDIDATA_WATCHDOG) - && (devpriv->timer_select_mode != ADDIDATA_COUNTER)) { - dev_err(dev->class_dev, "Invalid Subdevice!\n"); + } else { + dev_err(dev->class_dev, "Invalid subdevice.\n"); } return insn->n; } |