1027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten/* 2027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * addi_apci_3501.c 3027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 4027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * Project manager: Eric Stolz 5027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * 6027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * ADDI-DATA GmbH 7027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * Dieselstrasse 3 8027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * D-77833 Ottersweier 9027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * Tel: +19(0)7223/9493-0 10027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * Fax: +49(0)7223/9493-92 11027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * http://www.addi-data.com 12027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * info@addi-data.com 13027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * 14027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * This program is free software; you can redistribute it and/or modify it 15027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * under the terms of the GNU General Public License as published by the 16027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * Free Software Foundation; either version 2 of the License, or (at your 17027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * option) any later version. 18027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * 19027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * This program is distributed in the hope that it will be useful, but WITHOUT 20027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 22027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten * more details. 23027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten */ 24027f58c637cda26ba4492b782a08f697f99a1e23H Hartley Sweeten 25ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h> 2633782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten#include <linux/pci.h> 27abac8b54a353b9a1ac7d09ff790812655f618896H Hartley Sweeten#include <linux/interrupt.h> 28abac8b54a353b9a1ac7d09ff790812655f618896H Hartley Sweeten#include <linux/sched.h> 29abac8b54a353b9a1ac7d09ff790812655f618896H Hartley Sweeten 303d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "../comedidev.h" 313d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "comedi_fc.h" 32bf36f012c7ddaff083bb0ef187feddf4d85507a0H Hartley Sweeten#include "amcc_s5933.h" 333d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten 341bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten/* 351bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten * PCI bar 1 register I/O map 361bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten */ 371bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten#define APCI3501_AO_CTRL_STATUS_REG 0x00 381bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten#define APCI3501_AO_CTRL_BIPOLAR (1 << 0) 391bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten#define APCI3501_AO_STATUS_READY (1 << 8) 401bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten#define APCI3501_AO_DATA_REG 0x04 41262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten#define APCI3501_AO_DATA_CHAN(x) ((x) << 0) 42262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten#define APCI3501_AO_DATA_VAL(x) ((x) << 8) 43262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten#define APCI3501_AO_DATA_BIPOLAR (1 << 31) 441bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten#define APCI3501_AO_TRIG_SCS_REG 0x08 459798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_SYNC_REG 0x20 469798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_RELOAD_REG 0x24 479798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_TIMEBASE_REG 0x28 489798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_CTRL_REG 0x2c 499798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_STATUS_REG 0x30 509798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_IRQ_REG 0x34 519798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_WARN_RELOAD_REG 0x38 529798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten#define APCI3501_TIMER_WARN_TIMEBASE_REG 0x3c 531bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten#define APCI3501_DO_REG 0x40 541bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten#define APCI3501_DI_REG 0x50 551bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten 5625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten/* 5725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten * AMCC S5933 NVRAM 5825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten */ 5925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define NVRAM_USER_DATA_START 0x100 6025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 6125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define NVCMD_BEGIN_READ (0x7 << 5) 6225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define NVCMD_LOAD_LOW (0x4 << 5) 6325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define NVCMD_LOAD_HIGH (0x5 << 5) 6425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 6525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten/* 6625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten * Function types stored in the eeprom 6725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten */ 6825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define EEPROM_DIGITALINPUT 0 6925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define EEPROM_DIGITALOUTPUT 1 7025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define EEPROM_ANALOGINPUT 2 7125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define EEPROM_ANALOGOUTPUT 3 7225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define EEPROM_TIMER 4 7325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define EEPROM_WATCHDOG 5 7425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten#define EEPROM_TIMER_WATCHDOG_COUNTER 10 7525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 7653b28a23532f203f4b8287fad2461886088a9158H Hartley Sweetenstruct apci3501_private { 7753b28a23532f203f4b8287fad2461886088a9158H Hartley Sweeten int i_IobaseAmcc; 7853b28a23532f203f4b8287fad2461886088a9158H Hartley Sweeten struct task_struct *tsk_Current; 7953b28a23532f203f4b8287fad2461886088a9158H Hartley Sweeten unsigned char b_TimerSelectMode; 8053b28a23532f203f4b8287fad2461886088a9158H Hartley Sweeten}; 8153b28a23532f203f4b8287fad2461886088a9158H Hartley Sweeten 8299c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweetenstatic struct comedi_lrange apci3501_ao_range = { 8399c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweeten 2, { 8499c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweeten BIP_RANGE(10), 8599c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweeten UNI_RANGE(10) 8699c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweeten } 8799c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweeten}; 8899c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweeten 895458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweetenstatic int apci3501_wait_for_dac(struct comedi_device *dev) 905458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten{ 915458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten unsigned int status; 925458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten 935458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten do { 945458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten status = inl(dev->iobase + APCI3501_AO_CTRL_STATUS_REG); 955458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten } while (!(status & APCI3501_AO_STATUS_READY)); 965458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten 975458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten return 0; 985458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten} 995458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten 100298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweetenstatic int apci3501_ao_insn_write(struct comedi_device *dev, 101298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten struct comedi_subdevice *s, 102298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten struct comedi_insn *insn, 103298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten unsigned int *data) 104298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten{ 105298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten unsigned int chan = CR_CHAN(insn->chanspec); 106298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten unsigned int range = CR_RANGE(insn->chanspec); 107b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten unsigned int cfg = APCI3501_AO_DATA_CHAN(chan); 108298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten int ret; 109b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten int i; 110298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten 111298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten /* 112298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten * All analog output channels have the same output range. 113298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten * 14-bit bipolar: 0-10V 114298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten * 13-bit unipolar: +/-10V 115298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten * Changing the range of one channel changes all of them! 116298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten */ 117298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten if (range) { 118298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten outl(0, dev->iobase + APCI3501_AO_CTRL_STATUS_REG); 119298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten } else { 120b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten cfg |= APCI3501_AO_DATA_BIPOLAR; 121298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten outl(APCI3501_AO_CTRL_BIPOLAR, 122298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten dev->iobase + APCI3501_AO_CTRL_STATUS_REG); 123298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten } 124298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten 125298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten for (i = 0; i < insn->n; i++) { 126b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten unsigned int val = data[i]; 127b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten 128298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten if (range == 1) { 129298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten if (data[i] > 0x1fff) { 130298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten dev_err(dev->class_dev, 131298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten "Unipolar resolution is only 13-bits\n"); 132298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten return -EINVAL; 133298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten } 134298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten } 135298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten 136298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten ret = apci3501_wait_for_dac(dev); 137298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten if (ret) 138298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten return ret; 139298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten 140b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten outl(cfg | APCI3501_AO_DATA_VAL(val), 141298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten dev->iobase + APCI3501_AO_DATA_REG); 142b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten 143b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten s->readback[chan] = val; 144298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten } 145298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten 146298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten return insn->n; 147298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten} 148298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten 14953b28a23532f203f4b8287fad2461886088a9158H Hartley Sweeten#include "addi-data/hwdrv_apci3501.c" 15053b28a23532f203f4b8287fad2461886088a9158H Hartley Sweeten 151513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweetenstatic int apci3501_di_insn_bits(struct comedi_device *dev, 152513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten struct comedi_subdevice *s, 153513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten struct comedi_insn *insn, 154513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten unsigned int *data) 155513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten{ 1561bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten data[1] = inl(dev->iobase + APCI3501_DI_REG) & 0x3; 157513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten 158513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten return insn->n; 159513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten} 160513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten 161953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweetenstatic int apci3501_do_insn_bits(struct comedi_device *dev, 162953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten struct comedi_subdevice *s, 163953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten struct comedi_insn *insn, 164953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten unsigned int *data) 165953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten{ 1661bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten s->state = inl(dev->iobase + APCI3501_DO_REG); 167953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten 16897f4289ad08cffe55de06d4ac4f89ac540450aeeH Hartley Sweeten if (comedi_dio_update_state(s, data)) 1691bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten outl(s->state, dev->iobase + APCI3501_DO_REG); 170953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten 171953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten data[1] = s->state; 172953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten 173953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten return insn->n; 174953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten} 175953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten 17625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweetenstatic void apci3501_eeprom_wait(unsigned long iobase) 17725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten{ 17825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned char val; 17925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 18025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten do { 18125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD); 18225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten } while (val & 0x80); 18325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten} 18425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 18525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweetenstatic unsigned short apci3501_eeprom_readw(unsigned long iobase, 18625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned short addr) 18725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten{ 18825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned short val = 0; 18925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned char tmp; 19025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned char i; 19125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 19225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten /* Add the offset to the start of the user data */ 19325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten addr += NVRAM_USER_DATA_START; 19425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 19525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten for (i = 0; i < 2; i++) { 19625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten /* Load the low 8 bit address */ 19725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD); 19825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten apci3501_eeprom_wait(iobase); 19925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 20025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten apci3501_eeprom_wait(iobase); 20125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 20225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten /* Load the high 8 bit address */ 20325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD); 20425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten apci3501_eeprom_wait(iobase); 20525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten outb(((addr + i) >> 8) & 0xff, 20625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten iobase + AMCC_OP_REG_MCSR_NVDATA); 20725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten apci3501_eeprom_wait(iobase); 20825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 20925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten /* Read the eeprom data byte */ 21025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); 21125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten apci3501_eeprom_wait(iobase); 21225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); 21325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten apci3501_eeprom_wait(iobase); 21425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 21525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten if (i == 0) 21625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten val |= tmp; 21725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten else 21825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten val |= (tmp << 8); 21925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten } 22025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 22125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten return val; 22225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten} 22325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 22425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweetenstatic int apci3501_eeprom_get_ao_n_chan(struct comedi_device *dev) 22525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten{ 226015aebe78d3f341fc6aa42f655e191f84bd1a7e5H Hartley Sweeten struct apci3501_private *devpriv = dev->private; 22725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned long iobase = devpriv->i_IobaseAmcc; 22825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned char nfuncs; 22925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten int i; 23025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 23125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten nfuncs = apci3501_eeprom_readw(iobase, 10) & 0xff; 23225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 23325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten /* Read functionality details */ 23425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten for (i = 0; i < nfuncs; i++) { 23525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned short offset = i * 4; 23625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned short addr; 23725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned char func; 23825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned short val; 23925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 24025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten func = apci3501_eeprom_readw(iobase, 12 + offset) & 0x3f; 24125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten addr = apci3501_eeprom_readw(iobase, 14 + offset); 24225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 24325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten if (func == EEPROM_ANALOGOUTPUT) { 24425b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten val = apci3501_eeprom_readw(iobase, addr + 10); 24525b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten return (val >> 4) & 0x3ff; 24625b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten } 24725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten } 24825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten return 0; 24925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten} 25025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 25187c38fbed5bb706785be9171ed4a9b41faf17e13H Hartley Sweetenstatic int apci3501_eeprom_insn_read(struct comedi_device *dev, 2528861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten struct comedi_subdevice *s, 2538861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten struct comedi_insn *insn, 2548861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten unsigned int *data) 2558861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten{ 256015aebe78d3f341fc6aa42f655e191f84bd1a7e5H Hartley Sweeten struct apci3501_private *devpriv = dev->private; 25725b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten unsigned short addr = CR_CHAN(insn->chanspec); 2588861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 25925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten data[0] = apci3501_eeprom_readw(devpriv->i_IobaseAmcc, 2 * addr); 2608861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 2618861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten return insn->n; 2628861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten} 2638861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 264b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweetenstatic irqreturn_t apci3501_interrupt(int irq, void *d) 2658861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten{ 2668861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten struct comedi_device *dev = d; 267015aebe78d3f341fc6aa42f655e191f84bd1a7e5H Hartley Sweeten struct apci3501_private *devpriv = dev->private; 268b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten unsigned int ui_Timer_AOWatchdog; 269b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten unsigned long ul_Command1; 270b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten int i_temp; 271b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten 272b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten /* Disable Interrupt */ 2739798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); 274b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten ul_Command1 = (ul_Command1 & 0xFFFFF9FDul); 2759798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); 276b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten 2779798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten ui_Timer_AOWatchdog = inl(dev->iobase + APCI3501_TIMER_IRQ_REG) & 0x1; 278b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten if ((!ui_Timer_AOWatchdog)) { 27961768da12ae5f50b4dc3a8e2ca1c066cf827be93H Hartley Sweeten dev_err(dev->class_dev, "IRQ from unknown source\n"); 280b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten return IRQ_NONE; 281b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten } 2828861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 283b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten /* Enable Interrupt Send a signal to from kernel to user space */ 284b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten send_sig(SIGIO, devpriv->tsk_Current, 0); 2859798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG); 286b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1); 2879798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG); 2889798df7269a44fb148d1815542abb844b0dac435H Hartley Sweeten i_temp = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1; 289b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten 290b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten return IRQ_HANDLED; 2918861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten} 2928861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 293678a4d3ab159b776a7cb9c8ca9fdaf5498f3423aH Hartley Sweetenstatic int apci3501_reset(struct comedi_device *dev) 2948861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten{ 295262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten unsigned int val; 296262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten int chan; 2975458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten int ret; 298678a4d3ab159b776a7cb9c8ca9fdaf5498f3423aH Hartley Sweeten 299262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten /* Reset all digital outputs to "0" */ 3001bc5062a9796b2908f5c21c2bc3f50add7431fb8H Hartley Sweeten outl(0x0, dev->iobase + APCI3501_DO_REG); 301678a4d3ab159b776a7cb9c8ca9fdaf5498f3423aH Hartley Sweeten 302262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten /* Default all analog outputs to 0V (bipolar) */ 303262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten outl(APCI3501_AO_CTRL_BIPOLAR, 304262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten dev->iobase + APCI3501_AO_CTRL_STATUS_REG); 305262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten val = APCI3501_AO_DATA_BIPOLAR | APCI3501_AO_DATA_VAL(0); 306678a4d3ab159b776a7cb9c8ca9fdaf5498f3423aH Hartley Sweeten 307262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten /* Set all analog output channels */ 308262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten for (chan = 0; chan < 8; chan++) { 3095458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten ret = apci3501_wait_for_dac(dev); 3105458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten if (ret) { 3115458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten dev_warn(dev->class_dev, 3125458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten "%s: DAC not-ready for channel %i\n", 313262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten __func__, chan); 3145458f3e7b5a8707a49948857d69b2eb2fa5931acH Hartley Sweeten } else { 315262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten outl(val | APCI3501_AO_DATA_CHAN(chan), 316262736988d445cb1613aa936bfe343261627f899H Hartley Sweeten dev->iobase + APCI3501_AO_DATA_REG); 317678a4d3ab159b776a7cb9c8ca9fdaf5498f3423aH Hartley Sweeten } 318678a4d3ab159b776a7cb9c8ca9fdaf5498f3423aH Hartley Sweeten } 3198861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 3208861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten return 0; 3218861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten} 3228861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 3238861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweetenstatic int apci3501_auto_attach(struct comedi_device *dev, 3248861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten unsigned long context_unused) 3258861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten{ 3268861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten struct pci_dev *pcidev = comedi_to_pci_dev(dev); 327015aebe78d3f341fc6aa42f655e191f84bd1a7e5H Hartley Sweeten struct apci3501_private *devpriv; 3288861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten struct comedi_subdevice *s; 32925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten int ao_n_chan; 330694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten int ret; 3318861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 3320bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 3338861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten if (!devpriv) 3348861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten return -ENOMEM; 3358861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 336818f569fe930c5b8a05d1a44ece3c63c99c13c88H Hartley Sweeten ret = comedi_pci_enable(dev); 3378861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten if (ret) 3388861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten return ret; 3398861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 3401bdc840224f71768c6bbe41b211f07c0778330c8H Hartley Sweeten dev->iobase = pci_resource_start(pcidev, 1); 3411bdc840224f71768c6bbe41b211f07c0778330c8H Hartley Sweeten devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); 3428861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 34325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten ao_n_chan = apci3501_eeprom_get_ao_n_chan(dev); 3448861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 3458861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten if (pcidev->irq > 0) { 346b2b82184c9c9a82553bfd49e7940ebc67fe655a8H Hartley Sweeten ret = request_irq(pcidev->irq, apci3501_interrupt, IRQF_SHARED, 3478861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten dev->board_name, dev); 3488861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten if (ret == 0) 3498861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten dev->irq = pcidev->irq; 3508861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten } 3518861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 352694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten ret = comedi_alloc_subdevices(dev, 5); 3538861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten if (ret) 3548861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten return ret; 3558861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 356694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten /* Initialize the analog output subdevice */ 3578861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten s = &dev->subdevices[0]; 35825b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten if (ao_n_chan) { 35925b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten s->type = COMEDI_SUBD_AO; 36025b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; 36125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten s->n_chan = ao_n_chan; 36225b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten s->maxdata = 0x3fff; 36399c9fa48b6bbc640066c414d6b413a1f1b4aa857H Hartley Sweeten s->range_table = &apci3501_ao_range; 364298ab7de9ced3ecbe7961360ece58d5aa17aa3c1H Hartley Sweeten s->insn_write = apci3501_ao_insn_write; 365b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten s->insn_read = comedi_readback_insn_read; 366b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten 367b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten ret = comedi_alloc_subdev_readback(s); 368b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten if (ret) 369b1d6bffb92fe78d11e18f8853a80d4cc372afc2dH Hartley Sweeten return ret; 3708861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten } else { 37125b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten s->type = COMEDI_SUBD_UNUSED; 3728861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten } 37325b9b873d3e3c1ed25cd5a7551bfee0b42d4ed1dH Hartley Sweeten 374694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten /* Initialize the digital input subdevice */ 375694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten s = &dev->subdevices[1]; 376513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten s->type = COMEDI_SUBD_DI; 377513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten s->subdev_flags = SDF_READABLE; 378513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten s->n_chan = 2; 379513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten s->maxdata = 1; 380513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten s->range_table = &range_digital; 381513192fc7e34d089d4b949a0e7ba6ccd4780f663H Hartley Sweeten s->insn_bits = apci3501_di_insn_bits; 3828861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 383953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten /* Initialize the digital output subdevice */ 384694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten s = &dev->subdevices[2]; 385953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten s->type = COMEDI_SUBD_DO; 386953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten s->subdev_flags = SDF_WRITEABLE; 387953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten s->n_chan = 2; 388953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten s->maxdata = 1; 389953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten s->range_table = &range_digital; 390953a36c45aa4ba23be687451df6311ad33d89538H Hartley Sweeten s->insn_bits = apci3501_do_insn_bits; 3918861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 392694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten /* Initialize the timer/watchdog subdevice */ 393694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten s = &dev->subdevices[3]; 3943d596e50ffbb183df6fb132a9a795a5ff8d7842cH Hartley Sweeten s->type = COMEDI_SUBD_TIMER; 3953d596e50ffbb183df6fb132a9a795a5ff8d7842cH Hartley Sweeten s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; 3963d596e50ffbb183df6fb132a9a795a5ff8d7842cH Hartley Sweeten s->n_chan = 1; 3973d596e50ffbb183df6fb132a9a795a5ff8d7842cH Hartley Sweeten s->maxdata = 0; 3983d596e50ffbb183df6fb132a9a795a5ff8d7842cH Hartley Sweeten s->len_chanlist = 1; 3993d596e50ffbb183df6fb132a9a795a5ff8d7842cH Hartley Sweeten s->range_table = &range_digital; 400805077b90c5a290ec050d5003a4ea9e37be48453Fred Akers s->insn_write = apci3501_write_insn_timer; 401805077b90c5a290ec050d5003a4ea9e37be48453Fred Akers s->insn_read = apci3501_read_insn_timer; 402805077b90c5a290ec050d5003a4ea9e37be48453Fred Akers s->insn_config = apci3501_config_insn_timer; 4038861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 404694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten /* Initialize the eeprom subdevice */ 405694dcf501c35b6afcbc90ae3b4f3fea0b59f9888H Hartley Sweeten s = &dev->subdevices[4]; 40687c38fbed5bb706785be9171ed4a9b41faf17e13H Hartley Sweeten s->type = COMEDI_SUBD_MEMORY; 40787c38fbed5bb706785be9171ed4a9b41faf17e13H Hartley Sweeten s->subdev_flags = SDF_READABLE | SDF_INTERNAL; 40887c38fbed5bb706785be9171ed4a9b41faf17e13H Hartley Sweeten s->n_chan = 256; 40987c38fbed5bb706785be9171ed4a9b41faf17e13H Hartley Sweeten s->maxdata = 0xffff; 41087c38fbed5bb706785be9171ed4a9b41faf17e13H Hartley Sweeten s->insn_read = apci3501_eeprom_insn_read; 4118861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 412678a4d3ab159b776a7cb9c8ca9fdaf5498f3423aH Hartley Sweeten apci3501_reset(dev); 4138861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten return 0; 4148861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten} 4158861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 4168861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweetenstatic void apci3501_detach(struct comedi_device *dev) 4178861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten{ 418015aebe78d3f341fc6aa42f655e191f84bd1a7e5H Hartley Sweeten if (dev->iobase) 419015aebe78d3f341fc6aa42f655e191f84bd1a7e5H Hartley Sweeten apci3501_reset(dev); 420aac307f9dd5ce1fe651140a036ab4b0a0571b54aH Hartley Sweeten comedi_pci_detach(dev); 4218861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten} 422317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten 42320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct comedi_driver apci3501_driver = { 42420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .driver_name = "addi_apci_3501", 42520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .module = THIS_MODULE, 4268861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten .auto_attach = apci3501_auto_attach, 4278861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten .detach = apci3501_detach, 42820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 42920a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 430a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int apci3501_pci_probe(struct pci_dev *dev, 431b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten const struct pci_device_id *id) 43220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{ 433b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten return comedi_pci_auto_config(dev, &apci3501_driver, id->driver_data); 43420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten} 43520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten 43641e043fcfa2236bb2c4a8335eb09f4c8cee224b3Jingoo Hanstatic const struct pci_device_id apci3501_pci_table[] = { 4378861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, 4388861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten { 0 } 4398861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten}; 4408861b456b8f800208e043b2d0d65985eca538dd9H Hartley SweetenMODULE_DEVICE_TABLE(pci, apci3501_pci_table); 4418861b456b8f800208e043b2d0d65985eca538dd9H Hartley Sweeten 44220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct pci_driver apci3501_pci_driver = { 44320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .name = "addi_apci_3501", 44420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .id_table = apci3501_pci_table, 44520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten .probe = apci3501_pci_probe, 4469901a4d75d007686e8f6473189cafc4b216b7449Peter Huewe .remove = comedi_pci_auto_unconfig, 44720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}; 44820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenmodule_comedi_pci_driver(apci3501_driver, apci3501_pci_driver); 44990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas 4506ff35881e882f744a4a9954fbf838296a36fe7c2H Hartley SweetenMODULE_DESCRIPTION("ADDI-DATA APCI-3501 Analog output board"); 45190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org"); 45290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL"); 453