190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski/*
290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    comedi/drivers/mpc624.c
390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    Hardware driver for a Micro/sys inc. MPC-624 PC/104 board
490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    COMEDI - Linux Control and Measurement Device Interface
690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    This program is free software; you can redistribute it and/or modify
990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    it under the terms of the GNU General Public License as published by
1090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    the Free Software Foundation; either version 2 of the License, or
1190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    (at your option) any later version.
1290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
1390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    This program is distributed in the hope that it will be useful,
1490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    but WITHOUT ANY WARRANTY; without even the implied warranty of
1590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    GNU General Public License for more details.
1790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
1890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    You should have received a copy of the GNU General Public License
1990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    along with this program; if not, write to the Free Software
2090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
2290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski*/
2390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski/*
2490a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiDriver: mpc624
2590a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiDescription: Micro/sys MPC-624 PC/104 board
2690a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiDevices: [Micro/sys] MPC-624 (mpc624)
2790a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiAuthor: Stanislaw Raczynski <sraczynski@op.pl>
2890a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiUpdated: Thu, 15 Sep 2005 12:01:18 +0200
2990a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiStatus: working
3090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
3190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    The Micro/sys MPC-624 board is based on the LTC2440 24-bit sigma-delta
3290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    ADC chip.
3390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
3490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    Subdevices supported by the driver:
3590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - Analog In:   supported
3690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - Digital I/O: not supported
3790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - LEDs:        not supported
3890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - EEPROM:      not supported
3990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
4090a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiConfiguration Options:
4190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski  [0] - I/O base address
4225985edcedea6396277003854657b5f3cb31a628Lucas De Marchi  [1] - conversion rate
4325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	Conversion rate  RMS noise  Effective Number Of Bits
44b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	0      3.52kHz        23uV                17
45b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	1      1.76kHz       3.5uV                20
46b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	2       880Hz         2uV                21.3
47b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	3       440Hz        1.4uV               21.8
48b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	4       220Hz         1uV                22.4
49b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	5       110Hz        750uV               22.9
50b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	6       55Hz         510nV               23.4
51b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	7      27.5Hz        375nV                24
52b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	8      13.75Hz       250nV               24.4
53b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	9      6.875Hz       200nV               24.6
54b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher  [2] - voltage range
55b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	0      -1.01V .. +1.01V
56b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	1      -10.1V .. +10.1V
5790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski*/
5890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
5990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#include "../comedidev.h"
6090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
6190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#include <linux/ioport.h>
6290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#include <linux/delay.h>
6390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
6479a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* Consecutive I/O port addresses */
6590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_SIZE             16
6690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
6779a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* Offsets of different ports */
68b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_MASTER_CONTROL	0 /* not used */
69b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_GNMUXCH          1 /* Gain, Mux, Channel of ADC */
70b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_ADC              2 /* read/write to/from ADC */
71b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_EE               3 /* read/write to/from serial EEPROM via I2C */
72b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_LEDS             4 /* write to LEDs */
73b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_DIO              5 /* read/write to/from digital I/O ports */
74b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_IRQ_MASK         6 /* IRQ masking enable/disable */
7590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
7679a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* Register bits' names */
7790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADBUSY           (1<<5)
7890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADSDO            (1<<4)
7990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADFO             (1<<3)
8090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADCS             (1<<2)
8190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADSCK            (1<<1)
8290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADSDI            (1<<0)
8390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
8479a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* SDI Speed/Resolution Programming bits */
8590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR4             (1<<31)
8690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR3             (1<<30)
8790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR2             (1<<29)
8890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR1             (1<<28)
8990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR0             (1<<27)
9090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
9179a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* 32-bit output value bits' names */
9290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_EOC_BIT          (1<<31)
9390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_DMY_BIT          (1<<30)
9490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_SGN_BIT          (1<<29)
9590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
9625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi/* Conversion speeds */
9725985edcedea6396277003854657b5f3cb31a628Lucas De Marchi/* OSR4 OSR3 OSR2 OSR1 OSR0  Conversion rate  RMS noise  ENOB^
9890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    0    0    1        3.52kHz        23uV      17
9990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    0    1    0        1.76kHz       3.5uV      20
10090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    0    1    1         880Hz         2uV      21.3
10190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    0    0         440Hz        1.4uV     21.8
10290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    0    1         220Hz         1uV      22.4
10390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    1    0         110Hz        750uV     22.9
10490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    1    1          55Hz        510nV     23.4
10590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    1    0    0    0         27.5Hz       375nV      24
10690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    1    0    0    1        13.75Hz       250nV     24.4
10790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    1    1    1    1        6.875Hz       200nV     24.6
10890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *
10990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski * ^ - Effective Number Of Bits
11090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski */
11190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
112b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_3_52_kHz (MPC624_OSR4 | MPC624_OSR0)
113b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_1_76_kHz (MPC624_OSR4 | MPC624_OSR1)
114b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_880_Hz   (MPC624_OSR4 | MPC624_OSR1 | MPC624_OSR0)
115b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_440_Hz   (MPC624_OSR4 | MPC624_OSR2)
116b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_220_Hz   (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR0)
117b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_110_Hz   (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1)
118b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_55_Hz \
119b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	(MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
120b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_27_5_Hz  (MPC624_OSR4 | MPC624_OSR3)
121b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_13_75_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR0)
122b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_6_875_Hz \
123b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	(MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
124b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
12516450130a9f7006c91c9f49d725b9029fe711240Bill Pembertonstruct skel_private {
12616450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton
127b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	/*  set by mpc624_attach() from driver's parameters */
128b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	unsigned long int ulConvertionRate;
12916450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton};
13016450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton
13116450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton#define devpriv ((struct skel_private *)dev->private)
132b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
1339ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_mpc624_bipolar1 = {
13490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	1,
13590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	{
13679a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* BIP_RANGE(1.01)  this is correct, */
1370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 /*  but my MPC-624 actually seems to have a range of 2.02 */
1380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 BIP_RANGE(2.02)
1390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 }
14090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski};
1410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
1429ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_mpc624_bipolar10 = {
14390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	1,
14490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	{
14579a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* BIP_RANGE(10.1)   this is correct, */
1460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 /*  but my MPC-624 actually seems to have a range of 20.2 */
1470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 BIP_RANGE(20.2)
1480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 }
14990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski};
15090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
151b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
1520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc624_attach(struct comedi_device *dev,
1530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			 struct comedi_devconfig *it);
154da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int mpc624_detach(struct comedi_device *dev);
155b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
156139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_mpc624 = {
15768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "mpc624",
15868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
15968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = mpc624_attach,
16068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = mpc624_detach
16190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski};
16290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
163b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
1640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc624_ai_rinsn(struct comedi_device *dev,
1650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   struct comedi_subdevice *s, struct comedi_insn *insn,
1660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   unsigned int *data);
167b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
168da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
16990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski{
17034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
17190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	unsigned long iobase;
17290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
17390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	iobase = it->options[0];
174b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase);
17590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) {
176b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_ERR "I/O port(s) in use\n");
17790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		return -EIO;
17890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	}
17990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
18090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	dev->iobase = iobase;
18190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	dev->board_name = "mpc624";
18290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
18379a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton	/*  Private structure initialization */
18416450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton	if (alloc_private(dev, sizeof(struct skel_private)) < 0)
18590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		return -ENOMEM;
18690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
18790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	switch (it->options[1]) {
18890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 0:
18990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
190b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "3.52 kHz, ");
19190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
19290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 1:
19390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz;
194b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "1.76 kHz, ");
19590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
19690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 2:
19790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_880_Hz;
198b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "880 Hz, ");
19990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
20090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 3:
20190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_440_Hz;
202b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "440 Hz, ");
20390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
20490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 4:
20590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_220_Hz;
206b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "220 Hz, ");
20790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
20890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 5:
20990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_110_Hz;
210b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "110 Hz, ");
21190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
21290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 6:
21390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_55_Hz;
214b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "55 Hz, ");
21590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
21690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 7:
21790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz;
218b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "27.5 Hz, ");
21990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
22090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 8:
22190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz;
222b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "13.75 Hz, ");
22390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
22490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 9:
22590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz;
226b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "6.875 Hz, ");
22790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
22890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	default:
2295f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		printk
23025985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		    (KERN_ERR "illegal conversion rate setting!"
231b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			" Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
23290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
23390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	}
23490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
23579a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton	/*  Subdevices structures */
23690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	if (alloc_subdevices(dev, 1) < 0)
23790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		return -ENOMEM;
23890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
23990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	s = dev->subdevices + 0;
24090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	s->type = COMEDI_SUBD_AI;
24190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	s->subdev_flags = SDF_READABLE | SDF_DIFF;
24290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	s->n_chan = 8;
24390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	switch (it->options[1]) {
24490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	default:
24590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		s->maxdata = 0x3FFFFFFF;
246b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "30 bit, ");
24790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	}
24890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
24990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	switch (it->options[1]) {
25090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	case 0:
25190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		s->range_table = &range_mpc624_bipolar1;
252b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "1.01V]: ");
25390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		break;
25490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	default:
25590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		s->range_table = &range_mpc624_bipolar10;
256b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "10.1V]: ");
25790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	}
25890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	s->len_chanlist = 1;
25990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	s->insn_read = mpc624_ai_rinsn;
26090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
261b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	printk(KERN_INFO "attached\n");
26290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
26390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	return 1;
26490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski}
26590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
266da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int mpc624_detach(struct comedi_device *dev)
26790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski{
268b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	printk(KERN_INFO "comedi%d: mpc624: remove\n", dev->minor);
26990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
27090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	if (dev->iobase)
27190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		release_region(dev->iobase, MPC624_SIZE);
27290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
27390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	return 0;
27490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski}
27590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
27679a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* Timeout 200ms */
27790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define TIMEOUT 200
27890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
2790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc624_ai_rinsn(struct comedi_device *dev,
2800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   struct comedi_subdevice *s, struct comedi_insn *insn,
2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   unsigned int *data)
28290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski{
28390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	int n, i;
28490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	unsigned long int data_in, data_out;
28590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	unsigned char ucPort;
28690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
287b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	/*
288b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	 *  WARNING:
289b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	 *  We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc
290b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	 */
29190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
292b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* printk("Channel %d:\n", insn->chanspec); */
29390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	if (!insn->n) {
294b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		printk(KERN_INFO "MPC624: Warning, no data to acquire\n");
29590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		return 0;
29690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	}
29790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
29890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	for (n = 0; n < insn->n; n++) {
29925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/*  Trigger the conversion */
30090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
3015f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
30290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		outb(MPC624_ADCS | MPC624_ADSCK, dev->iobase + MPC624_ADC);
3035f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
30490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		outb(0, dev->iobase + MPC624_ADC);
3055f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
30690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
30725985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/*  Wait for the conversion to end */
30890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		for (i = 0; i < TIMEOUT; i++) {
30990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			ucPort = inb(dev->iobase + MPC624_ADC);
31090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			if (ucPort & MPC624_ADBUSY)
3115f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				udelay(1000);
31290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			else
31390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				break;
31490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		}
31590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		if (i == TIMEOUT) {
316b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			printk(KERN_ERR "MPC624: timeout (%dms)\n", TIMEOUT);
31790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data[n] = 0;
31890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			return -ETIMEDOUT;
31990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		}
32079a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton		/*  Start reading data */
32190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		data_in = 0;
32290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		data_out = devpriv->ulConvertionRate;
3235f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
32490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		for (i = 0; i < 32; i++) {
32579a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton			/*  Set the clock low */
32690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			outb(0, dev->iobase + MPC624_ADC);
3275f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			udelay(1);
32890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
329b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			if (data_out & (1 << 31)) { /*  the next bit is a 1 */
33079a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the ADSDI line (send to MPC624) */
33190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(MPC624_ADSDI, dev->iobase + MPC624_ADC);
3325f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				udelay(1);
33379a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the clock high */
33490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(MPC624_ADSCK | MPC624_ADSDI,
3350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     dev->iobase + MPC624_ADC);
3360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			} else {	/*  the next bit is a 0 */
3370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
33879a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the ADSDI line (send to MPC624) */
33990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(0, dev->iobase + MPC624_ADC);
3405f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				udelay(1);
34179a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the clock high */
34290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
34390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			}
34479a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton			/*  Read ADSDO on high clock (receive from MPC624) */
3455f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			udelay(1);
34690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in <<= 1;
34790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in |=
3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    (inb(dev->iobase + MPC624_ADC) & MPC624_ADSDO) >> 4;
3495f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			udelay(1);
35090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
35190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_out <<= 1;
35290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		}
35390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
354b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		/*
355b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *  Received 32-bit long value consist of:
356b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    31: EOC -
357b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (End Of Transmission) bit - should be 0
358b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    30: DMY
359b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Dummy) bit - should be 0
360b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    29: SIG
361b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Sign) bit- 1 if the voltage is positive,
362b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *                      0 if negative
363b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    28: MSB
364b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Most Significant Bit) - the first bit of
365b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *                                   the conversion result
366b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    ....
367b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    05: LSB
368b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Least Significant Bit)- the last bit of the
369b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *                                   conversion result
370b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    04-00: sub-LSB
371b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          - sub-LSBs are basically noise, but when
372b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *            averaged properly, they can increase conversion
373b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *            precision up to 29 bits; they can be discarded
374b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *            without loss of resolution.
375b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 */
37690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
37790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		if (data_in & MPC624_EOC_BIT)
378b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			printk(KERN_INFO "MPC624:EOC bit is set (data_in=%lu)!",
3790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       data_in);
38090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		if (data_in & MPC624_DMY_BIT)
381b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			printk(KERN_INFO "MPC624:DMY bit is set (data_in=%lu)!",
3820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       data_in);
383b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		if (data_in & MPC624_SGN_BIT) {	/* Volatge is positive */
384b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			/*
385b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * comedi operates on unsigned numbers, so mask off EOC
386b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * and DMY and don't clear the SGN bit
387b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 */
388b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			data_in &= 0x3FFFFFFF;
389b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			data[n] = data_in;
390b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		} else { /*  The voltage is negative */
391b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			/*
392b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * data_in contains a number in 30-bit two's complement
393b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * code and we must deal with it
394b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 */
39590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in |= MPC624_SGN_BIT;
39690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in = ~data_in;
39790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in += 1;
39890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in &= ~(MPC624_EOC_BIT | MPC624_DMY_BIT);
39979a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton			/*  clear EOC and DMY bits */
40090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in = 0x20000000 - data_in;
40190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data[n] = data_in;
40290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		}
40390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	}
40490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
40579a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton	/*  Return the number of samples read/written */
40690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	return n;
40790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski}
40890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
4097114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_mpc624_init_module(void)
4107114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
4117114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	return comedi_driver_register(&driver_mpc624);
4127114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
4137114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
4147114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_mpc624_cleanup_module(void)
4157114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
4167114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	comedi_driver_unregister(&driver_mpc624);
4177114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
4187114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
4197114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_mpc624_init_module);
4207114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_mpc624_cleanup_module);
42190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
42290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
42390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
42490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
425