[go: nahoru, domu]

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/*
1990a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiDriver: mpc624
2090a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiDescription: Micro/sys MPC-624 PC/104 board
2190a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiDevices: [Micro/sys] MPC-624 (mpc624)
2290a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiAuthor: Stanislaw Raczynski <sraczynski@op.pl>
2390a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiUpdated: Thu, 15 Sep 2005 12:01:18 +0200
2490a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiStatus: working
2590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
2690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    The Micro/sys MPC-624 board is based on the LTC2440 24-bit sigma-delta
2790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    ADC chip.
2890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
2990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    Subdevices supported by the driver:
3090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - Analog In:   supported
3190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - Digital I/O: not supported
3290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - LEDs:        not supported
3390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski    - EEPROM:      not supported
3490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
3590a5038d91db44a8a224936651fc33325989ad43Stanislaw RaczynskiConfiguration Options:
3690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski  [0] - I/O base address
3725985edcedea6396277003854657b5f3cb31a628Lucas De Marchi  [1] - conversion rate
3825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	Conversion rate  RMS noise  Effective Number Of Bits
39b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	0      3.52kHz        23uV                17
40b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	1      1.76kHz       3.5uV                20
41b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	2       880Hz         2uV                21.3
42b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	3       440Hz        1.4uV               21.8
43b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	4       220Hz         1uV                22.4
44b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	5       110Hz        750uV               22.9
45b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	6       55Hz         510nV               23.4
46b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	7      27.5Hz        375nV                24
47b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	8      13.75Hz       250nV               24.4
48b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	9      6.875Hz       200nV               24.6
49b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher  [2] - voltage range
50b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	0      -1.01V .. +1.01V
51b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	1      -10.1V .. +10.1V
5290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski*/
5390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
54ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h>
5590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#include "../comedidev.h"
5690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
5790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#include <linux/delay.h>
5890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
5979a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* Offsets of different ports */
60b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_MASTER_CONTROL	0 /* not used */
61b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_GNMUXCH          1 /* Gain, Mux, Channel of ADC */
62b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_ADC              2 /* read/write to/from ADC */
63b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_EE               3 /* read/write to/from serial EEPROM via I2C */
64b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_LEDS             4 /* write to LEDs */
65b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_DIO              5 /* read/write to/from digital I/O ports */
66b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_IRQ_MASK         6 /* IRQ masking enable/disable */
6790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
6879a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* Register bits' names */
6990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADBUSY           (1<<5)
7090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADSDO            (1<<4)
7190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADFO             (1<<3)
7290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADCS             (1<<2)
7390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADSCK            (1<<1)
7490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_ADSDI            (1<<0)
7590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
7679a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* SDI Speed/Resolution Programming bits */
7790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR4             (1<<31)
7890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR3             (1<<30)
7990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR2             (1<<29)
8090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR1             (1<<28)
8190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_OSR0             (1<<27)
8290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
8379a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* 32-bit output value bits' names */
8490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_EOC_BIT          (1<<31)
8590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_DMY_BIT          (1<<30)
8690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski#define MPC624_SGN_BIT          (1<<29)
8790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
8825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi/* Conversion speeds */
8925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi/* OSR4 OSR3 OSR2 OSR1 OSR0  Conversion rate  RMS noise  ENOB^
9090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    0    0    1        3.52kHz        23uV      17
9190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    0    1    0        1.76kHz       3.5uV      20
9290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    0    1    1         880Hz         2uV      21.3
9390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    0    0         440Hz        1.4uV     21.8
9490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    0    1         220Hz         1uV      22.4
9590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    1    0         110Hz        750uV     22.9
9690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    0    1    1    1          55Hz        510nV     23.4
9790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    1    0    0    0         27.5Hz       375nV      24
9890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    1    0    0    1        13.75Hz       250nV     24.4
9990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *  X    1    1    1    1        6.875Hz       200nV     24.6
10090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski *
10190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski * ^ - Effective Number Of Bits
10290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski */
10390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
104b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_3_52_kHz (MPC624_OSR4 | MPC624_OSR0)
105b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_1_76_kHz (MPC624_OSR4 | MPC624_OSR1)
106b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_880_Hz   (MPC624_OSR4 | MPC624_OSR1 | MPC624_OSR0)
107b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_440_Hz   (MPC624_OSR4 | MPC624_OSR2)
108b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_220_Hz   (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR0)
109b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_110_Hz   (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1)
110b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_55_Hz \
111b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	(MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
112b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_27_5_Hz  (MPC624_OSR4 | MPC624_OSR3)
113b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_13_75_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR0)
114b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher#define MPC624_SPEED_6_875_Hz \
115b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	(MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
116b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
1179a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweetenstruct mpc624_private {
11816450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton
119b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	/*  set by mpc624_attach() from driver's parameters */
120b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	unsigned long int ulConvertionRate;
12116450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton};
12216450130a9f7006c91c9f49d725b9029fe711240Bill Pemberton
123b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher/* -------------------------------------------------------------------------- */
1249ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_mpc624_bipolar1 = {
12590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	1,
12690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	{
12779a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* BIP_RANGE(1.01)  this is correct, */
1280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 /*  but my MPC-624 actually seems to have a range of 2.02 */
1290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 BIP_RANGE(2.02)
1300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 }
13190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski};
1320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
1339ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_mpc624_bipolar10 = {
13490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	1,
13590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	{
13679a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton/* BIP_RANGE(10.1)   this is correct, */
1370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 /*  but my MPC-624 actually seems to have a range of 20.2 */
1380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 BIP_RANGE(20.2)
1390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 }
14090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski};
14190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
1423d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweetenstatic int mpc624_ai_eoc(struct comedi_device *dev,
1433d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten			 struct comedi_subdevice *s,
1443d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten			 struct comedi_insn *insn,
1453d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten			 unsigned long context)
1463d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten{
1473d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten	unsigned char status;
1483d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten
1493d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten	status = inb(dev->iobase + MPC624_ADC);
1503d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten	if ((status & MPC624_ADBUSY) == 0)
1513d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten		return 0;
1523d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten	return -EBUSY;
1533d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten}
15490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
1550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int mpc624_ai_rinsn(struct comedi_device *dev,
1560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   struct comedi_subdevice *s, struct comedi_insn *insn,
1570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   unsigned int *data)
15890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski{
1599a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten	struct mpc624_private *devpriv = dev->private;
16090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	int n, i;
16190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	unsigned long int data_in, data_out;
1623d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten	int ret;
16390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
164b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	/*
165b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	 *  WARNING:
166b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	 *  We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc
167b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher	 */
16890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
16990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
17090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	for (n = 0; n < insn->n; n++) {
17125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/*  Trigger the conversion */
17290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
1735f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
17490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		outb(MPC624_ADCS | MPC624_ADSCK, dev->iobase + MPC624_ADC);
1755f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
17690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		outb(0, dev->iobase + MPC624_ADC);
1775f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
17890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
17925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/*  Wait for the conversion to end */
1803d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten		ret = comedi_timeout(dev, s, insn, mpc624_ai_eoc, 0);
1813d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten		if (ret)
1823d21960b6dd6bc68d3312be77c9a7a60a0857b90H Hartley Sweeten			return ret;
1834a4ed3f96bc125f376d83f3d29aef6bb2780c10bH Hartley Sweeten
18479a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton		/*  Start reading data */
18590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		data_in = 0;
18690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		data_out = devpriv->ulConvertionRate;
1875f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		udelay(1);
18890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		for (i = 0; i < 32; i++) {
18979a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton			/*  Set the clock low */
19090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			outb(0, dev->iobase + MPC624_ADC);
1915f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			udelay(1);
19290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
193b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			if (data_out & (1 << 31)) { /*  the next bit is a 1 */
19479a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the ADSDI line (send to MPC624) */
19590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(MPC624_ADSDI, dev->iobase + MPC624_ADC);
1965f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				udelay(1);
19779a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the clock high */
19890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(MPC624_ADSCK | MPC624_ADSDI,
1990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     dev->iobase + MPC624_ADC);
2000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			} else {	/*  the next bit is a 0 */
2010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral
20279a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the ADSDI line (send to MPC624) */
20390a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(0, dev->iobase + MPC624_ADC);
2045f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				udelay(1);
20579a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton				/*  Set the clock high */
20690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski				outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
20790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			}
20879a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton			/*  Read ADSDO on high clock (receive from MPC624) */
2095f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			udelay(1);
21090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in <<= 1;
21190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in |=
2120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    (inb(dev->iobase + MPC624_ADC) & MPC624_ADSDO) >> 4;
2135f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			udelay(1);
21490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
21590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_out <<= 1;
21690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		}
21790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
218b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		/*
219b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *  Received 32-bit long value consist of:
220b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    31: EOC -
221b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (End Of Transmission) bit - should be 0
222b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    30: DMY
223b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Dummy) bit - should be 0
224b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    29: SIG
225b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Sign) bit- 1 if the voltage is positive,
226b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *                      0 if negative
227b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    28: MSB
228b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Most Significant Bit) - the first bit of
229b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *                                   the conversion result
230b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    ....
231b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    05: LSB
232b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          (Least Significant Bit)- the last bit of the
233b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *                                   conversion result
234b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *    04-00: sub-LSB
235b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *          - sub-LSBs are basically noise, but when
236b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *            averaged properly, they can increase conversion
237b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *            precision up to 29 bits; they can be discarded
238b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 *            without loss of resolution.
239b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		 */
24090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
24190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		if (data_in & MPC624_EOC_BIT)
242ba74f010ac5f14a836c64c1a53456da199b3ee7cH Hartley Sweeten			dev_dbg(dev->class_dev,
243ba74f010ac5f14a836c64c1a53456da199b3ee7cH Hartley Sweeten				"EOC bit is set (data_in=%lu)!", data_in);
24490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		if (data_in & MPC624_DMY_BIT)
245ba74f010ac5f14a836c64c1a53456da199b3ee7cH Hartley Sweeten			dev_dbg(dev->class_dev,
246ba74f010ac5f14a836c64c1a53456da199b3ee7cH Hartley Sweeten				"DMY bit is set (data_in=%lu)!", data_in);
247b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		if (data_in & MPC624_SGN_BIT) {	/* Volatge is positive */
248b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			/*
249b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * comedi operates on unsigned numbers, so mask off EOC
250b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * and DMY and don't clear the SGN bit
251b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 */
252b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			data_in &= 0x3FFFFFFF;
253b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			data[n] = data_in;
254b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher		} else { /*  The voltage is negative */
255b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			/*
256b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * data_in contains a number in 30-bit two's complement
257b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 * code and we must deal with it
258b8c623e5dde98a00ada4af47bec92a708794c573Iain Churcher			 */
25990a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in |= MPC624_SGN_BIT;
26090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in = ~data_in;
26190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in += 1;
26290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in &= ~(MPC624_EOC_BIT | MPC624_DMY_BIT);
26379a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton			/*  clear EOC and DMY bits */
26490a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data_in = 0x20000000 - data_in;
26590a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski			data[n] = data_in;
26690a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski		}
26790a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	}
26890a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
26979a31bae80df12e3cd19a831e7eacfbc4dc555a0Bill Pemberton	/*  Return the number of samples read/written */
27090a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski	return n;
27190a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski}
27290a5038d91db44a8a224936651fc33325989ad43Stanislaw Raczynski
2739142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweetenstatic int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
2747114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
2759a1a6cf8ae5ca58171e117335b9983e3cfa2185cH Hartley Sweeten	struct mpc624_private *devpriv;
2769142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	struct comedi_subdevice *s;
2778b6c56949ffa83dbc2a6e8fa3f98b10a19372207H Hartley Sweeten	int ret;
2789142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten
279862755ec07572036b0c69d738b88f89b6beede99H Hartley Sweeten	ret = comedi_request_region(dev, it->options[0], 0x10);
28054573376e8d8fa4762db6c1a35f05d4780e5145dH Hartley Sweeten	if (ret)
28154573376e8d8fa4762db6c1a35f05d4780e5145dH Hartley Sweeten		return ret;
2829142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten
2830bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
284c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten	if (!devpriv)
285c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten		return -ENOMEM;
2869142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten
2879142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	switch (it->options[1]) {
2889142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 0:
2899142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
2909142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
2919142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 1:
2929142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz;
2939142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
2949142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 2:
2959142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_880_Hz;
2969142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
2979142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 3:
2989142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_440_Hz;
2999142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3009142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 4:
3019142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_220_Hz;
3029142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3039142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 5:
3049142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_110_Hz;
3059142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3069142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 6:
3079142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_55_Hz;
3089142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3099142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 7:
3109142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz;
3119142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3129142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 8:
3139142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz;
3149142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3159142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 9:
3169142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz;
3179142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3189142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	default:
3199142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
3209142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	}
3219142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten
3228b6c56949ffa83dbc2a6e8fa3f98b10a19372207H Hartley Sweeten	ret = comedi_alloc_subdevices(dev, 1);
3238b6c56949ffa83dbc2a6e8fa3f98b10a19372207H Hartley Sweeten	if (ret)
3248b6c56949ffa83dbc2a6e8fa3f98b10a19372207H Hartley Sweeten		return ret;
3259142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten
326283fd0b2ac1de771255bdeb8749440d7488219a0H Hartley Sweeten	s = &dev->subdevices[0];
3279142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	s->type = COMEDI_SUBD_AI;
3289142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	s->subdev_flags = SDF_READABLE | SDF_DIFF;
3299142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	s->n_chan = 8;
3309142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	switch (it->options[1]) {
3319142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	default:
3329142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		s->maxdata = 0x3FFFFFFF;
3339142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	}
3349142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten
3359142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	switch (it->options[1]) {
3369142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	case 0:
3379142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		s->range_table = &range_mpc624_bipolar1;
3389142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		break;
3399142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	default:
3409142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten		s->range_table = &range_mpc624_bipolar10;
3419142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	}
3429142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	s->len_chanlist = 1;
3439142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	s->insn_read = mpc624_ai_rinsn;
3449142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten
345fb780d213355868b69cc12142635aae5e0ee7c2aH Hartley Sweeten	return 0;
3467114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
3477114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
3489142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweetenstatic struct comedi_driver mpc624_driver = {
3499142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	.driver_name	= "mpc624",
3509142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	.module		= THIS_MODULE,
3519142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten	.attach		= mpc624_attach,
35221208519d42404150fef42283a20192ffe08b0afH Hartley Sweeten	.detach		= comedi_legacy_detach,
3539142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweeten};
3549142e00efeeb8b06fe7f0c42fd2e9400223b9418H Hartley Sweetenmodule_comedi_driver(mpc624_driver);
35590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
35690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
35790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
35890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
359