1bede729096e08172f1a52df91bee1202b17c5d92David Schleef/*
2bede729096e08172f1a52df91bee1202b17c5d92David Schleef    comedi/drivers/mite.c
3bede729096e08172f1a52df91bee1202b17c5d92David Schleef    Hardware driver for NI Mite PCI interface chip
4bede729096e08172f1a52df91bee1202b17c5d92David Schleef
5bede729096e08172f1a52df91bee1202b17c5d92David Schleef    COMEDI - Linux Control and Measurement Device Interface
6bede729096e08172f1a52df91bee1202b17c5d92David Schleef    Copyright (C) 1997-2002 David A. Schleef <ds@schleef.org>
7bede729096e08172f1a52df91bee1202b17c5d92David Schleef
8bede729096e08172f1a52df91bee1202b17c5d92David Schleef    This program is free software; you can redistribute it and/or modify
9bede729096e08172f1a52df91bee1202b17c5d92David Schleef    it under the terms of the GNU General Public License as published by
10bede729096e08172f1a52df91bee1202b17c5d92David Schleef    the Free Software Foundation; either version 2 of the License, or
11bede729096e08172f1a52df91bee1202b17c5d92David Schleef    (at your option) any later version.
12bede729096e08172f1a52df91bee1202b17c5d92David Schleef
13bede729096e08172f1a52df91bee1202b17c5d92David Schleef    This program is distributed in the hope that it will be useful,
14bede729096e08172f1a52df91bee1202b17c5d92David Schleef    but WITHOUT ANY WARRANTY; without even the implied warranty of
15bede729096e08172f1a52df91bee1202b17c5d92David Schleef    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16bede729096e08172f1a52df91bee1202b17c5d92David Schleef    GNU General Public License for more details.
17bede729096e08172f1a52df91bee1202b17c5d92David Schleef
18bede729096e08172f1a52df91bee1202b17c5d92David Schleef    You should have received a copy of the GNU General Public License
19bede729096e08172f1a52df91bee1202b17c5d92David Schleef    along with this program; if not, write to the Free Software
20bede729096e08172f1a52df91bee1202b17c5d92David Schleef    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21bede729096e08172f1a52df91bee1202b17c5d92David Schleef
22bede729096e08172f1a52df91bee1202b17c5d92David Schleef*/
23bede729096e08172f1a52df91bee1202b17c5d92David Schleef
24bede729096e08172f1a52df91bee1202b17c5d92David Schleef/*
25bede729096e08172f1a52df91bee1202b17c5d92David Schleef	The PCI-MIO E series driver was originally written by
26bede729096e08172f1a52df91bee1202b17c5d92David Schleef	Tomasz Motylewski <...>, and ported to comedi by ds.
27bede729096e08172f1a52df91bee1202b17c5d92David Schleef
28bede729096e08172f1a52df91bee1202b17c5d92David Schleef	References for specifications:
29bede729096e08172f1a52df91bee1202b17c5d92David Schleef
30bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   321747b.pdf  Register Level Programmer Manual (obsolete)
31bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   321747c.pdf  Register Level Programmer Manual (new)
32bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   DAQ-STC reference manual
33bede729096e08172f1a52df91bee1202b17c5d92David Schleef
34bede729096e08172f1a52df91bee1202b17c5d92David Schleef	Other possibly relevant info:
35bede729096e08172f1a52df91bee1202b17c5d92David Schleef
36bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   320517c.pdf  User manual (obsolete)
37bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   320517f.pdf  User manual (new)
38bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   320889a.pdf  delete
39bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   320906c.pdf  maximum signal ratings
40bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   321066a.pdf  about 16x
41bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   321791a.pdf  discontinuation of at-mio-16e-10 rev. c
42bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   321808a.pdf  about at-mio-16e-10 rev P
43bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   321837a.pdf  discontinuation of at-mio-16de-10 rev d
44bede729096e08172f1a52df91bee1202b17c5d92David Schleef	   321838a.pdf  about at-mio-16de-10 rev N
45bede729096e08172f1a52df91bee1202b17c5d92David Schleef
46bede729096e08172f1a52df91bee1202b17c5d92David Schleef	ISSUES:
47bede729096e08172f1a52df91bee1202b17c5d92David Schleef
48bede729096e08172f1a52df91bee1202b17c5d92David Schleef*/
49bede729096e08172f1a52df91bee1202b17c5d92David Schleef
50b6c777571b8d387d3add91170826f32a379e4313Bill Pemberton/* #define USE_KMALLOC */
51bede729096e08172f1a52df91bee1202b17c5d92David Schleef
52bede729096e08172f1a52df91bee1202b17c5d92David Schleef#include "mite.h"
53bede729096e08172f1a52df91bee1202b17c5d92David Schleef
54bede729096e08172f1a52df91bee1202b17c5d92David Schleef#include "comedi_fc.h"
55bede729096e08172f1a52df91bee1202b17c5d92David Schleef#include "comedi_pci.h"
56bede729096e08172f1a52df91bee1202b17c5d92David Schleef#include "../comedidev.h"
57bede729096e08172f1a52df91bee1202b17c5d92David Schleef
58bede729096e08172f1a52df91bee1202b17c5d92David Schleef
59bede729096e08172f1a52df91bee1202b17c5d92David Schleef#define PCI_MITE_SIZE		4096
60bede729096e08172f1a52df91bee1202b17c5d92David Schleef#define PCI_DAQ_SIZE		4096
61bede729096e08172f1a52df91bee1202b17c5d92David Schleef#define PCI_DAQ_SIZE_660X       8192
62bede729096e08172f1a52df91bee1202b17c5d92David Schleef
6351b713a684d403bd672b3e4cac55db43dc5cca2dBill Pembertonstruct mite_struct *mite_devices;
645256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_devices);
65bede729096e08172f1a52df91bee1202b17c5d92David Schleef
66bede729096e08172f1a52df91bee1202b17c5d92David Schleef#define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK)))
67bede729096e08172f1a52df91bee1202b17c5d92David Schleef
68bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_init(void)
69bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
7020fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy	struct pci_dev *pcidev = NULL;
71bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite;
72bede729096e08172f1a52df91bee1202b17c5d92David Schleef
7320fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy	for_each_pci_dev(pcidev) {
744e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman		if (pcidev->vendor == PCI_VENDOR_ID_NI) {
75bede729096e08172f1a52df91bee1202b17c5d92David Schleef			unsigned i;
76bede729096e08172f1a52df91bee1202b17c5d92David Schleef
77bede729096e08172f1a52df91bee1202b17c5d92David Schleef			mite = kzalloc(sizeof(*mite), GFP_KERNEL);
78bede729096e08172f1a52df91bee1202b17c5d92David Schleef			if (!mite) {
795256fb8818917d7c70b192dd11194a0126772bd1matt mooney				printk(KERN_ERR "mite: allocation failed\n");
80bede729096e08172f1a52df91bee1202b17c5d92David Schleef				pci_dev_put(pcidev);
81bede729096e08172f1a52df91bee1202b17c5d92David Schleef				return;
82bede729096e08172f1a52df91bee1202b17c5d92David Schleef			}
83bede729096e08172f1a52df91bee1202b17c5d92David Schleef			spin_lock_init(&mite->lock);
84bede729096e08172f1a52df91bee1202b17c5d92David Schleef			mite->pcidev = pci_dev_get(pcidev);
85bede729096e08172f1a52df91bee1202b17c5d92David Schleef			for (i = 0; i < MAX_MITE_DMA_CHANNELS; ++i) {
86bede729096e08172f1a52df91bee1202b17c5d92David Schleef				mite->channels[i].mite = mite;
87bede729096e08172f1a52df91bee1202b17c5d92David Schleef				mite->channels[i].channel = i;
88bede729096e08172f1a52df91bee1202b17c5d92David Schleef				mite->channels[i].done = 1;
89bede729096e08172f1a52df91bee1202b17c5d92David Schleef			}
90bede729096e08172f1a52df91bee1202b17c5d92David Schleef			mite->next = mite_devices;
91bede729096e08172f1a52df91bee1202b17c5d92David Schleef			mite_devices = mite;
92bede729096e08172f1a52df91bee1202b17c5d92David Schleef		}
93bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
94bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
95bede729096e08172f1a52df91bee1202b17c5d92David Schleef
96bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic void dump_chip_signature(u32 csigr_bits)
97bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
985256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_INFO "mite: version = %i, type = %i, mite mode = %i,"
995256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       "interface mode = %i\n",
1005256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits),
1015256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
1025256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_INFO "mite: num channels = %i, write post fifo depth = %i,"
1035256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       "wins = %i, iowins = %i\n",
1045256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits),
1055256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
106bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
107bede729096e08172f1a52df91bee1202b17c5d92David Schleef
108e473e9120b0a2d7252aca1ed9db5adadee36c0faBill Pembertonunsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
109bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
1100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	unsigned fcr_bits = readl(mite->mite_io_addr + MITE_FCR(channel));
111bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned empty_count = (fcr_bits >> 16) & 0xff;
112bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned full_count = fcr_bits & 0xff;
113bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return empty_count + full_count;
114bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
115bede729096e08172f1a52df91bee1202b17c5d92David Schleef
116bede729096e08172f1a52df91bee1202b17c5d92David Schleefint mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
117bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
118bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long length;
119bede729096e08172f1a52df91bee1202b17c5d92David Schleef	resource_size_t addr;
120bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int i;
121bede729096e08172f1a52df91bee1202b17c5d92David Schleef	u32 csigr_bits;
122bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned unknown_dma_burst_bits;
123bede729096e08172f1a52df91bee1202b17c5d92David Schleef
124bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (comedi_pci_enable(mite->pcidev, "mite")) {
1255256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_ERR "error enabling mite and requesting io regions\n");
126bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return -EIO;
127bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
128bede729096e08172f1a52df91bee1202b17c5d92David Schleef	pci_set_master(mite->pcidev);
129bede729096e08172f1a52df91bee1202b17c5d92David Schleef
130bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = pci_resource_start(mite->pcidev, 0);
131bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->mite_phys_addr = addr;
132bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->mite_io_addr = ioremap(addr, PCI_MITE_SIZE);
133bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (!mite->mite_io_addr) {
1345256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_ERR "Failed to remap mite io memory address\n");
135bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return -ENOMEM;
136bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
1375256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_INFO "MITE:0x%08llx mapped to %p ",
1380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       (unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);
139bede729096e08172f1a52df91bee1202b17c5d92David Schleef
140bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = pci_resource_start(mite->pcidev, 1);
141bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->daq_phys_addr = addr;
142bede729096e08172f1a52df91bee1202b17c5d92David Schleef	length = pci_resource_len(mite->pcidev, 1);
1435256fb8818917d7c70b192dd11194a0126772bd1matt mooney	/*
1445256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * In case of a 660x board, DAQ size is 8k instead of 4k
1455256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * (see as shown by lspci output)
1465256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 */
147bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
148bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (!mite->daq_io_addr) {
1495256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_ERR "Failed to remap daq io memory address\n");
150bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return -ENOMEM;
151bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
1525256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_INFO "DAQ:0x%08llx mapped to %p\n",
1530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       (unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);
154bede729096e08172f1a52df91bee1202b17c5d92David Schleef
155bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (use_iodwbsr_1) {
156bede729096e08172f1a52df91bee1202b17c5d92David Schleef		writel(0, mite->mite_io_addr + MITE_IODWBSR);
1575256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_INFO "mite: using I/O Window Base Size register 1\n");
1580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		writel(mite->daq_phys_addr | WENAB |
1590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       MITE_IODWBSR_1_WSIZE_bits(length),
1600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       mite->mite_io_addr + MITE_IODWBSR_1);
161bede729096e08172f1a52df91bee1202b17c5d92David Schleef		writel(0, mite->mite_io_addr + MITE_IODWCR_1);
162bede729096e08172f1a52df91bee1202b17c5d92David Schleef	} else {
163bede729096e08172f1a52df91bee1202b17c5d92David Schleef		writel(mite->daq_phys_addr | WENAB,
1640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       mite->mite_io_addr + MITE_IODWBSR);
165bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
1665256fb8818917d7c70b192dd11194a0126772bd1matt mooney	/*
1675256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * make sure dma bursts work. I got this from running a bus analyzer
1685256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * on a pxi-6281 and a pxi-6713. 6713 powered up with register value
1695256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * of 0x61f and bursts worked. 6281 powered up with register value of
1705256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * 0x1f and bursts didn't work. The NI windows driver reads the
1715256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * register, then does a bitwise-or of 0x600 with it and writes it back.
172bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 */
173bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unknown_dma_burst_bits =
1740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
175bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS;
176bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(unknown_dma_burst_bits,
1770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
178bede729096e08172f1a52df91bee1202b17c5d92David Schleef
179bede729096e08172f1a52df91bee1202b17c5d92David Schleef	csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
180bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->num_channels = mite_csigr_dmac(csigr_bits);
181bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
1825256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_WARNING "mite: bug? chip claims to have %i dma "
1835256fb8818917d7c70b192dd11194a0126772bd1matt mooney		       "channels. Setting to %i.\n",
1845256fb8818917d7c70b192dd11194a0126772bd1matt mooney		       mite->num_channels, MAX_MITE_DMA_CHANNELS);
185bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite->num_channels = MAX_MITE_DMA_CHANNELS;
186bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
187bede729096e08172f1a52df91bee1202b17c5d92David Schleef	dump_chip_signature(csigr_bits);
188bede729096e08172f1a52df91bee1202b17c5d92David Schleef	for (i = 0; i < mite->num_channels; i++) {
189bede729096e08172f1a52df91bee1202b17c5d92David Schleef		writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i));
190bede729096e08172f1a52df91bee1202b17c5d92David Schleef		/* disable interrupts */
191bede729096e08172f1a52df91bee1202b17c5d92David Schleef		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
1920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
1930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
1940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       mite->mite_io_addr + MITE_CHCR(i));
195bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
196bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->fifo_size = mite_fifo_size(mite, 0);
1975256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_INFO "mite: fifo size is %i.\n", mite->fifo_size);
198bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->used = 1;
199bede729096e08172f1a52df91bee1202b17c5d92David Schleef
200bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return 0;
201bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
2025256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_setup2);
203bede729096e08172f1a52df91bee1202b17c5d92David Schleef
204bede729096e08172f1a52df91bee1202b17c5d92David Schleefint mite_setup(struct mite_struct *mite)
205bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
206bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return mite_setup2(mite, 0);
207bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
2085256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_setup);
209bede729096e08172f1a52df91bee1202b17c5d92David Schleef
210bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_cleanup(void)
211bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
212bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite, *next;
213bede729096e08172f1a52df91bee1202b17c5d92David Schleef
214bede729096e08172f1a52df91bee1202b17c5d92David Schleef	for (mite = mite_devices; mite; mite = next) {
215bede729096e08172f1a52df91bee1202b17c5d92David Schleef		pci_dev_put(mite->pcidev);
216bede729096e08172f1a52df91bee1202b17c5d92David Schleef		next = mite->next;
217bede729096e08172f1a52df91bee1202b17c5d92David Schleef		kfree(mite);
218bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
219bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
220bede729096e08172f1a52df91bee1202b17c5d92David Schleef
221bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_unsetup(struct mite_struct *mite)
222bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
223b6c777571b8d387d3add91170826f32a379e4313Bill Pemberton	/* unsigned long offset, start, length; */
224bede729096e08172f1a52df91bee1202b17c5d92David Schleef
225bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (!mite)
226bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return;
227bede729096e08172f1a52df91bee1202b17c5d92David Schleef
228bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (mite->mite_io_addr) {
229bede729096e08172f1a52df91bee1202b17c5d92David Schleef		iounmap(mite->mite_io_addr);
230bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite->mite_io_addr = NULL;
231bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
232bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (mite->daq_io_addr) {
233bede729096e08172f1a52df91bee1202b17c5d92David Schleef		iounmap(mite->daq_io_addr);
234bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite->daq_io_addr = NULL;
235bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
236bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (mite->mite_phys_addr) {
237bede729096e08172f1a52df91bee1202b17c5d92David Schleef		comedi_pci_disable(mite->pcidev);
238bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite->mite_phys_addr = 0;
239bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
240bede729096e08172f1a52df91bee1202b17c5d92David Schleef
241bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite->used = 0;
242bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
2435256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_unsetup);
244bede729096e08172f1a52df91bee1202b17c5d92David Schleef
245bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_list_devices(void)
246bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
247bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite, *next;
248bede729096e08172f1a52df91bee1202b17c5d92David Schleef
2495256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_INFO "Available NI device IDs:");
250bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (mite_devices)
251bede729096e08172f1a52df91bee1202b17c5d92David Schleef		for (mite = mite_devices; mite; mite = next) {
252bede729096e08172f1a52df91bee1202b17c5d92David Schleef			next = mite->next;
2535256fb8818917d7c70b192dd11194a0126772bd1matt mooney			printk(KERN_INFO " 0x%04x", mite_device_id(mite));
254bede729096e08172f1a52df91bee1202b17c5d92David Schleef			if (mite->used)
2555256fb8818917d7c70b192dd11194a0126772bd1matt mooney				printk(KERN_INFO "(used)");
256bede729096e08172f1a52df91bee1202b17c5d92David Schleef		}
2575256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_INFO "\n");
258bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
2595256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_list_devices);
260bede729096e08172f1a52df91bee1202b17c5d92David Schleef
261bede729096e08172f1a52df91bee1202b17c5d92David Schleefstruct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
2620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral						   struct
2630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral						   mite_dma_descriptor_ring
2640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral						   *ring, unsigned min_channel,
2650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral						   unsigned max_channel)
266bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
267bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int i;
268bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long flags;
269bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_channel *channel = NULL;
270bede729096e08172f1a52df91bee1202b17c5d92David Schleef
2715256fb8818917d7c70b192dd11194a0126772bd1matt mooney	/* spin lock so mite_release_channel can be called safely
2725256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * from interrupts
2735256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 */
2745f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&mite->lock, flags);
275bede729096e08172f1a52df91bee1202b17c5d92David Schleef	for (i = min_channel; i <= max_channel; ++i) {
276bede729096e08172f1a52df91bee1202b17c5d92David Schleef		if (mite->channel_allocated[i] == 0) {
277bede729096e08172f1a52df91bee1202b17c5d92David Schleef			mite->channel_allocated[i] = 1;
278bede729096e08172f1a52df91bee1202b17c5d92David Schleef			channel = &mite->channels[i];
279bede729096e08172f1a52df91bee1202b17c5d92David Schleef			channel->ring = ring;
280bede729096e08172f1a52df91bee1202b17c5d92David Schleef			break;
281bede729096e08172f1a52df91bee1202b17c5d92David Schleef		}
282bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
2835f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&mite->lock, flags);
284bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return channel;
285bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
2865256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_request_channel_in_range);
287bede729096e08172f1a52df91bee1202b17c5d92David Schleef
288bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_release_channel(struct mite_channel *mite_chan)
289bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
290bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
291bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long flags;
292bede729096e08172f1a52df91bee1202b17c5d92David Schleef
293b6c777571b8d387d3add91170826f32a379e4313Bill Pemberton	/*  spin lock to prevent races with mite_request_channel */
2945f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&mite->lock, flags);
295bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (mite->channel_allocated[mite_chan->channel]) {
296bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite_dma_disarm(mite_chan);
297bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite_dma_reset(mite_chan);
2985256fb8818917d7c70b192dd11194a0126772bd1matt mooney	/*
2995256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * disable all channel's interrupts (do it after disarm/reset so
3005256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * MITE_CHCR reg isn't changed while dma is still active!)
3015256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 */
302bede729096e08172f1a52df91bee1202b17c5d92David Schleef		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE |
3030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE |
3040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
3050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
3060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
307bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite->channel_allocated[mite_chan->channel] = 0;
308bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite_chan->ring = NULL;
309bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mmiowb();
310bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
3115f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&mite->lock, flags);
312bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
3135256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_release_channel);
314bede729096e08172f1a52df91bee1202b17c5d92David Schleef
315bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_dma_arm(struct mite_channel *mite_chan)
316bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
317bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
318bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int chor;
319bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long flags;
320bede729096e08172f1a52df91bee1202b17c5d92David Schleef
321bede729096e08172f1a52df91bee1202b17c5d92David Schleef	MDPRINTK("mite_dma_arm ch%i\n", channel);
3225256fb8818917d7c70b192dd11194a0126772bd1matt mooney	/*
3235256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * memory barrier is intended to insure any twiddling with the buffer
3245256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * is done before writing to the mite to arm dma transfer
3255256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 */
326bede729096e08172f1a52df91bee1202b17c5d92David Schleef	smp_mb();
327bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* arm */
328bede729096e08172f1a52df91bee1202b17c5d92David Schleef	chor = CHOR_START;
3295f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&mite->lock, flags);
330bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_chan->done = 0;
331bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
332bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mmiowb();
3335f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&mite->lock, flags);
334b6c777571b8d387d3add91170826f32a379e4313Bill Pemberton/*       mite_dma_tcr(mite, channel); */
335bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
3365256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_dma_arm);
337bede729096e08172f1a52df91bee1202b17c5d92David Schleef
338bede729096e08172f1a52df91bee1202b17c5d92David Schleef/**************************************/
339bede729096e08172f1a52df91bee1202b17c5d92David Schleef
3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralint mite_buf_change(struct mite_dma_descriptor_ring *ring,
3410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    struct comedi_async *async)
342bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
343bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned int n_links;
344bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int i;
345bede729096e08172f1a52df91bee1202b17c5d92David Schleef
346bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (ring->descriptors) {
347bede729096e08172f1a52df91bee1202b17c5d92David Schleef		dma_free_coherent(ring->hw_dev,
3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				  ring->n_links *
3490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				  sizeof(struct mite_dma_descriptor),
3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				  ring->descriptors,
3510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				  ring->descriptors_dma_addr);
352bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
353bede729096e08172f1a52df91bee1202b17c5d92David Schleef	ring->descriptors = NULL;
354bede729096e08172f1a52df91bee1202b17c5d92David Schleef	ring->descriptors_dma_addr = 0;
355bede729096e08172f1a52df91bee1202b17c5d92David Schleef	ring->n_links = 0;
356bede729096e08172f1a52df91bee1202b17c5d92David Schleef
35782675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton	if (async->prealloc_bufsz == 0)
358bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return 0;
35982675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton
360bede729096e08172f1a52df91bee1202b17c5d92David Schleef	n_links = async->prealloc_bufsz >> PAGE_SHIFT;
361bede729096e08172f1a52df91bee1202b17c5d92David Schleef
362bede729096e08172f1a52df91bee1202b17c5d92David Schleef	MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links);
363bede729096e08172f1a52df91bee1202b17c5d92David Schleef
364bede729096e08172f1a52df91bee1202b17c5d92David Schleef	ring->descriptors =
3650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    dma_alloc_coherent(ring->hw_dev,
3660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       n_links * sizeof(struct mite_dma_descriptor),
3670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       &ring->descriptors_dma_addr, GFP_KERNEL);
368bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (!ring->descriptors) {
3695256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_ERR "mite: ring buffer allocation failed\n");
370bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return -ENOMEM;
371bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
372bede729096e08172f1a52df91bee1202b17c5d92David Schleef	ring->n_links = n_links;
373bede729096e08172f1a52df91bee1202b17c5d92David Schleef
374bede729096e08172f1a52df91bee1202b17c5d92David Schleef	for (i = 0; i < n_links; i++) {
375bede729096e08172f1a52df91bee1202b17c5d92David Schleef		ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE);
376bede729096e08172f1a52df91bee1202b17c5d92David Schleef		ring->descriptors[i].addr =
3770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    cpu_to_le32(async->buf_page_list[i].dma_addr);
378bede729096e08172f1a52df91bee1202b17c5d92David Schleef		ring->descriptors[i].next =
3790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    cpu_to_le32(ring->descriptors_dma_addr + (i +
3800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							      1) *
3810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				sizeof(struct mite_dma_descriptor));
382bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
383bede729096e08172f1a52df91bee1202b17c5d92David Schleef	ring->descriptors[n_links - 1].next =
3840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    cpu_to_le32(ring->descriptors_dma_addr);
3855256fb8818917d7c70b192dd11194a0126772bd1matt mooney	/*
3865256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * barrier is meant to insure that all the writes to the dma descriptors
3875256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * have completed before the dma controller is commanded to read them
3885256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 */
389bede729096e08172f1a52df91bee1202b17c5d92David Schleef	smp_wmb();
390bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return 0;
391bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
3925256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_buf_change);
393bede729096e08172f1a52df91bee1202b17c5d92David Schleef
394bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_prep_dma(struct mite_channel *mite_chan,
3950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		   unsigned int num_device_bits, unsigned int num_memory_bits)
396bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
397bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned int chor, chcr, mcr, dcr, lkcr;
398bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
399bede729096e08172f1a52df91bee1202b17c5d92David Schleef
400bede729096e08172f1a52df91bee1202b17c5d92David Schleef	MDPRINTK("mite_prep_dma ch%i\n", mite_chan->channel);
401bede729096e08172f1a52df91bee1202b17c5d92David Schleef
402bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* reset DMA and FIFO */
403bede729096e08172f1a52df91bee1202b17c5d92David Schleef	chor = CHOR_DMARESET | CHOR_FRESET;
404bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
405bede729096e08172f1a52df91bee1202b17c5d92David Schleef
406bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* short link chaining mode */
407bede729096e08172f1a52df91bee1202b17c5d92David Schleef	chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE |
4080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    CHCR_BURSTEN;
409bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/*
410bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 * Link Complete Interrupt: interrupt every time a link
411bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 * in MITE_RING is completed. This can generate a lot of
412bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 * extra interrupts, but right now we update the values
4135256fb8818917d7c70b192dd11194a0126772bd1matt mooney	 * of buf_int_ptr and buf_int_count at each interrupt. A
414bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 * better method is to poll the MITE before each user
415bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 * "read()" to calculate the number of bytes available.
416bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 */
417bede729096e08172f1a52df91bee1202b17c5d92David Schleef	chcr |= CHCR_SET_LC_IE;
418bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (num_memory_bits == 32 && num_device_bits == 16) {
4195256fb8818917d7c70b192dd11194a0126772bd1matt mooney		/*
4205256fb8818917d7c70b192dd11194a0126772bd1matt mooney		 * Doing a combined 32 and 16 bit byteswap gets the 16 bit
4215256fb8818917d7c70b192dd11194a0126772bd1matt mooney		 * samples into the fifo in the right order. Tested doing 32 bit
4225256fb8818917d7c70b192dd11194a0126772bd1matt mooney		 * memory to 16 bit device transfers to the analog out of a
4235256fb8818917d7c70b192dd11194a0126772bd1matt mooney		 * pxi-6281, which has mite version = 1, type = 4. This also
4245256fb8818917d7c70b192dd11194a0126772bd1matt mooney		 * works for dma reads from the counters on e-series boards.
4255256fb8818917d7c70b192dd11194a0126772bd1matt mooney		 */
426bede729096e08172f1a52df91bee1202b17c5d92David Schleef		chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
427bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
42882675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton	if (mite_chan->dir == COMEDI_INPUT)
429bede729096e08172f1a52df91bee1202b17c5d92David Schleef		chcr |= CHCR_DEV_TO_MEM;
43082675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton
431bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(chcr, mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
432bede729096e08172f1a52df91bee1202b17c5d92David Schleef
433bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* to/from memory */
434bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mcr = CR_RL(64) | CR_ASEQUP;
435bede729096e08172f1a52df91bee1202b17c5d92David Schleef	switch (num_memory_bits) {
436bede729096e08172f1a52df91bee1202b17c5d92David Schleef	case 8:
437bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mcr |= CR_PSIZE8;
438bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
439bede729096e08172f1a52df91bee1202b17c5d92David Schleef	case 16:
440bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mcr |= CR_PSIZE16;
441bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
442bede729096e08172f1a52df91bee1202b17c5d92David Schleef	case 32:
443bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mcr |= CR_PSIZE32;
444bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
445bede729096e08172f1a52df91bee1202b17c5d92David Schleef	default:
4465256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_WARNING "mite: bug! invalid mem bit width for dma "
4475256fb8818917d7c70b192dd11194a0126772bd1matt mooney		       "transfer\n");
448bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
449bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
450bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel));
451bede729096e08172f1a52df91bee1202b17c5d92David Schleef
452bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* from/to device */
453bede729096e08172f1a52df91bee1202b17c5d92David Schleef	dcr = CR_RL(64) | CR_ASEQUP;
454bede729096e08172f1a52df91bee1202b17c5d92David Schleef	dcr |= CR_PORTIO | CR_AMDEVICE | CR_REQSDRQ(mite_chan->channel);
455bede729096e08172f1a52df91bee1202b17c5d92David Schleef	switch (num_device_bits) {
456bede729096e08172f1a52df91bee1202b17c5d92David Schleef	case 8:
457bede729096e08172f1a52df91bee1202b17c5d92David Schleef		dcr |= CR_PSIZE8;
458bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
459bede729096e08172f1a52df91bee1202b17c5d92David Schleef	case 16:
460bede729096e08172f1a52df91bee1202b17c5d92David Schleef		dcr |= CR_PSIZE16;
461bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
462bede729096e08172f1a52df91bee1202b17c5d92David Schleef	case 32:
463bede729096e08172f1a52df91bee1202b17c5d92David Schleef		dcr |= CR_PSIZE32;
464bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
465bede729096e08172f1a52df91bee1202b17c5d92David Schleef	default:
4665256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_WARNING "mite: bug! invalid dev bit width for dma "
4675256fb8818917d7c70b192dd11194a0126772bd1matt mooney		       "transfer\n");
468bede729096e08172f1a52df91bee1202b17c5d92David Schleef		break;
469bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
470bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel));
471bede729096e08172f1a52df91bee1202b17c5d92David Schleef
472bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* reset the DAR */
473bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(0, mite->mite_io_addr + MITE_DAR(mite_chan->channel));
474bede729096e08172f1a52df91bee1202b17c5d92David Schleef
475bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* the link is 32bits */
476bede729096e08172f1a52df91bee1202b17c5d92David Schleef	lkcr = CR_RL(64) | CR_ASEQUP | CR_PSIZE32;
477bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(lkcr, mite->mite_io_addr + MITE_LKCR(mite_chan->channel));
478bede729096e08172f1a52df91bee1202b17c5d92David Schleef
479bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* starting address for link chaining */
480bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(mite_chan->ring->descriptors_dma_addr,
4810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
482bede729096e08172f1a52df91bee1202b17c5d92David Schleef
483bede729096e08172f1a52df91bee1202b17c5d92David Schleef	MDPRINTK("exit mite_prep_dma\n");
484bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
4855256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_prep_dma);
486bede729096e08172f1a52df91bee1202b17c5d92David Schleef
487bede729096e08172f1a52df91bee1202b17c5d92David Schleefu32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
488bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
489bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
490bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
491bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
492bede729096e08172f1a52df91bee1202b17c5d92David Schleef
4935256fb8818917d7c70b192dd11194a0126772bd1matt mooneyu32 mite_bytes_in_transit(struct mite_channel *mite_chan)
494bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
495bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
496bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return readl(mite->mite_io_addr +
4970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     MITE_FCR(mite_chan->channel)) & 0x000000FF;
498bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
4995256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_bytes_in_transit);
500bede729096e08172f1a52df91bee1202b17c5d92David Schleef
5015256fb8818917d7c70b192dd11194a0126772bd1matt mooney/* returns lower bound for number of bytes transferred from device to memory */
5025256fb8818917d7c70b192dd11194a0126772bd1matt mooneyu32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
503bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
504bede729096e08172f1a52df91bee1202b17c5d92David Schleef	u32 device_byte_count;
505bede729096e08172f1a52df91bee1202b17c5d92David Schleef
506bede729096e08172f1a52df91bee1202b17c5d92David Schleef	device_byte_count = mite_device_bytes_transferred(mite_chan);
507bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return device_byte_count - mite_bytes_in_transit(mite_chan);
508bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
5095256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_bytes_written_to_memory_lb);
510bede729096e08172f1a52df91bee1202b17c5d92David Schleef
5115256fb8818917d7c70b192dd11194a0126772bd1matt mooney/* returns upper bound for number of bytes transferred from device to memory */
5125256fb8818917d7c70b192dd11194a0126772bd1matt mooneyu32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
513bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
514bede729096e08172f1a52df91bee1202b17c5d92David Schleef	u32 in_transit_count;
515bede729096e08172f1a52df91bee1202b17c5d92David Schleef
516bede729096e08172f1a52df91bee1202b17c5d92David Schleef	in_transit_count = mite_bytes_in_transit(mite_chan);
517bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return mite_device_bytes_transferred(mite_chan) - in_transit_count;
518bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
5195256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_bytes_written_to_memory_ub);
520bede729096e08172f1a52df91bee1202b17c5d92David Schleef
5215256fb8818917d7c70b192dd11194a0126772bd1matt mooney/* returns lower bound for number of bytes read from memory to device */
5225256fb8818917d7c70b192dd11194a0126772bd1matt mooneyu32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
523bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
524bede729096e08172f1a52df91bee1202b17c5d92David Schleef	u32 device_byte_count;
525bede729096e08172f1a52df91bee1202b17c5d92David Schleef
526bede729096e08172f1a52df91bee1202b17c5d92David Schleef	device_byte_count = mite_device_bytes_transferred(mite_chan);
527bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return device_byte_count + mite_bytes_in_transit(mite_chan);
528bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
5295256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_bytes_read_from_memory_lb);
530bede729096e08172f1a52df91bee1202b17c5d92David Schleef
5315256fb8818917d7c70b192dd11194a0126772bd1matt mooney/* returns upper bound for number of bytes read from memory to device */
5325256fb8818917d7c70b192dd11194a0126772bd1matt mooneyu32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
533bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
534bede729096e08172f1a52df91bee1202b17c5d92David Schleef	u32 in_transit_count;
535bede729096e08172f1a52df91bee1202b17c5d92David Schleef
536bede729096e08172f1a52df91bee1202b17c5d92David Schleef	in_transit_count = mite_bytes_in_transit(mite_chan);
537bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return mite_device_bytes_transferred(mite_chan) + in_transit_count;
538bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
5395256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_bytes_read_from_memory_ub);
540bede729096e08172f1a52df91bee1202b17c5d92David Schleef
541bede729096e08172f1a52df91bee1202b17c5d92David Schleefunsigned mite_dma_tcr(struct mite_channel *mite_chan)
542bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
543bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
544bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int tcr;
545bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int lkar;
546bede729096e08172f1a52df91bee1202b17c5d92David Schleef
547bede729096e08172f1a52df91bee1202b17c5d92David Schleef	lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
548bede729096e08172f1a52df91bee1202b17c5d92David Schleef	tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel));
549bede729096e08172f1a52df91bee1202b17c5d92David Schleef	MDPRINTK("mite_dma_tcr ch%i, lkar=0x%08x tcr=%d\n", mite_chan->channel,
5500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		 lkar, tcr);
551bede729096e08172f1a52df91bee1202b17c5d92David Schleef
552bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return tcr;
553bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
5545256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_dma_tcr);
555bede729096e08172f1a52df91bee1202b17c5d92David Schleef
556bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_dma_disarm(struct mite_channel *mite_chan)
557bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
558bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
559bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned chor;
560bede729096e08172f1a52df91bee1202b17c5d92David Schleef
561bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* disarm */
562bede729096e08172f1a52df91bee1202b17c5d92David Schleef	chor = CHOR_ABORT;
563bede729096e08172f1a52df91bee1202b17c5d92David Schleef	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
564bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
5655256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_dma_disarm);
566bede729096e08172f1a52df91bee1202b17c5d92David Schleef
5670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralint mite_sync_input_dma(struct mite_channel *mite_chan,
5680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			struct comedi_async *async)
569bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
570bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int count;
571bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned int nbytes, old_alloc_count;
572bede729096e08172f1a52df91bee1202b17c5d92David Schleef	const unsigned bytes_per_scan = cfc_bytes_per_scan(async->subdevice);
573bede729096e08172f1a52df91bee1202b17c5d92David Schleef
574bede729096e08172f1a52df91bee1202b17c5d92David Schleef	old_alloc_count = async->buf_write_alloc_count;
5755256fb8818917d7c70b192dd11194a0126772bd1matt mooney	/* write alloc as much as we can */
576bede729096e08172f1a52df91bee1202b17c5d92David Schleef	comedi_buf_write_alloc(async, async->prealloc_bufsz);
577bede729096e08172f1a52df91bee1202b17c5d92David Schleef
578bede729096e08172f1a52df91bee1202b17c5d92David Schleef	nbytes = mite_bytes_written_to_memory_lb(mite_chan);
579bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if ((int)(mite_bytes_written_to_memory_ub(mite_chan) -
5800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		  old_alloc_count) > 0) {
5815f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		printk("mite: DMA overwrite of free area\n");
582bede729096e08172f1a52df91bee1202b17c5d92David Schleef		async->events |= COMEDI_CB_OVERFLOW;
583bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return -1;
584bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
585bede729096e08172f1a52df91bee1202b17c5d92David Schleef
586bede729096e08172f1a52df91bee1202b17c5d92David Schleef	count = nbytes - async->buf_write_count;
587bede729096e08172f1a52df91bee1202b17c5d92David Schleef	/* it's possible count will be negative due to
588bede729096e08172f1a52df91bee1202b17c5d92David Schleef	 * conservative value returned by mite_bytes_written_to_memory_lb */
58982675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton	if (count <= 0)
590bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return 0;
59182675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton
592bede729096e08172f1a52df91bee1202b17c5d92David Schleef	comedi_buf_write_free(async, count);
593bede729096e08172f1a52df91bee1202b17c5d92David Schleef
594bede729096e08172f1a52df91bee1202b17c5d92David Schleef	async->scan_progress += count;
595bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (async->scan_progress >= bytes_per_scan) {
596bede729096e08172f1a52df91bee1202b17c5d92David Schleef		async->scan_progress %= bytes_per_scan;
597bede729096e08172f1a52df91bee1202b17c5d92David Schleef		async->events |= COMEDI_CB_EOS;
598bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
599bede729096e08172f1a52df91bee1202b17c5d92David Schleef	async->events |= COMEDI_CB_BLOCK;
600bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return 0;
601bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
6025256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_sync_input_dma);
603bede729096e08172f1a52df91bee1202b17c5d92David Schleef
6040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralint mite_sync_output_dma(struct mite_channel *mite_chan,
6050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			 struct comedi_async *async)
606bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
607bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int count;
608bede729096e08172f1a52df91bee1202b17c5d92David Schleef	u32 nbytes_ub, nbytes_lb;
609bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned int old_alloc_count;
610bede729096e08172f1a52df91bee1202b17c5d92David Schleef	u32 stop_count =
6110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    async->cmd.stop_arg * cfc_bytes_per_scan(async->subdevice);
612bede729096e08172f1a52df91bee1202b17c5d92David Schleef
613bede729096e08172f1a52df91bee1202b17c5d92David Schleef	old_alloc_count = async->buf_read_alloc_count;
614b6c777571b8d387d3add91170826f32a379e4313Bill Pemberton	/*  read alloc as much as we can */
615bede729096e08172f1a52df91bee1202b17c5d92David Schleef	comedi_buf_read_alloc(async, async->prealloc_bufsz);
616bede729096e08172f1a52df91bee1202b17c5d92David Schleef	nbytes_lb = mite_bytes_read_from_memory_lb(mite_chan);
617bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (async->cmd.stop_src == TRIG_COUNT &&
6180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    (int)(nbytes_lb - stop_count) > 0)
619bede729096e08172f1a52df91bee1202b17c5d92David Schleef		nbytes_lb = stop_count;
620bede729096e08172f1a52df91bee1202b17c5d92David Schleef	nbytes_ub = mite_bytes_read_from_memory_ub(mite_chan);
621bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (async->cmd.stop_src == TRIG_COUNT &&
6220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    (int)(nbytes_ub - stop_count) > 0)
623bede729096e08172f1a52df91bee1202b17c5d92David Schleef		nbytes_ub = stop_count;
624bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if ((int)(nbytes_ub - old_alloc_count) > 0) {
6255256fb8818917d7c70b192dd11194a0126772bd1matt mooney		printk(KERN_ERR "mite: DMA underrun\n");
626bede729096e08172f1a52df91bee1202b17c5d92David Schleef		async->events |= COMEDI_CB_OVERFLOW;
627bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return -1;
628bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
629bede729096e08172f1a52df91bee1202b17c5d92David Schleef	count = nbytes_lb - async->buf_read_count;
63082675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton	if (count <= 0)
631bede729096e08172f1a52df91bee1202b17c5d92David Schleef		return 0;
63282675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton
633bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (count) {
634bede729096e08172f1a52df91bee1202b17c5d92David Schleef		comedi_buf_read_free(async, count);
635bede729096e08172f1a52df91bee1202b17c5d92David Schleef		async->events |= COMEDI_CB_BLOCK;
636bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
637bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return 0;
638bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
6395256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_sync_output_dma);
640bede729096e08172f1a52df91bee1202b17c5d92David Schleef
641bede729096e08172f1a52df91bee1202b17c5d92David Schleefunsigned mite_get_status(struct mite_channel *mite_chan)
642bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
643bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
644bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned status;
645bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long flags;
646bede729096e08172f1a52df91bee1202b17c5d92David Schleef
6475f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&mite->lock, flags);
648bede729096e08172f1a52df91bee1202b17c5d92David Schleef	status = readl(mite->mite_io_addr + MITE_CHSR(mite_chan->channel));
649bede729096e08172f1a52df91bee1202b17c5d92David Schleef	if (status & CHSR_DONE) {
650bede729096e08172f1a52df91bee1202b17c5d92David Schleef		mite_chan->done = 1;
651bede729096e08172f1a52df91bee1202b17c5d92David Schleef		writel(CHOR_CLRDONE,
6520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
653bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
654bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mmiowb();
6555f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&mite->lock, flags);
656bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return status;
657bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
6585256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_get_status);
659bede729096e08172f1a52df91bee1202b17c5d92David Schleef
660bede729096e08172f1a52df91bee1202b17c5d92David Schleefint mite_done(struct mite_channel *mite_chan)
661bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
662bede729096e08172f1a52df91bee1202b17c5d92David Schleef	struct mite_struct *mite = mite_chan->mite;
663bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long flags;
664bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int done;
665bede729096e08172f1a52df91bee1202b17c5d92David Schleef
666bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_get_status(mite_chan);
6675f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&mite->lock, flags);
668bede729096e08172f1a52df91bee1202b17c5d92David Schleef	done = mite_chan->done;
6695f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&mite->lock, flags);
670bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return done;
671bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
6725256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_done);
673bede729096e08172f1a52df91bee1202b17c5d92David Schleef
674bede729096e08172f1a52df91bee1202b17c5d92David Schleef#ifdef DEBUG_MITE
675bede729096e08172f1a52df91bee1202b17c5d92David Schleef
676bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic void mite_decode(char **bit_str, unsigned int bits);
677bede729096e08172f1a52df91bee1202b17c5d92David Schleef
678bede729096e08172f1a52df91bee1202b17c5d92David Schleef/* names of bits in mite registers */
679bede729096e08172f1a52df91bee1202b17c5d92David Schleef
680bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic const char *const mite_CHOR_strings[] = {
681bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"start", "cont", "stop", "abort",
682bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"freset", "clrlc", "clrrb", "clrdone",
683bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"clr_lpause", "set_lpause", "clr_send_tc",
684bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"set_send_tc", "12", "13", "14",
685bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"15", "16", "17", "18",
686bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"19", "20", "21", "22",
687bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"23", "24", "25", "26",
688bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"27", "28", "29", "30",
689bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"dmareset",
690bede729096e08172f1a52df91bee1202b17c5d92David Schleef};
691bede729096e08172f1a52df91bee1202b17c5d92David Schleef
692bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic const char *const mite_CHCR_strings[] = {
693bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"continue", "ringbuff", "2", "3",
694bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"4", "5", "6", "7",
695bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"8", "9", "10", "11",
696bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"12", "13", "bursten", "fifodis",
697bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"clr_cont_rb_ie", "set_cont_rb_ie", "clr_lc_ie", "set_lc_ie",
698bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"clr_drdy_ie", "set_drdy_ie", "clr_mrdy_ie", "set_mrdy_ie",
699bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"clr_done_ie", "set_done_ie", "clr_sar_ie", "set_sar_ie",
700bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"clr_linkp_ie", "set_linkp_ie", "clr_dma_ie", "set_dma_ie",
701bede729096e08172f1a52df91bee1202b17c5d92David Schleef};
702bede729096e08172f1a52df91bee1202b17c5d92David Schleef
703bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic const char *const mite_MCR_strings[] = {
704bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"amdevice", "1", "2", "3",
705bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"4", "5", "portio", "portvxi",
706bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "11",
707bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"12", "13", "blocken", "berhand",
708bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"reqsintlim/reqs0", "reqs1", "reqs2", "rd32",
709bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"rd512", "rl1", "rl2", "rl8",
710bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"24", "25", "26", "27",
711bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"28", "29", "30", "stopen",
712bede729096e08172f1a52df91bee1202b17c5d92David Schleef};
713bede729096e08172f1a52df91bee1202b17c5d92David Schleef
714bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic const char *const mite_DCR_strings[] = {
715bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"amdevice", "1", "2", "3",
716bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"4", "5", "portio", "portvxi",
717bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "aseqxp2",
718bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"aseqxp8", "13", "blocken", "berhand",
719bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"reqsintlim", "reqs1", "reqs2", "rd32",
720bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"rd512", "rl1", "rl2", "rl8",
721bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"23", "24", "25", "27",
722bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"28", "wsdevc", "wsdevs", "rwdevpack",
723bede729096e08172f1a52df91bee1202b17c5d92David Schleef};
724bede729096e08172f1a52df91bee1202b17c5d92David Schleef
725bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic const char *const mite_LKCR_strings[] = {
726bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"amdevice", "1", "2", "3",
727bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"4", "5", "portio", "portvxi",
728bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"psizebyte", "psizehalf (byte & half = word)", "asequp", "aseqdown",
729bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"12", "13", "14", "berhand",
730bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"16", "17", "18", "rd32",
731bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"rd512", "rl1", "rl2", "rl8",
732bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"24", "25", "26", "27",
733bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"28", "29", "30", "chngend",
734bede729096e08172f1a52df91bee1202b17c5d92David Schleef};
735bede729096e08172f1a52df91bee1202b17c5d92David Schleef
736bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic const char *const mite_CHSR_strings[] = {
737bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"d.err0", "d.err1", "m.err0", "m.err1",
738bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"l.err0", "l.err1", "drq0", "drq1",
739bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"end", "xferr", "operr0", "operr1",
740bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"stops", "habort", "sabort", "error",
741bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"16", "conts_rb", "18", "linkc",
742bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"20", "drdy", "22", "mrdy",
743bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"24", "done", "26", "sars",
744bede729096e08172f1a52df91bee1202b17c5d92David Schleef	"28", "lpauses", "30", "int",
745bede729096e08172f1a52df91bee1202b17c5d92David Schleef};
746bede729096e08172f1a52df91bee1202b17c5d92David Schleef
747bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid mite_dump_regs(struct mite_channel *mite_chan)
748bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
749bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long mite_io_addr =
7500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    (unsigned long)mite_chan->mite->mite_io_addr;
751bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long addr = 0;
752bede729096e08172f1a52df91bee1202b17c5d92David Schleef	unsigned long temp = 0;
753bede729096e08172f1a52df91bee1202b17c5d92David Schleef
7545256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite_dump_regs ch%i\n", mite_chan->channel);
7555256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite address is  =0x%08lx\n", mite_io_addr);
756bede729096e08172f1a52df91bee1202b17c5d92David Schleef
757bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = mite_io_addr + MITE_CHOR(channel);
7585256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[CHOR]at 0x%08lx =0x%08lx\n", addr,
7595256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       temp = readl(addr));
760bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_decode(mite_CHOR_strings, temp);
761bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = mite_io_addr + MITE_CHCR(channel);
7625256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[CHCR]at 0x%08lx =0x%08lx\n", addr,
7635256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       temp = readl(addr));
764bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_decode(mite_CHCR_strings, temp);
765bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = mite_io_addr + MITE_TCR(channel);
7665256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[TCR] at 0x%08lx =0x%08x\n", addr,
7670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       readl(addr));
7685256fb8818917d7c70b192dd11194a0126772bd1matt mooney	addr = mite_io_addr + MITE_MCR(channel);
7695256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[MCR] at 0x%08lx =0x%08lx\n", addr,
7705256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       temp = readl(addr));
771bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_decode(mite_MCR_strings, temp);
772bede729096e08172f1a52df91bee1202b17c5d92David Schleef
773bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = mite_io_addr + MITE_MAR(channel);
7745256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[MAR] at 0x%08lx =0x%08x\n", addr,
7750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       readl(addr));
7765256fb8818917d7c70b192dd11194a0126772bd1matt mooney	addr = mite_io_addr + MITE_DCR(channel);
7775256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[DCR] at 0x%08lx =0x%08lx\n", addr,
7785256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       temp = readl(addr));
779bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_decode(mite_DCR_strings, temp);
780bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = mite_io_addr + MITE_DAR(channel);
7815256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[DAR] at 0x%08lx =0x%08x\n", addr,
7820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       readl(addr));
7835256fb8818917d7c70b192dd11194a0126772bd1matt mooney	addr = mite_io_addr + MITE_LKCR(channel);
7845256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[LKCR]at 0x%08lx =0x%08lx\n", addr,
7855256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       temp = readl(addr));
786bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_decode(mite_LKCR_strings, temp);
787bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = mite_io_addr + MITE_LKAR(channel);
7885256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[LKAR]at 0x%08lx =0x%08x\n", addr,
7890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       readl(addr));
7905256fb8818917d7c70b192dd11194a0126772bd1matt mooney	addr = mite_io_addr + MITE_CHSR(channel);
7915256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[CHSR]at 0x%08lx =0x%08lx\n", addr,
7925256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       temp = readl(addr));
793bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_decode(mite_CHSR_strings, temp);
794bede729096e08172f1a52df91bee1202b17c5d92David Schleef	addr = mite_io_addr + MITE_FCR(channel);
7955256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "mite status[FCR] at 0x%08lx =0x%08x\n\n", addr,
7965256fb8818917d7c70b192dd11194a0126772bd1matt mooney	       readl(addr));
797bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
7985256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_dump_regs);
799bede729096e08172f1a52df91bee1202b17c5d92David Schleef
800bede729096e08172f1a52df91bee1202b17c5d92David Schleefstatic void mite_decode(char **bit_str, unsigned int bits)
801bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
802bede729096e08172f1a52df91bee1202b17c5d92David Schleef	int i;
803bede729096e08172f1a52df91bee1202b17c5d92David Schleef
804bede729096e08172f1a52df91bee1202b17c5d92David Schleef	for (i = 31; i >= 0; i--) {
80582675f3547ba2a0732beabd9bb4393535f74408cBill Pemberton		if (bits & (1 << i))
8065256fb8818917d7c70b192dd11194a0126772bd1matt mooney			printk(KERN_DEBUG " %s", bit_str[i]);
807bede729096e08172f1a52df91bee1202b17c5d92David Schleef	}
8085256fb8818917d7c70b192dd11194a0126772bd1matt mooney	printk(KERN_DEBUG "\n");
809bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
8105256fb8818917d7c70b192dd11194a0126772bd1matt mooneyEXPORT_SYMBOL(mite_decode);
811bede729096e08172f1a52df91bee1202b17c5d92David Schleef#endif
812bede729096e08172f1a52df91bee1202b17c5d92David Schleef
813bede729096e08172f1a52df91bee1202b17c5d92David Schleef#ifdef MODULE
814bede729096e08172f1a52df91bee1202b17c5d92David Schleefint __init init_module(void)
815bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
816bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_init();
817bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_list_devices();
818bede729096e08172f1a52df91bee1202b17c5d92David Schleef
819bede729096e08172f1a52df91bee1202b17c5d92David Schleef	return 0;
820bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
821bede729096e08172f1a52df91bee1202b17c5d92David Schleef
822bede729096e08172f1a52df91bee1202b17c5d92David Schleefvoid __exit cleanup_module(void)
823bede729096e08172f1a52df91bee1202b17c5d92David Schleef{
824bede729096e08172f1a52df91bee1202b17c5d92David Schleef	mite_cleanup();
825bede729096e08172f1a52df91bee1202b17c5d92David Schleef}
826bede729096e08172f1a52df91bee1202b17c5d92David Schleef#endif
82790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
82890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
82990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
83090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
831