cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

addi_apci_3120.c (30505B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * addi_apci_3120.c
      4 * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
      5 *
      6 *	ADDI-DATA GmbH
      7 *	Dieselstrasse 3
      8 *	D-77833 Ottersweier
      9 *	Tel: +19(0)7223/9493-0
     10 *	Fax: +49(0)7223/9493-92
     11 *	http://www.addi-data.com
     12 *	info@addi-data.com
     13 */
     14
     15#include <linux/module.h>
     16#include <linux/interrupt.h>
     17#include <linux/comedi/comedi_pci.h>
     18
     19#include "amcc_s5933.h"
     20
     21/*
     22 * PCI BAR 0 register map (devpriv->amcc)
     23 * see amcc_s5933.h for register and bit defines
     24 */
     25#define APCI3120_FIFO_ADVANCE_ON_BYTE_2		BIT(29)
     26
     27/*
     28 * PCI BAR 1 register map (dev->iobase)
     29 */
     30#define APCI3120_AI_FIFO_REG			0x00
     31#define APCI3120_CTRL_REG			0x00
     32#define APCI3120_CTRL_EXT_TRIG			BIT(15)
     33#define APCI3120_CTRL_GATE(x)			BIT(12 + (x))
     34#define APCI3120_CTRL_PR(x)			(((x) & 0xf) << 8)
     35#define APCI3120_CTRL_PA(x)			(((x) & 0xf) << 0)
     36#define APCI3120_AI_SOFTTRIG_REG		0x02
     37#define APCI3120_STATUS_REG			0x02
     38#define APCI3120_STATUS_EOC_INT			BIT(15)
     39#define APCI3120_STATUS_AMCC_INT		BIT(14)
     40#define APCI3120_STATUS_EOS_INT			BIT(13)
     41#define APCI3120_STATUS_TIMER2_INT		BIT(12)
     42#define APCI3120_STATUS_INT_MASK		(0xf << 12)
     43#define APCI3120_STATUS_TO_DI_BITS(x)		(((x) >> 8) & 0xf)
     44#define APCI3120_STATUS_TO_VERSION(x)		(((x) >> 4) & 0xf)
     45#define APCI3120_STATUS_FIFO_FULL		BIT(2)
     46#define APCI3120_STATUS_FIFO_EMPTY		BIT(1)
     47#define APCI3120_STATUS_DA_READY		BIT(0)
     48#define APCI3120_TIMER_REG			0x04
     49#define APCI3120_CHANLIST_REG			0x06
     50#define APCI3120_CHANLIST_INDEX(x)		(((x) & 0xf) << 8)
     51#define APCI3120_CHANLIST_UNIPOLAR		BIT(7)
     52#define APCI3120_CHANLIST_GAIN(x)		(((x) & 0x3) << 4)
     53#define APCI3120_CHANLIST_MUX(x)		(((x) & 0xf) << 0)
     54#define APCI3120_AO_REG(x)			(0x08 + (((x) / 4) * 2))
     55#define APCI3120_AO_MUX(x)			(((x) & 0x3) << 14)
     56#define APCI3120_AO_DATA(x)			((x) << 0)
     57#define APCI3120_TIMER_MODE_REG			0x0c
     58#define APCI3120_TIMER_MODE(_t, _m)		((_m) << ((_t) * 2))
     59#define APCI3120_TIMER_MODE0			0  /* I8254_MODE0 */
     60#define APCI3120_TIMER_MODE2			1  /* I8254_MODE2 */
     61#define APCI3120_TIMER_MODE4			2  /* I8254_MODE4 */
     62#define APCI3120_TIMER_MODE5			3  /* I8254_MODE5 */
     63#define APCI3120_TIMER_MODE_MASK(_t)		(3 << ((_t) * 2))
     64#define APCI3120_CTR0_REG			0x0d
     65#define APCI3120_CTR0_DO_BITS(x)		((x) << 4)
     66#define APCI3120_CTR0_TIMER_SEL(x)		((x) << 0)
     67#define APCI3120_MODE_REG			0x0e
     68#define APCI3120_MODE_TIMER2_CLK(x)		(((x) & 0x3) << 6)
     69#define APCI3120_MODE_TIMER2_CLK_OSC		APCI3120_MODE_TIMER2_CLK(0)
     70#define APCI3120_MODE_TIMER2_CLK_OUT1		APCI3120_MODE_TIMER2_CLK(1)
     71#define APCI3120_MODE_TIMER2_CLK_EOC		APCI3120_MODE_TIMER2_CLK(2)
     72#define APCI3120_MODE_TIMER2_CLK_EOS		APCI3120_MODE_TIMER2_CLK(3)
     73#define APCI3120_MODE_TIMER2_CLK_MASK		APCI3120_MODE_TIMER2_CLK(3)
     74#define APCI3120_MODE_TIMER2_AS(x)		(((x) & 0x3) << 4)
     75#define APCI3120_MODE_TIMER2_AS_TIMER		APCI3120_MODE_TIMER2_AS(0)
     76#define APCI3120_MODE_TIMER2_AS_COUNTER		APCI3120_MODE_TIMER2_AS(1)
     77#define APCI3120_MODE_TIMER2_AS_WDOG		APCI3120_MODE_TIMER2_AS(2)
     78#define APCI3120_MODE_TIMER2_AS_MASK		APCI3120_MODE_TIMER2_AS(3)
     79#define APCI3120_MODE_SCAN_ENA			BIT(3)
     80#define APCI3120_MODE_TIMER2_IRQ_ENA		BIT(2)
     81#define APCI3120_MODE_EOS_IRQ_ENA		BIT(1)
     82#define APCI3120_MODE_EOC_IRQ_ENA		BIT(0)
     83
     84/*
     85 * PCI BAR 2 register map (devpriv->addon)
     86 */
     87#define APCI3120_ADDON_ADDR_REG			0x00
     88#define APCI3120_ADDON_DATA_REG			0x02
     89#define APCI3120_ADDON_CTRL_REG			0x04
     90#define APCI3120_ADDON_CTRL_AMWEN_ENA		BIT(1)
     91#define APCI3120_ADDON_CTRL_A2P_FIFO_ENA	BIT(0)
     92
     93/*
     94 * Board revisions
     95 */
     96#define APCI3120_REVA				0xa
     97#define APCI3120_REVB				0xb
     98#define APCI3120_REVA_OSC_BASE			70	/* 70ns = 14.29MHz */
     99#define APCI3120_REVB_OSC_BASE			50	/* 50ns = 20MHz */
    100
    101static const struct comedi_lrange apci3120_ai_range = {
    102	8, {
    103		BIP_RANGE(10),
    104		BIP_RANGE(5),
    105		BIP_RANGE(2),
    106		BIP_RANGE(1),
    107		UNI_RANGE(10),
    108		UNI_RANGE(5),
    109		UNI_RANGE(2),
    110		UNI_RANGE(1)
    111	}
    112};
    113
    114enum apci3120_boardid {
    115	BOARD_APCI3120,
    116	BOARD_APCI3001,
    117};
    118
    119struct apci3120_board {
    120	const char *name;
    121	unsigned int ai_is_16bit:1;
    122	unsigned int has_ao:1;
    123};
    124
    125static const struct apci3120_board apci3120_boardtypes[] = {
    126	[BOARD_APCI3120] = {
    127		.name		= "apci3120",
    128		.ai_is_16bit	= 1,
    129		.has_ao		= 1,
    130	},
    131	[BOARD_APCI3001] = {
    132		.name		= "apci3001",
    133	},
    134};
    135
    136struct apci3120_dmabuf {
    137	unsigned short *virt;
    138	dma_addr_t hw;
    139	unsigned int size;
    140	unsigned int use_size;
    141};
    142
    143struct apci3120_private {
    144	unsigned long amcc;
    145	unsigned long addon;
    146	unsigned int osc_base;
    147	unsigned int use_dma:1;
    148	unsigned int use_double_buffer:1;
    149	unsigned int cur_dmabuf:1;
    150	struct apci3120_dmabuf dmabuf[2];
    151	unsigned char do_bits;
    152	unsigned char timer_mode;
    153	unsigned char mode;
    154	unsigned short ctrl;
    155};
    156
    157static void apci3120_addon_write(struct comedi_device *dev,
    158				 unsigned int val, unsigned int reg)
    159{
    160	struct apci3120_private *devpriv = dev->private;
    161
    162	/* 16-bit interface for AMCC add-on registers */
    163
    164	outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG);
    165	outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
    166
    167	outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG);
    168	outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
    169}
    170
    171static void apci3120_init_dma(struct comedi_device *dev,
    172			      struct apci3120_dmabuf *dmabuf)
    173{
    174	struct apci3120_private *devpriv = dev->private;
    175
    176	/* AMCC - enable transfer count and reset A2P FIFO */
    177	outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
    178	     devpriv->amcc + AMCC_OP_REG_AGCSTS);
    179
    180	/* Add-On - enable transfer count and reset A2P FIFO */
    181	apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
    182			     AMCC_OP_REG_AGCSTS);
    183
    184	/* AMCC - enable transfers and reset A2P flags */
    185	outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS,
    186	     devpriv->amcc + AMCC_OP_REG_MCSR);
    187
    188	/* Add-On - DMA start address */
    189	apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR);
    190
    191	/* Add-On - Number of acquisitions */
    192	apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC);
    193
    194	/* AMCC - enable write complete (DMA) and set FIFO advance */
    195	outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL,
    196	     devpriv->amcc + AMCC_OP_REG_INTCSR);
    197
    198	/* Add-On - enable DMA */
    199	outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA,
    200	     devpriv->addon + APCI3120_ADDON_CTRL_REG);
    201}
    202
    203static void apci3120_setup_dma(struct comedi_device *dev,
    204			       struct comedi_subdevice *s)
    205{
    206	struct apci3120_private *devpriv = dev->private;
    207	struct comedi_cmd *cmd = &s->async->cmd;
    208	struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
    209	struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
    210	unsigned int dmalen0 = dmabuf0->size;
    211	unsigned int dmalen1 = dmabuf1->size;
    212	unsigned int scan_bytes;
    213
    214	scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg);
    215
    216	if (cmd->stop_src == TRIG_COUNT) {
    217		/*
    218		 * Must we fill full first buffer? And must we fill
    219		 * full second buffer when first is once filled?
    220		 */
    221		if (dmalen0 > (cmd->stop_arg * scan_bytes))
    222			dmalen0 = cmd->stop_arg * scan_bytes;
    223		else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0))
    224			dmalen1 = cmd->stop_arg * scan_bytes - dmalen0;
    225	}
    226
    227	if (cmd->flags & CMDF_WAKE_EOS) {
    228		/* don't we want wake up every scan? */
    229		if (dmalen0 > scan_bytes) {
    230			dmalen0 = scan_bytes;
    231			if (cmd->scan_end_arg & 1)
    232				dmalen0 += 2;
    233		}
    234		if (dmalen1 > scan_bytes) {
    235			dmalen1 = scan_bytes;
    236			if (cmd->scan_end_arg & 1)
    237				dmalen1 -= 2;
    238			if (dmalen1 < 4)
    239				dmalen1 = 4;
    240		}
    241	} else {
    242		/* isn't output buff smaller that our DMA buff? */
    243		if (dmalen0 > s->async->prealloc_bufsz)
    244			dmalen0 = s->async->prealloc_bufsz;
    245		if (dmalen1 > s->async->prealloc_bufsz)
    246			dmalen1 = s->async->prealloc_bufsz;
    247	}
    248	dmabuf0->use_size = dmalen0;
    249	dmabuf1->use_size = dmalen1;
    250
    251	apci3120_init_dma(dev, dmabuf0);
    252}
    253
    254/*
    255 * There are three timers on the board. They all use the same base
    256 * clock with a fixed prescaler for each timer. The base clock used
    257 * depends on the board version and type.
    258 *
    259 * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns)
    260 * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns)
    261 * APCI-3001 boards OSC = 20MHz base clock (50ns)
    262 *
    263 * The prescalers for each timer are:
    264 * Timer 0 CLK = OSC/10
    265 * Timer 1 CLK = OSC/1000
    266 * Timer 2 CLK = OSC/1000
    267 */
    268static unsigned int apci3120_ns_to_timer(struct comedi_device *dev,
    269					 unsigned int timer,
    270					 unsigned int ns,
    271					 unsigned int flags)
    272{
    273	struct apci3120_private *devpriv = dev->private;
    274	unsigned int prescale = (timer == 0) ? 10 : 1000;
    275	unsigned int timer_base = devpriv->osc_base * prescale;
    276	unsigned int divisor;
    277
    278	switch (flags & CMDF_ROUND_MASK) {
    279	case CMDF_ROUND_UP:
    280		divisor = DIV_ROUND_UP(ns, timer_base);
    281		break;
    282	case CMDF_ROUND_DOWN:
    283		divisor = ns / timer_base;
    284		break;
    285	case CMDF_ROUND_NEAREST:
    286	default:
    287		divisor = DIV_ROUND_CLOSEST(ns, timer_base);
    288		break;
    289	}
    290
    291	if (timer == 2) {
    292		/* timer 2 is 24-bits */
    293		if (divisor > 0x00ffffff)
    294			divisor = 0x00ffffff;
    295	} else {
    296		/* timers 0 and 1 are 16-bits */
    297		if (divisor > 0xffff)
    298			divisor = 0xffff;
    299	}
    300	/* the timers require a minimum divisor of 2 */
    301	if (divisor < 2)
    302		divisor = 2;
    303
    304	return divisor;
    305}
    306
    307static void apci3120_clr_timer2_interrupt(struct comedi_device *dev)
    308{
    309	/* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
    310	inb(dev->iobase + APCI3120_CTR0_REG);
    311}
    312
    313static void apci3120_timer_write(struct comedi_device *dev,
    314				 unsigned int timer, unsigned int val)
    315{
    316	struct apci3120_private *devpriv = dev->private;
    317
    318	/* write 16-bit value to timer (lower 16-bits of timer 2) */
    319	outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
    320	     APCI3120_CTR0_TIMER_SEL(timer),
    321	     dev->iobase + APCI3120_CTR0_REG);
    322	outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG);
    323
    324	if (timer == 2) {
    325		/* write upper 16-bits to timer 2 */
    326		outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
    327		     APCI3120_CTR0_TIMER_SEL(timer + 1),
    328		     dev->iobase + APCI3120_CTR0_REG);
    329		outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG);
    330	}
    331}
    332
    333static unsigned int apci3120_timer_read(struct comedi_device *dev,
    334					unsigned int timer)
    335{
    336	struct apci3120_private *devpriv = dev->private;
    337	unsigned int val;
    338
    339	/* read 16-bit value from timer (lower 16-bits of timer 2) */
    340	outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
    341	     APCI3120_CTR0_TIMER_SEL(timer),
    342	     dev->iobase + APCI3120_CTR0_REG);
    343	val = inw(dev->iobase + APCI3120_TIMER_REG);
    344
    345	if (timer == 2) {
    346		/* read upper 16-bits from timer 2 */
    347		outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
    348		     APCI3120_CTR0_TIMER_SEL(timer + 1),
    349		     dev->iobase + APCI3120_CTR0_REG);
    350		val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16);
    351	}
    352
    353	return val;
    354}
    355
    356static void apci3120_timer_set_mode(struct comedi_device *dev,
    357				    unsigned int timer, unsigned int mode)
    358{
    359	struct apci3120_private *devpriv = dev->private;
    360
    361	devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer);
    362	devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode);
    363	outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG);
    364}
    365
    366static void apci3120_timer_enable(struct comedi_device *dev,
    367				  unsigned int timer, bool enable)
    368{
    369	struct apci3120_private *devpriv = dev->private;
    370
    371	if (enable)
    372		devpriv->ctrl |= APCI3120_CTRL_GATE(timer);
    373	else
    374		devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer);
    375	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
    376}
    377
    378static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable)
    379{
    380	struct apci3120_private *devpriv = dev->private;
    381
    382	if (enable)
    383		devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG;
    384	else
    385		devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG;
    386	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
    387}
    388
    389static void apci3120_set_chanlist(struct comedi_device *dev,
    390				  struct comedi_subdevice *s,
    391				  int n_chan, unsigned int *chanlist)
    392{
    393	struct apci3120_private *devpriv = dev->private;
    394	int i;
    395
    396	/* set chanlist for scan */
    397	for (i = 0; i < n_chan; i++) {
    398		unsigned int chan = CR_CHAN(chanlist[i]);
    399		unsigned int range = CR_RANGE(chanlist[i]);
    400		unsigned int val;
    401
    402		val = APCI3120_CHANLIST_MUX(chan) |
    403		      APCI3120_CHANLIST_GAIN(range) |
    404		      APCI3120_CHANLIST_INDEX(i);
    405
    406		if (comedi_range_is_unipolar(s, range))
    407			val |= APCI3120_CHANLIST_UNIPOLAR;
    408
    409		outw(val, dev->iobase + APCI3120_CHANLIST_REG);
    410	}
    411
    412	/* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
    413	inw(dev->iobase + APCI3120_TIMER_MODE_REG);
    414
    415	/* set scan length (PR) and scan start (PA) */
    416	devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0);
    417	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
    418
    419	/* enable chanlist scanning if necessary */
    420	if (n_chan > 1)
    421		devpriv->mode |= APCI3120_MODE_SCAN_ENA;
    422}
    423
    424static void apci3120_interrupt_dma(struct comedi_device *dev,
    425				   struct comedi_subdevice *s)
    426{
    427	struct apci3120_private *devpriv = dev->private;
    428	struct comedi_async *async = s->async;
    429	struct comedi_cmd *cmd = &async->cmd;
    430	struct apci3120_dmabuf *dmabuf;
    431	unsigned int nbytes;
    432	unsigned int nsamples;
    433
    434	dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
    435
    436	nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC);
    437
    438	if (nbytes < dmabuf->use_size)
    439		dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
    440	if (nbytes & 1) {
    441		dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
    442		async->events |= COMEDI_CB_ERROR;
    443		return;
    444	}
    445
    446	nsamples = comedi_bytes_to_samples(s, nbytes);
    447	if (nsamples) {
    448		comedi_buf_write_samples(s, dmabuf->virt, nsamples);
    449
    450		if (!(cmd->flags & CMDF_WAKE_EOS))
    451			async->events |= COMEDI_CB_EOS;
    452	}
    453
    454	if ((async->events & COMEDI_CB_CANCEL_MASK) ||
    455	    (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg))
    456		return;
    457
    458	if (devpriv->use_double_buffer) {
    459		/* switch DMA buffers for next interrupt */
    460		devpriv->cur_dmabuf = !devpriv->cur_dmabuf;
    461		dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
    462		apci3120_init_dma(dev, dmabuf);
    463	} else {
    464		/* restart DMA if not using double buffering */
    465		apci3120_init_dma(dev, dmabuf);
    466	}
    467}
    468
    469static irqreturn_t apci3120_interrupt(int irq, void *d)
    470{
    471	struct comedi_device *dev = d;
    472	struct apci3120_private *devpriv = dev->private;
    473	struct comedi_subdevice *s = dev->read_subdev;
    474	struct comedi_async *async = s->async;
    475	struct comedi_cmd *cmd = &async->cmd;
    476	unsigned int status;
    477	unsigned int int_amcc;
    478
    479	status = inw(dev->iobase + APCI3120_STATUS_REG);
    480	int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
    481
    482	if (!(status & APCI3120_STATUS_INT_MASK) &&
    483	    !(int_amcc & ANY_S593X_INT)) {
    484		dev_err(dev->class_dev, "IRQ from unknown source\n");
    485		return IRQ_NONE;
    486	}
    487
    488	outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR);
    489
    490	if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG)
    491		apci3120_exttrig_enable(dev, false);
    492
    493	if (int_amcc & MASTER_ABORT_INT)
    494		dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
    495	if (int_amcc & TARGET_ABORT_INT)
    496		dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
    497
    498	if ((status & APCI3120_STATUS_EOS_INT) &&
    499	    (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
    500		unsigned short val;
    501		int i;
    502
    503		for (i = 0; i < cmd->chanlist_len; i++) {
    504			val = inw(dev->iobase + APCI3120_AI_FIFO_REG);
    505			comedi_buf_write_samples(s, &val, 1);
    506		}
    507
    508		devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
    509		outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
    510	}
    511
    512	if (status & APCI3120_STATUS_TIMER2_INT) {
    513		/*
    514		 * for safety...
    515		 * timer2 interrupts are not enabled in the driver
    516		 */
    517		apci3120_clr_timer2_interrupt(dev);
    518	}
    519
    520	if (status & APCI3120_STATUS_AMCC_INT) {
    521		/* AMCC- Clear write complete interrupt (DMA) */
    522		outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
    523
    524		/* do some data transfer */
    525		apci3120_interrupt_dma(dev, s);
    526	}
    527
    528	if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
    529		async->events |= COMEDI_CB_EOA;
    530
    531	comedi_handle_events(dev, s);
    532
    533	return IRQ_HANDLED;
    534}
    535
    536static int apci3120_ai_cmd(struct comedi_device *dev,
    537			   struct comedi_subdevice *s)
    538{
    539	struct apci3120_private *devpriv = dev->private;
    540	struct comedi_cmd *cmd = &s->async->cmd;
    541	unsigned int divisor;
    542
    543	/* set default mode bits */
    544	devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
    545			APCI3120_MODE_TIMER2_AS_TIMER;
    546
    547	/* AMCC- Clear write complete interrupt (DMA) */
    548	outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
    549
    550	devpriv->cur_dmabuf = 0;
    551
    552	/* load chanlist for command scan */
    553	apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);
    554
    555	if (cmd->start_src == TRIG_EXT)
    556		apci3120_exttrig_enable(dev, true);
    557
    558	if (cmd->scan_begin_src == TRIG_TIMER) {
    559		/*
    560		 * Timer 1 is used in MODE2 (rate generator) to set the
    561		 * start time for each scan.
    562		 */
    563		divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
    564					       cmd->flags);
    565		apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);
    566		apci3120_timer_write(dev, 1, divisor);
    567	}
    568
    569	/*
    570	 * Timer 0 is used in MODE2 (rate generator) to set the conversion
    571	 * time for each acquisition.
    572	 */
    573	divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
    574	apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);
    575	apci3120_timer_write(dev, 0, divisor);
    576
    577	if (devpriv->use_dma)
    578		apci3120_setup_dma(dev, s);
    579	else
    580		devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
    581
    582	/* set mode to enable acquisition */
    583	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
    584
    585	if (cmd->scan_begin_src == TRIG_TIMER)
    586		apci3120_timer_enable(dev, 1, true);
    587	apci3120_timer_enable(dev, 0, true);
    588
    589	return 0;
    590}
    591
    592static int apci3120_ai_cmdtest(struct comedi_device *dev,
    593			       struct comedi_subdevice *s,
    594			       struct comedi_cmd *cmd)
    595{
    596	unsigned int arg;
    597	int err = 0;
    598
    599	/* Step 1 : check if triggers are trivially valid */
    600
    601	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
    602	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
    603					TRIG_TIMER | TRIG_FOLLOW);
    604	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
    605	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
    606	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
    607
    608	if (err)
    609		return 1;
    610
    611	/* Step 2a : make sure trigger sources are unique */
    612
    613	err |= comedi_check_trigger_is_unique(cmd->start_src);
    614	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
    615	err |= comedi_check_trigger_is_unique(cmd->stop_src);
    616
    617	/* Step 2b : and mutually compatible */
    618
    619	if (err)
    620		return 2;
    621
    622	/* Step 3: check if arguments are trivially valid */
    623
    624	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
    625
    626	if (cmd->scan_begin_src == TRIG_TIMER) {	/* Test Delay timing */
    627		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
    628						    100000);
    629	}
    630
    631	/* minimum conversion time per sample is 10us */
    632	err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
    633
    634	err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
    635	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
    636					   cmd->chanlist_len);
    637
    638	if (cmd->stop_src == TRIG_COUNT)
    639		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
    640	else	/*  TRIG_NONE */
    641		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
    642
    643	if (err)
    644		return 3;
    645
    646	/* Step 4: fix up any arguments */
    647
    648	if (cmd->scan_begin_src == TRIG_TIMER) {
    649		/* scan begin must be larger than the scan time */
    650		arg = cmd->convert_arg * cmd->scan_end_arg;
    651		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
    652	}
    653
    654	if (err)
    655		return 4;
    656
    657	/* Step 5: check channel list if it exists */
    658
    659	return 0;
    660}
    661
    662static int apci3120_cancel(struct comedi_device *dev,
    663			   struct comedi_subdevice *s)
    664{
    665	struct apci3120_private *devpriv = dev->private;
    666
    667	/* Add-On - disable DMA */
    668	outw(0, devpriv->addon + 4);
    669
    670	/* Add-On - disable bus master */
    671	apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS);
    672
    673	/* AMCC - disable bus master */
    674	outl(0, devpriv->amcc + AMCC_OP_REG_MCSR);
    675
    676	/* disable all counters, ext trigger, and reset scan */
    677	devpriv->ctrl = 0;
    678	outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
    679
    680	/* DISABLE_ALL_INTERRUPT */
    681	devpriv->mode = 0;
    682	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
    683
    684	inw(dev->iobase + APCI3120_STATUS_REG);
    685	devpriv->cur_dmabuf = 0;
    686
    687	return 0;
    688}
    689
    690static int apci3120_ai_eoc(struct comedi_device *dev,
    691			   struct comedi_subdevice *s,
    692			   struct comedi_insn *insn,
    693			   unsigned long context)
    694{
    695	unsigned int status;
    696
    697	status = inw(dev->iobase + APCI3120_STATUS_REG);
    698	if ((status & APCI3120_STATUS_EOC_INT) == 0)
    699		return 0;
    700	return -EBUSY;
    701}
    702
    703static int apci3120_ai_insn_read(struct comedi_device *dev,
    704				 struct comedi_subdevice *s,
    705				 struct comedi_insn *insn,
    706				 unsigned int *data)
    707{
    708	struct apci3120_private *devpriv = dev->private;
    709	unsigned int divisor;
    710	int ret;
    711	int i;
    712
    713	/* set mode for A/D conversions by software trigger with timer 0 */
    714	devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
    715			APCI3120_MODE_TIMER2_AS_TIMER;
    716	outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
    717
    718	/* load chanlist for single channel scan */
    719	apci3120_set_chanlist(dev, s, 1, &insn->chanspec);
    720
    721	/*
    722	 * Timer 0 is used in MODE4 (software triggered strobe) to set the
    723	 * conversion time for each acquisition. Each conversion is triggered
    724	 * when the divisor is written to the timer, The conversion is done
    725	 * when the EOC bit in the status register is '0'.
    726	 */
    727	apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4);
    728	apci3120_timer_enable(dev, 0, true);
    729
    730	/* fixed conversion time of 10 us */
    731	divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST);
    732
    733	for (i = 0; i < insn->n; i++) {
    734		/* trigger conversion */
    735		apci3120_timer_write(dev, 0, divisor);
    736
    737		ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0);
    738		if (ret)
    739			return ret;
    740
    741		data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG);
    742	}
    743
    744	return insn->n;
    745}
    746
    747static int apci3120_ao_ready(struct comedi_device *dev,
    748			     struct comedi_subdevice *s,
    749			     struct comedi_insn *insn,
    750			     unsigned long context)
    751{
    752	unsigned int status;
    753
    754	status = inw(dev->iobase + APCI3120_STATUS_REG);
    755	if (status & APCI3120_STATUS_DA_READY)
    756		return 0;
    757	return -EBUSY;
    758}
    759
    760static int apci3120_ao_insn_write(struct comedi_device *dev,
    761				  struct comedi_subdevice *s,
    762				  struct comedi_insn *insn,
    763				  unsigned int *data)
    764{
    765	unsigned int chan = CR_CHAN(insn->chanspec);
    766	int i;
    767
    768	for (i = 0; i < insn->n; i++) {
    769		unsigned int val = data[i];
    770		int ret;
    771
    772		ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
    773		if (ret)
    774			return ret;
    775
    776		outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
    777		     dev->iobase + APCI3120_AO_REG(chan));
    778
    779		s->readback[chan] = val;
    780	}
    781
    782	return insn->n;
    783}
    784
    785static int apci3120_di_insn_bits(struct comedi_device *dev,
    786				 struct comedi_subdevice *s,
    787				 struct comedi_insn *insn,
    788				 unsigned int *data)
    789{
    790	unsigned int status;
    791
    792	status = inw(dev->iobase + APCI3120_STATUS_REG);
    793	data[1] = APCI3120_STATUS_TO_DI_BITS(status);
    794
    795	return insn->n;
    796}
    797
    798static int apci3120_do_insn_bits(struct comedi_device *dev,
    799				 struct comedi_subdevice *s,
    800				 struct comedi_insn *insn,
    801				 unsigned int *data)
    802{
    803	struct apci3120_private *devpriv = dev->private;
    804
    805	if (comedi_dio_update_state(s, data)) {
    806		devpriv->do_bits = s->state;
    807		outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits),
    808		     dev->iobase + APCI3120_CTR0_REG);
    809	}
    810
    811	data[1] = s->state;
    812
    813	return insn->n;
    814}
    815
    816static int apci3120_timer_insn_config(struct comedi_device *dev,
    817				      struct comedi_subdevice *s,
    818				      struct comedi_insn *insn,
    819				      unsigned int *data)
    820{
    821	struct apci3120_private *devpriv = dev->private;
    822	unsigned int divisor;
    823	unsigned int status;
    824	unsigned int mode;
    825	unsigned int timer_mode;
    826
    827	switch (data[0]) {
    828	case INSN_CONFIG_ARM:
    829		apci3120_clr_timer2_interrupt(dev);
    830		divisor = apci3120_ns_to_timer(dev, 2, data[1],
    831					       CMDF_ROUND_DOWN);
    832		apci3120_timer_write(dev, 2, divisor);
    833		apci3120_timer_enable(dev, 2, true);
    834		break;
    835
    836	case INSN_CONFIG_DISARM:
    837		apci3120_timer_enable(dev, 2, false);
    838		apci3120_clr_timer2_interrupt(dev);
    839		break;
    840
    841	case INSN_CONFIG_GET_COUNTER_STATUS:
    842		data[1] = 0;
    843		data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
    844			  COMEDI_COUNTER_TERMINAL_COUNT;
    845
    846		if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) {
    847			data[1] |= COMEDI_COUNTER_ARMED;
    848			data[1] |= COMEDI_COUNTER_COUNTING;
    849		}
    850		status = inw(dev->iobase + APCI3120_STATUS_REG);
    851		if (status & APCI3120_STATUS_TIMER2_INT) {
    852			data[1] &= ~COMEDI_COUNTER_COUNTING;
    853			data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
    854		}
    855		break;
    856
    857	case INSN_CONFIG_SET_COUNTER_MODE:
    858		switch (data[1]) {
    859		case I8254_MODE0:
    860			mode = APCI3120_MODE_TIMER2_AS_COUNTER;
    861			timer_mode = APCI3120_TIMER_MODE0;
    862			break;
    863		case I8254_MODE2:
    864			mode = APCI3120_MODE_TIMER2_AS_TIMER;
    865			timer_mode = APCI3120_TIMER_MODE2;
    866			break;
    867		case I8254_MODE4:
    868			mode = APCI3120_MODE_TIMER2_AS_TIMER;
    869			timer_mode = APCI3120_TIMER_MODE4;
    870			break;
    871		case I8254_MODE5:
    872			mode = APCI3120_MODE_TIMER2_AS_WDOG;
    873			timer_mode = APCI3120_TIMER_MODE5;
    874			break;
    875		default:
    876			return -EINVAL;
    877		}
    878		apci3120_timer_enable(dev, 2, false);
    879		apci3120_clr_timer2_interrupt(dev);
    880		apci3120_timer_set_mode(dev, 2, timer_mode);
    881		devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK;
    882		devpriv->mode |= mode;
    883		outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
    884		break;
    885
    886	default:
    887		return -EINVAL;
    888	}
    889
    890	return insn->n;
    891}
    892
    893static int apci3120_timer_insn_read(struct comedi_device *dev,
    894				    struct comedi_subdevice *s,
    895				    struct comedi_insn *insn,
    896				    unsigned int *data)
    897{
    898	int i;
    899
    900	for (i = 0; i < insn->n; i++)
    901		data[i] = apci3120_timer_read(dev, 2);
    902
    903	return insn->n;
    904}
    905
    906static void apci3120_dma_alloc(struct comedi_device *dev)
    907{
    908	struct apci3120_private *devpriv = dev->private;
    909	struct apci3120_dmabuf *dmabuf;
    910	int order;
    911	int i;
    912
    913	for (i = 0; i < 2; i++) {
    914		dmabuf = &devpriv->dmabuf[i];
    915		for (order = 2; order >= 0; order--) {
    916			dmabuf->virt = dma_alloc_coherent(dev->hw_dev,
    917							  PAGE_SIZE << order,
    918							  &dmabuf->hw,
    919							  GFP_KERNEL);
    920			if (dmabuf->virt)
    921				break;
    922		}
    923		if (!dmabuf->virt)
    924			break;
    925		dmabuf->size = PAGE_SIZE << order;
    926
    927		if (i == 0)
    928			devpriv->use_dma = 1;
    929		if (i == 1)
    930			devpriv->use_double_buffer = 1;
    931	}
    932}
    933
    934static void apci3120_dma_free(struct comedi_device *dev)
    935{
    936	struct apci3120_private *devpriv = dev->private;
    937	struct apci3120_dmabuf *dmabuf;
    938	int i;
    939
    940	if (!devpriv)
    941		return;
    942
    943	for (i = 0; i < 2; i++) {
    944		dmabuf = &devpriv->dmabuf[i];
    945		if (dmabuf->virt) {
    946			dma_free_coherent(dev->hw_dev, dmabuf->size,
    947					  dmabuf->virt, dmabuf->hw);
    948		}
    949	}
    950}
    951
    952static void apci3120_reset(struct comedi_device *dev)
    953{
    954	/* disable all interrupt sources */
    955	outb(0, dev->iobase + APCI3120_MODE_REG);
    956
    957	/* disable all counters, ext trigger, and reset scan */
    958	outw(0, dev->iobase + APCI3120_CTRL_REG);
    959
    960	/* clear interrupt status */
    961	inw(dev->iobase + APCI3120_STATUS_REG);
    962}
    963
    964static int apci3120_auto_attach(struct comedi_device *dev,
    965				unsigned long context)
    966{
    967	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
    968	const struct apci3120_board *board = NULL;
    969	struct apci3120_private *devpriv;
    970	struct comedi_subdevice *s;
    971	unsigned int status;
    972	int ret;
    973
    974	if (context < ARRAY_SIZE(apci3120_boardtypes))
    975		board = &apci3120_boardtypes[context];
    976	if (!board)
    977		return -ENODEV;
    978	dev->board_ptr = board;
    979	dev->board_name = board->name;
    980
    981	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
    982	if (!devpriv)
    983		return -ENOMEM;
    984
    985	ret = comedi_pci_enable(dev);
    986	if (ret)
    987		return ret;
    988	pci_set_master(pcidev);
    989
    990	dev->iobase = pci_resource_start(pcidev, 1);
    991	devpriv->amcc = pci_resource_start(pcidev, 0);
    992	devpriv->addon = pci_resource_start(pcidev, 2);
    993
    994	apci3120_reset(dev);
    995
    996	if (pcidev->irq > 0) {
    997		ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
    998				  dev->board_name, dev);
    999		if (ret == 0) {
   1000			dev->irq = pcidev->irq;
   1001
   1002			apci3120_dma_alloc(dev);
   1003		}
   1004	}
   1005
   1006	status = inw(dev->iobase + APCI3120_STATUS_REG);
   1007	if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB ||
   1008	    context == BOARD_APCI3001)
   1009		devpriv->osc_base = APCI3120_REVB_OSC_BASE;
   1010	else
   1011		devpriv->osc_base = APCI3120_REVA_OSC_BASE;
   1012
   1013	ret = comedi_alloc_subdevices(dev, 5);
   1014	if (ret)
   1015		return ret;
   1016
   1017	/* Analog Input subdevice */
   1018	s = &dev->subdevices[0];
   1019	s->type		= COMEDI_SUBD_AI;
   1020	s->subdev_flags	= SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
   1021	s->n_chan	= 16;
   1022	s->maxdata	= board->ai_is_16bit ? 0xffff : 0x0fff;
   1023	s->range_table	= &apci3120_ai_range;
   1024	s->insn_read	= apci3120_ai_insn_read;
   1025	if (dev->irq) {
   1026		dev->read_subdev = s;
   1027		s->subdev_flags	|= SDF_CMD_READ;
   1028		s->len_chanlist	= s->n_chan;
   1029		s->do_cmdtest	= apci3120_ai_cmdtest;
   1030		s->do_cmd	= apci3120_ai_cmd;
   1031		s->cancel	= apci3120_cancel;
   1032	}
   1033
   1034	/* Analog Output subdevice */
   1035	s = &dev->subdevices[1];
   1036	if (board->has_ao) {
   1037		s->type		= COMEDI_SUBD_AO;
   1038		s->subdev_flags	= SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
   1039		s->n_chan	= 8;
   1040		s->maxdata	= 0x3fff;
   1041		s->range_table	= &range_bipolar10;
   1042		s->insn_write	= apci3120_ao_insn_write;
   1043
   1044		ret = comedi_alloc_subdev_readback(s);
   1045		if (ret)
   1046			return ret;
   1047	} else {
   1048		s->type		= COMEDI_SUBD_UNUSED;
   1049	}
   1050
   1051	/* Digital Input subdevice */
   1052	s = &dev->subdevices[2];
   1053	s->type		= COMEDI_SUBD_DI;
   1054	s->subdev_flags	= SDF_READABLE;
   1055	s->n_chan	= 4;
   1056	s->maxdata	= 1;
   1057	s->range_table	= &range_digital;
   1058	s->insn_bits	= apci3120_di_insn_bits;
   1059
   1060	/* Digital Output subdevice */
   1061	s = &dev->subdevices[3];
   1062	s->type		= COMEDI_SUBD_DO;
   1063	s->subdev_flags	= SDF_WRITABLE;
   1064	s->n_chan	= 4;
   1065	s->maxdata	= 1;
   1066	s->range_table	= &range_digital;
   1067	s->insn_bits	= apci3120_do_insn_bits;
   1068
   1069	/* Timer subdevice */
   1070	s = &dev->subdevices[4];
   1071	s->type		= COMEDI_SUBD_TIMER;
   1072	s->subdev_flags	= SDF_READABLE;
   1073	s->n_chan	= 1;
   1074	s->maxdata	= 0x00ffffff;
   1075	s->insn_config	= apci3120_timer_insn_config;
   1076	s->insn_read	= apci3120_timer_insn_read;
   1077
   1078	return 0;
   1079}
   1080
   1081static void apci3120_detach(struct comedi_device *dev)
   1082{
   1083	comedi_pci_detach(dev);
   1084	apci3120_dma_free(dev);
   1085}
   1086
   1087static struct comedi_driver apci3120_driver = {
   1088	.driver_name	= "addi_apci_3120",
   1089	.module		= THIS_MODULE,
   1090	.auto_attach	= apci3120_auto_attach,
   1091	.detach		= apci3120_detach,
   1092};
   1093
   1094static int apci3120_pci_probe(struct pci_dev *dev,
   1095			      const struct pci_device_id *id)
   1096{
   1097	return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
   1098}
   1099
   1100static const struct pci_device_id apci3120_pci_table[] = {
   1101	{ PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
   1102	{ PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
   1103	{ 0 }
   1104};
   1105MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
   1106
   1107static struct pci_driver apci3120_pci_driver = {
   1108	.name		= "addi_apci_3120",
   1109	.id_table	= apci3120_pci_table,
   1110	.probe		= apci3120_pci_probe,
   1111	.remove		= comedi_pci_auto_unconfig,
   1112};
   1113module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
   1114
   1115MODULE_AUTHOR("Comedi https://www.comedi.org");
   1116MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
   1117MODULE_LICENSE("GPL");