cb_pcidda.c revision 20fb2280815510533cbd7785b53821ca7209345b
1086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 2086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez comedi/drivers/cb_pcidda.c 3086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez This intends to be a driver for the ComputerBoards / MeasurementComputing 4086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez PCI-DDA series. 5086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 6086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com> 7086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net> 8086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 9086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez COMEDI - Linux Control and Measurement Device Interface 10086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> 11086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 12086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez This program is free software; you can redistribute it and/or modify 13086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez it under the terms of the GNU General Public License as published by 14086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez the Free Software Foundation; either version 2 of the License, or 15086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez (at your option) any later version. 16086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 17086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez This program is distributed in the hope that it will be useful, 18086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez but WITHOUT ANY WARRANTY; without even the implied warranty of 19086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez GNU General Public License for more details. 21086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 22086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez You should have received a copy of the GNU General Public License 23086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez along with this program; if not, write to the Free Software 24086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 26086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez*/ 27086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 28086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezDriver: cb_pcidda 29086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezDescription: MeasurementComputing PCI-DDA series 30086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezAuthor: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net> 31086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezStatus: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12 32086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezDevices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12, 33086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16 34086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 35086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezConfiguration options: 36086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez [0] - PCI bus of device (optional) 37086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez [1] - PCI slot of device (optional) 38086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez If bus/slot is not specified, the first available PCI 39086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez device will be used. 40086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 41086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezOnly simple analog output writing is supported. 42086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 43086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezSo far it has only been tested with: 44086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez - PCI-DDA08/12 45086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezPlease report success/failure with other different cards to 46086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez<comedi@comedi.org>. 47086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez*/ 48086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 49086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#include "../comedidev.h" 50086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 51086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#include "comedi_pci.h" 52086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#include "8255.h" 53086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 542696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */ 552696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define N_BOARDS 10 /* Number of boards in cb_pcidda_boards */ 562696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define EEPROM_SIZE 128 /* number of entries in eeprom */ 572696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */ 58086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 59086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* PCI-DDA base addresses */ 60086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define DIGITALIO_BADRINDEX 2 612696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* DIGITAL I/O is pci_dev->resource[2] */ 62086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define DIGITALIO_SIZE 8 632696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* DIGITAL I/O uses 8 I/O port addresses */ 64086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define DAC_BADRINDEX 3 652696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* DAC is pci_dev->resource[3] */ 66086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 67086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* Digital I/O registers */ 682696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define PORT1A 0 /* PORT 1A DATA */ 69086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 702696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define PORT1B 1 /* PORT 1B DATA */ 71086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 722696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define PORT1C 2 /* PORT 1C DATA */ 73086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 742696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define CONTROL1 3 /* CONTROL REGISTER 1 */ 75086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 762696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define PORT2A 4 /* PORT 2A DATA */ 77086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 782696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define PORT2B 5 /* PORT 2B DATA */ 79086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 802696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define PORT2C 6 /* PORT 2C DATA */ 81086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 822696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define CONTROL2 7 /* CONTROL REGISTER 2 */ 83086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 84086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* DAC registers */ 852696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DACONTROL 0 /* D/A CONTROL REGISTER */ 862696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define SU 0000001 /* Simultaneous update enabled */ 872696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define NOSU 0000000 /* Simultaneous update disabled */ 882696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define ENABLEDAC 0000002 /* Enable specified DAC */ 892696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DISABLEDAC 0000000 /* Disable specified DAC */ 902696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define RANGE2V5 0000000 /* 2.5V */ 912696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define RANGE5V 0000200 /* 5V */ 922696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define RANGE10V 0000300 /* 10V */ 932696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define UNIP 0000400 /* Unipolar outputs */ 942696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define BIP 0000000 /* Bipolar outputs */ 952696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 962696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */ 972696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* write bits */ 982696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define SERIAL_IN_BIT 0x1 /* serial data input for eeprom, caldacs, reference dac */ 99086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define CAL_CHANNEL_MASK (0x7 << 1) 100086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK) 1012696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* read bits */ 102086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define CAL_COUNTER_MASK 0x1f 1032696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define CAL_COUNTER_OVERFLOW_BIT 0x20 /* calibration counter overflow status bit */ 1042696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define AO_BELOW_REF_BIT 0x40 /* analog output is less than reference dac voltage */ 1052696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define SERIAL_OUT_BIT 0x80 /* serial data out, for reading from eeprom */ 106086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 1072696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DACALIBRATION2 6 /* D/A CALIBRATION REGISTER 2 */ 1082696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define SELECT_EEPROM_BIT 0x1 /* send serial data in to eeprom */ 1092696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DESELECT_REF_DAC_BIT 0x2 /* don't send serial data to MAX542 reference dac */ 1102696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DESELECT_CALDAC_BIT(n) (0x4 << (n)) /* don't send serial data to caldac n */ 1112696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DUMMY_BIT 0x40 /* manual says to set this bit with no explanation */ 112086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 1132696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton#define DADATA 8 /* FIRST D/A DATA REGISTER (0) */ 114086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 1159ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange cb_pcidda_ranges = { 116086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 6, 117086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez { 1180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(10), 1190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(5), 1200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral BIP_RANGE(2.5), 1210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(10), 1220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(5), 1230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral UNI_RANGE(2.5), 1240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral } 125086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez}; 126086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 127086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 128086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Board descriptions for two imaginary boards. Describing the 129086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * boards in this way is optional, and completely driver-dependent. 130086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Some drivers use arrays such as this, other do not. 131086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 1321657e325042ffc723182377a47d38ccc7319078fBill Pembertonstruct cb_pcidda_board { 133086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez const char *name; 1342696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton char status; /* Driver status: */ 1352696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 1362696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* 1372696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton * 0 - tested 1382696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton * 1 - manual read, not tested 1392696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton * 2 - manual not read 1402696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton */ 1412696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 142086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned short device_id; 143086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int ao_chans; 144086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int ao_bits; 1459ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pemberton const struct comedi_lrange *ranges; 1461657e325042ffc723182377a47d38ccc7319078fBill Pemberton}; 1472696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 1481657e325042ffc723182377a47d38ccc7319078fBill Pembertonstatic const struct cb_pcidda_board cb_pcidda_boards[] = { 149086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez { 1500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dda02/12", 1510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .status = 1, 1520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x20, 1530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_chans = 2, 1540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_bits = 12, 1550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidda_ranges, 1560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 157086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez { 1580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dda04/12", 1590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .status = 1, 1600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x21, 1610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_chans = 4, 1620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_bits = 12, 1630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidda_ranges, 1640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 165086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez { 1660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dda08/12", 1670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .status = 0, 1680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x22, 1690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_chans = 8, 1700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_bits = 12, 1710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidda_ranges, 1720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 173086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez { 1740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dda02/16", 1750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .status = 2, 1760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x23, 1770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_chans = 2, 1780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_bits = 16, 1790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidda_ranges, 1800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 181086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez { 1820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dda04/16", 1830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .status = 2, 1840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x24, 1850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_chans = 4, 1860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_bits = 16, 1870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidda_ranges, 1880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 189086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez { 1900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .name = "pci-dda08/16", 1910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .status = 0, 1920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .device_id = 0x25, 1930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_chans = 8, 1940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ao_bits = 16, 1950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral .ranges = &cb_pcidda_ranges, 1960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral }, 197086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez}; 198086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 199086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { 2000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral { 2010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_VENDOR_ID_CB, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 2020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_VENDOR_ID_CB, 0x0021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 2030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_VENDOR_ID_CB, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 2040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_VENDOR_ID_CB, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 2050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_VENDOR_ID_CB, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 2060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_VENDOR_ID_CB, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 2070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral 0} 208086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez}; 209086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 210086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan MartinezMODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table); 211086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 212086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 213086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Useful for shorthand access to the particular board structure 214086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 2151657e325042ffc723182377a47d38ccc7319078fBill Pemberton#define thisboard ((const struct cb_pcidda_board *)dev->board_ptr) 216086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 217086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* this structure is for data unique to this hardware driver. If 218086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez several hardware drivers keep similar information in this structure, 21971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton feel free to suggest moving the variable to the struct comedi_device struct. */ 220cc7bb61e00a2e9e4e0d742b9917cb37406080922Bill Pembertonstruct cb_pcidda_private { 221086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int data; 222086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 223086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* would be useful for a PCI device */ 224086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez struct pci_dev *pci_dev; 225086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 226086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned long digitalio; 227086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned long dac; 2282696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 2292696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* unsigned long control_status; */ 2302696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* unsigned long adc_fifo; */ 2312696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 2322696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton unsigned int dac_cal1_bits; /* bits last written to da calibration register 1 */ 2332696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton unsigned int ao_range[MAX_AO_CHANNELS]; /* current range settings for output channels */ 2342696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */ 235cc7bb61e00a2e9e4e0d742b9917cb37406080922Bill Pemberton}; 236086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 237086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 238086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * most drivers define the following macro to make it easy to 239086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * access the private structure. 240086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 241cc7bb61e00a2e9e4e0d742b9917cb37406080922Bill Pemberton#define devpriv ((struct cb_pcidda_private *)dev->private) 242086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 2430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidda_attach(struct comedi_device *dev, 2440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it); 245da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidda_detach(struct comedi_device *dev); 2462696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */ 2470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidda_ao_winsn(struct comedi_device *dev, 2480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 2490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data); 2502696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 2512696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct *comedi_subdevice *s);*/ 2522696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); */ 2532696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* static int cb_pcidda_ns_to_timer(unsigned int *ns,int *round); */ 2542696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 255da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic unsigned int cb_pcidda_serial_in(struct comedi_device *dev); 256da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, 2570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bits); 258da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, 2590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int address); 260da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, 2610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int range); 262086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 263086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 264139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pemberton * The struct comedi_driver structure tells the Comedi core module 265086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * which functions to call to configure/deconfigure (attach/detach) 266086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * the board, and also about the kernel module that contains 267086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * the device code. 268086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 269139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_cb_pcidda = { 27068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .driver_name = "cb_pcidda", 27168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .module = THIS_MODULE, 27268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .attach = cb_pcidda_attach, 27368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton .detach = cb_pcidda_detach, 274086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez}; 275086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 276086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 277086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Attach is called by the Comedi core to configure the driver 278086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * for a particular board. 279086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 2800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidda_attach(struct comedi_device *dev, 2810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_devconfig *it) 282086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 28334c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton struct comedi_subdevice *s; 28420fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy struct pci_dev *pcidev = NULL; 285086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int index; 286086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 287086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("comedi%d: cb_pcidda: ", dev->minor); 288086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 289086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 290086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Allocate the private structure area. 291086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 292cc7bb61e00a2e9e4e0d742b9917cb37406080922Bill Pemberton if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0) 293086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return -ENOMEM; 294086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 295086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 296086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Probe the device to determine what device in the series it is. 297086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 298086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("\n"); 299086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 30020fb2280815510533cbd7785b53821ca7209345bKulikov Vasiliy for_each_pci_dev(pcidev) { 301086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (pcidev->vendor == PCI_VENDOR_ID_CB) { 302086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (it->options[0] || it->options[1]) { 303086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (pcidev->bus->number != it->options[0] || 3040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral PCI_SLOT(pcidev->devfn) != it->options[1]) { 305086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez continue; 306086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 307086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 308086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez for (index = 0; index < N_BOARDS; index++) { 309086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cb_pcidda_boards[index].device_id == 3100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pcidev->device) { 311086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez goto found; 312086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 313086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 314086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 315086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 316086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (!pcidev) { 3170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 3180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("Not a ComputerBoards/MeasurementComputing card on requested position\n"); 319086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return -EIO; 320086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 3210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralfound: 322086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez devpriv->pci_dev = pcidev; 323086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez dev->board_ptr = cb_pcidda_boards + index; 3242696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* "thisboard" macro can be used from here. */ 325086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("Found %s at requested position\n", thisboard->name); 326086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 327086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* 328086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Enable PCI device and request regions. 329086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 330086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (comedi_pci_enable(pcidev, thisboard->name)) { 3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 3320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("cb_pcidda: failed to enable PCI device and request regions\n"); 333086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return -EIO; 334086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 335086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 336086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 337086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Allocate the I/O ports. 338086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 339086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez devpriv->digitalio = 3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX); 341086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX); 342086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 343086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 344086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Warn about the status of the driver. 345086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 346086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (thisboard->status == 2) 3470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral printk 3480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " 3490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " 3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n"); 351086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 352086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 353086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Initialize dev->board_name. 354086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 355086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez dev->board_name = thisboard->name; 356086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 357086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 358086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Allocate the subdevice structures. 359086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 360086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (alloc_subdevices(dev, 3) < 0) 361086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return -ENOMEM; 362086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 363086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s = dev->subdevices + 0; 364086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* analog output subdevice */ 365086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s->type = COMEDI_SUBD_AO; 366086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s->subdev_flags = SDF_WRITABLE; 367086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s->n_chan = thisboard->ao_chans; 368086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s->maxdata = (1 << thisboard->ao_bits) - 1; 369086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s->range_table = thisboard->ranges; 370086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s->insn_write = cb_pcidda_ao_winsn; 371086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 3722696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* s->subdev_flags |= SDF_CMD_READ; */ 3732696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* s->do_cmd = cb_pcidda_ai_cmd; */ 3742696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */ 3752696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton 3762696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* two 8255 digital io subdevices */ 377086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s = dev->subdevices + 1; 378086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez subdev_8255_init(dev, s, NULL, devpriv->digitalio); 379086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez s = dev->subdevices + 2; 380086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A); 381086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 382086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk(" eeprom:"); 383086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez for (index = 0; index < EEPROM_SIZE; index++) { 384086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); 385086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk(" %i:0x%x ", index, devpriv->eeprom_data[index]); 386086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 387086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("\n"); 388086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 3892696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* set calibrations dacs */ 390086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez for (index = 0; index < thisboard->ao_chans; index++) 391086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]); 392086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 393086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 1; 394086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 395086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 396086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 397086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * _detach is called to deconfigure a device. It should deallocate 398086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * resources. 399086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * This function is also called when _attach() fails, so it should be 400086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * careful not to release resources that were not necessarily 401086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * allocated by _attach(). dev->private and dev->subdevices are 402086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * deallocated automatically by the core. 403086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 404da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int cb_pcidda_detach(struct comedi_device *dev) 405086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 406086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 407086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Deallocate the I/O ports. 408086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 409086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (devpriv) { 410086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (devpriv->pci_dev) { 41120db7d7de7027ddee5df1b51b3d013568273b9dfAndrea Gelmini if (devpriv->dac) 412086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez comedi_pci_disable(devpriv->pci_dev); 413086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez pci_dev_put(devpriv->pci_dev); 414086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 415086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 4162696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* cleanup 8255 */ 417086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (dev->subdevices) { 418086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez subdev_8255_cleanup(dev, dev->subdevices + 1); 419086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez subdev_8255_cleanup(dev, dev->subdevices + 2); 420086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 421086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 422086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("comedi%d: cb_pcidda: remove\n", dev->minor); 423086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 424086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 0; 425086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 426086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 427086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 428086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * I will program this later... ;-) 429086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 430086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#if 0 4310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidda_ai_cmd(struct comedi_device *dev, 4320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s) 433086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 434086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("cb_pcidda_ai_cmd\n"); 435086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("subdev: %d\n", cmd->subdev); 436086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("flags: %d\n", cmd->flags); 437086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("start_src: %d\n", cmd->start_src); 438086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("start_arg: %d\n", cmd->start_arg); 439086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("scan_begin_src: %d\n", cmd->scan_begin_src); 440086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("convert_src: %d\n", cmd->convert_src); 441086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("convert_arg: %d\n", cmd->convert_arg); 442086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("scan_end_src: %d\n", cmd->scan_end_src); 443086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("scan_end_arg: %d\n", cmd->scan_end_arg); 444086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("stop_src: %d\n", cmd->stop_src); 445086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("stop_arg: %d\n", cmd->stop_arg); 446086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez printk("chanlist_len: %d\n", cmd->chanlist_len); 447086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 448086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#endif 449086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 450086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#if 0 4510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidda_ai_cmdtest(struct comedi_device *dev, 4520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 4530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_cmd *cmd) 454086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 455086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int err = 0; 456086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int tmp; 457086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 458086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* cmdtest tests a particular command to see if it is valid. 459086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * Using the cmdtest ioctl, a user can create a valid cmd 460086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * and then have it executes by the cmd ioctl. 461086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * 462086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * cmdtest returns 1,2,3,4 or 0, depending on which tests 463086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * the command passes. */ 464086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 465086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* step 1: make sure trigger sources are trivially valid */ 466086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 467086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez tmp = cmd->start_src; 468086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->start_src &= TRIG_NOW; 469086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (!cmd->start_src || tmp != cmd->start_src) 470086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 471086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 472086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez tmp = cmd->scan_begin_src; 473086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 474086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 475086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 476086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 477086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez tmp = cmd->convert_src; 478086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 479086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (!cmd->convert_src || tmp != cmd->convert_src) 480086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 481086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 482086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez tmp = cmd->scan_end_src; 483086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->scan_end_src &= TRIG_COUNT; 484086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 485086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 486086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 487086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez tmp = cmd->stop_src; 488086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 489086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (!cmd->stop_src || tmp != cmd->stop_src) 490086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 491086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 492086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (err) 493086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 1; 494086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 495086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* step 2: make sure trigger sources are unique and mutually compatible */ 496086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 497828684f9a6e096f9150bad523c43b75d74b9baddDirk Hohndel /* note that mutual compatibility is not an issue here */ 498086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_begin_src != TRIG_TIMER 4990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral && cmd->scan_begin_src != TRIG_EXT) 500086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 501086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 502086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 503086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT) 504086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 505086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 506086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (err) 507086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 2; 508086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 509086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* step 3: make sure arguments are trivially compatible */ 510086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 511086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->start_arg != 0) { 512086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->start_arg = 0; 513086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 514086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 515086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define MAX_SPEED 10000 /* in nanoseconds */ 516086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#define MIN_SPEED 1000000000 /* in nanoseconds */ 517086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 518086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 519086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_begin_arg < MAX_SPEED) { 520086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->scan_begin_arg = MAX_SPEED; 521086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 522086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 523086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_begin_arg > MIN_SPEED) { 524086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->scan_begin_arg = MIN_SPEED; 525086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 526086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 527086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } else { 528086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* external trigger */ 529086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* should be level/edge, hi/lo specification here */ 530086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* should specify multiple external triggers */ 531086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_begin_arg > 9) { 532086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->scan_begin_arg = 9; 533086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 534086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 535086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 536086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->convert_src == TRIG_TIMER) { 537086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->convert_arg < MAX_SPEED) { 538086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->convert_arg = MAX_SPEED; 539086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 540086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 541086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->convert_arg > MIN_SPEED) { 542086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->convert_arg = MIN_SPEED; 543086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 544086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 545086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } else { 546086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* external trigger */ 547086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* see above */ 548086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->convert_arg > 9) { 549086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->convert_arg = 9; 550086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 551086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 552086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 553086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 554086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_end_arg != cmd->chanlist_len) { 555086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->scan_end_arg = cmd->chanlist_len; 556086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 557086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 558086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->stop_src == TRIG_COUNT) { 559086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->stop_arg > 0x00ffffff) { 560086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->stop_arg = 0x00ffffff; 561086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 562086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 563086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } else { 564086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* TRIG_NONE */ 565086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->stop_arg != 0) { 566086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->stop_arg = 0; 567086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 568086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 569086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 570086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 571086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (err) 572086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 3; 573086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 574086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* step 4: fix up any arguments */ 575086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 576086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_begin_src == TRIG_TIMER) { 577086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez tmp = cmd->scan_begin_arg; 578086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_ns_to_timer(&cmd->scan_begin_arg, 5790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 580086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (tmp != cmd->scan_begin_arg) 581086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 582086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 583086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->convert_src == TRIG_TIMER) { 584086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez tmp = cmd->convert_arg; 585086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_ns_to_timer(&cmd->convert_arg, 5860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->flags & TRIG_ROUND_MASK); 587086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (tmp != cmd->convert_arg) 588086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 589086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (cmd->scan_begin_src == TRIG_TIMER && 5900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->scan_begin_arg < 5910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg) { 592086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cmd->scan_begin_arg = 5930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral cmd->convert_arg * cmd->scan_end_arg; 594086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez err++; 595086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 596086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 597086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 598086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (err) 599086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 4; 600086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 601086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 0; 602086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 603086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#endif 604086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 605086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* This function doesn't require a particular form, this is just 606086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * what happens to be used in some of the drivers. It should 607086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * convert ns nanoseconds to a counter value suitable for programming 608086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * the device. Also, it should adjust ns so that it cooresponds to 609086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * the actual time that the device will use. */ 610086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#if 0 611086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic int cb_pcidda_ns_to_timer(unsigned int *ns, int round) 612086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 613086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* trivial timer */ 614086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return *ns; 615086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 616086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez#endif 617086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 6180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int cb_pcidda_ao_winsn(struct comedi_device *dev, 6190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_subdevice *s, 6200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral struct comedi_insn *insn, unsigned int *data) 621086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 622086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int command; 623086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int channel, range; 624086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 625086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez channel = CR_CHAN(insn->chanspec); 626086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez range = CR_RANGE(insn->chanspec); 627086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 6282696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* adjust calibration dacs if range has changed */ 629086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (range != devpriv->ao_range[channel]) 630086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_calibrate(dev, channel, range); 631086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 632086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* output channel configuration */ 633086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command = NOSU | ENABLEDAC; 634086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 635086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* output channel range */ 636086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez switch (range) { 637086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez case 0: 638086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command |= BIP | RANGE10V; 639086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez break; 640086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez case 1: 641086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command |= BIP | RANGE5V; 642086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez break; 643086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez case 2: 644086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command |= BIP | RANGE2V5; 645086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez break; 646086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez case 3: 647086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command |= UNIP | RANGE10V; 648086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez break; 649086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez case 4: 650086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command |= UNIP | RANGE5V; 651086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez break; 652086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez case 5: 653086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command |= UNIP | RANGE2V5; 654086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez break; 655086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez }; 656086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 657086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* output channel specification */ 658086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez command |= channel << 2; 659086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez outw(command, devpriv->dac + DACONTROL); 660086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 661086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* write data */ 662086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez outw(data[0], devpriv->dac + DADATA + channel * 2); 663086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 664086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* return the number of samples read/written */ 665086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 1; 666086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 667086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 6682696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* lowlevel read from eeprom */ 669da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic unsigned int cb_pcidda_serial_in(struct comedi_device *dev) 670086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 671086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int value = 0; 672086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int i; 6732696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton const int value_width = 16; /* number of bits wide values are */ 674086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 675086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez for (i = 1; i <= value_width; i++) { 6762696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* read bits most significant bit first */ 67720db7d7de7027ddee5df1b51b3d013568273b9dfAndrea Gelmini if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) 678086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez value |= 1 << (value_width - i); 679086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 680086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 681086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return value; 682086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 683086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 6842696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* lowlevel write to eeprom/dac */ 685da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, 6860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int num_bits) 687086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 688086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez int i; 689086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 690086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez for (i = 1; i <= num_bits; i++) { 6912696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* send bits most significant bit first */ 692086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez if (value & (1 << (num_bits - i))) 693086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez devpriv->dac_cal1_bits |= SERIAL_IN_BIT; 694086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez else 695086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT; 696086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1); 697086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez } 698086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 699086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7002696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* reads a 16 bit value from board's eeprom */ 701da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, 7020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int address) 703086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 704086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int i; 705086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int cal2_bits; 706086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int value; 7072696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton const int max_num_caldacs = 4; /* one caldac for every two dac channels */ 7082696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton const int read_instruction = 0x6; /* bits to send to tell eeprom we want to read */ 709086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez const int instruction_length = 3; 710086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez const int address_length = 8; 711086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7122696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* send serial output stream to eeprom */ 713086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT; 7142696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* deactivate caldacs (one caldac for every two channels) */ 71520db7d7de7027ddee5df1b51b3d013568273b9dfAndrea Gelmini for (i = 0; i < max_num_caldacs; i++) 716086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cal2_bits |= DESELECT_CALDAC_BIT(i); 717086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); 718086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7192696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* tell eeprom we want to read */ 720086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_serial_out(dev, read_instruction, instruction_length); 7212696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* send address we want to read from */ 722086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_serial_out(dev, address, address_length); 723086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 724086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez value = cb_pcidda_serial_in(dev); 725086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7262696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* deactivate eeprom */ 727086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cal2_bits &= ~SELECT_EEPROM_BIT; 728086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); 729086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 730086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return value; 731086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 732086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7332696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* writes to 8 bit calibration dacs */ 7340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void cb_pcidda_write_caldac(struct comedi_device *dev, 7350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int caldac, unsigned int channel, 7360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int value) 737086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 738086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int cal2_bits; 739086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int i; 7402696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton const int num_channel_bits = 3; /* caldacs use 3 bit channel specification */ 7412696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton const int num_caldac_bits = 8; /* 8 bit calibration dacs */ 7422696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton const int max_num_caldacs = 4; /* one caldac for every two dac channels */ 743086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 744086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez /* write 3 bit channel */ 745086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_serial_out(dev, channel, num_channel_bits); 7462696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* write 8 bit caldac value */ 747086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_serial_out(dev, value, num_caldac_bits); 748086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7492696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* 7502696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton* latch stream into appropriate caldac deselect reference dac 7512696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton*/ 752086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT; 7532696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* deactivate caldacs (one caldac for every two channels) */ 75420db7d7de7027ddee5df1b51b3d013568273b9dfAndrea Gelmini for (i = 0; i < max_num_caldacs; i++) 755086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cal2_bits |= DESELECT_CALDAC_BIT(i); 7562696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* activate the caldac we want */ 757086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cal2_bits &= ~DESELECT_CALDAC_BIT(caldac); 758086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); 7592696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* deactivate caldac */ 760086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cal2_bits |= DESELECT_CALDAC_BIT(caldac); 761086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); 762086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 763086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7642696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns caldac that calibrates given analog out channel */ 765086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int caldac_number(unsigned int channel) 766086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 767086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return channel / 2; 768086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 769086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7702696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns caldac channel that provides fine gain for given ao channel */ 771086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int fine_gain_channel(unsigned int ao_channel) 772086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 773086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 4 * (ao_channel % 2); 774086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 775086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7762696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns caldac channel that provides coarse gain for given ao channel */ 777086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int coarse_gain_channel(unsigned int ao_channel) 778086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 779086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 1 + 4 * (ao_channel % 2); 780086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 781086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7822696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns caldac channel that provides coarse offset for given ao channel */ 783086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int coarse_offset_channel(unsigned int ao_channel) 784086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 785086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 2 + 4 * (ao_channel % 2); 786086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 787086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7882696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns caldac channel that provides fine offset for given ao channel */ 789086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int fine_offset_channel(unsigned int ao_channel) 790086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 791086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 3 + 4 * (ao_channel % 2); 792086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 793086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 7942696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns eeprom address that provides offset for given ao channel and range */ 795086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int offset_eeprom_address(unsigned int ao_channel, 7960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int range) 797086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 798086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 0x7 + 2 * range + 12 * ao_channel; 799086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 800086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 8012696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns eeprom address that provides gain calibration for given ao channel and range */ 802086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int gain_eeprom_address(unsigned int ao_channel, 8030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int range) 804086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 805086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return 0x8 + 2 * range + 12 * ao_channel; 806086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 807086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 8082696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns upper byte of eeprom entry, which gives the coarse adjustment values */ 809086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int eeprom_coarse_byte(unsigned int word) 810086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 811086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return (word >> 8) & 0xff; 812086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 813086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 8142696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* returns lower byte of eeprom entry, which gives the fine adjustment values */ 815086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinezstatic unsigned int eeprom_fine_byte(unsigned int word) 816086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 817086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez return word & 0xff; 818086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 819086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 8202696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* set caldacs to eeprom values for given channel and range */ 821da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, 8220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral unsigned int range) 823086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez{ 824086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain; 825086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 8262696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* remember range so we can tell when we need to readjust calibration */ 827086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez devpriv->ao_range[channel] = range; 828086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 8292696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* get values from eeprom data */ 830086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez coarse_offset = 8310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral eeprom_coarse_byte(devpriv->eeprom_data 8320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral [offset_eeprom_address(channel, range)]); 833086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez fine_offset = 8340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral eeprom_fine_byte(devpriv->eeprom_data 8350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral [offset_eeprom_address(channel, range)]); 836086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez coarse_gain = 8370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral eeprom_coarse_byte(devpriv->eeprom_data 8380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral [gain_eeprom_address(channel, range)]); 839086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez fine_gain = 8400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral eeprom_fine_byte(devpriv->eeprom_data 8410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral [gain_eeprom_address(channel, range)]); 842086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 8432696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton /* set caldacs */ 844086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_write_caldac(dev, caldac_number(channel), 8450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral coarse_offset_channel(channel), coarse_offset); 846086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_write_caldac(dev, caldac_number(channel), 8470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral fine_offset_channel(channel), fine_offset); 848086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_write_caldac(dev, caldac_number(channel), 8490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral coarse_gain_channel(channel), coarse_gain); 850086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez cb_pcidda_write_caldac(dev, caldac_number(channel), 8510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral fine_gain_channel(channel), fine_gain); 852086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez} 853086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez 854086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez/* 855086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * A convenient macro that defines init_module() and cleanup_module(), 856086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez * as necessary. 857086df5b5fea9c6bd1374acb6dea2c558247d4637Ivan Martinez */ 858727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev, 859727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas const struct pci_device_id *ent) 860727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 861727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name); 862727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 863727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 864727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev) 865727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 866727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_pci_auto_unconfig(dev); 867727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 868727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 869727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_cb_pcidda_pci_driver = { 870727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .id_table = cb_pcidda_pci_table, 871727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .probe = &driver_cb_pcidda_pci_probe, 872727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas .remove = __devexit_p(&driver_cb_pcidda_pci_remove) 873727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}; 874727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 875727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_cb_pcidda_init_module(void) 876727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 877727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas int retval; 878727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 879727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas retval = comedi_driver_register(&driver_cb_pcidda); 880727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas if (retval < 0) 881727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return retval; 882727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 883727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas driver_cb_pcidda_pci_driver.name = (char *)driver_cb_pcidda.driver_name; 884727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas return pci_register_driver(&driver_cb_pcidda_pci_driver); 885727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 886727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 887727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_cb_pcidda_cleanup_module(void) 888727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{ 889727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas pci_unregister_driver(&driver_cb_pcidda_pci_driver); 890727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas comedi_driver_unregister(&driver_cb_pcidda); 891727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas} 892727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas 893727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_cb_pcidda_init_module); 894727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_cb_pcidda_cleanup_module); 89590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 89690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 89790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver"); 89890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 899