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