adl_pci6208.c revision 968265fd9c97fa02a65c2798ba03be229936fb77
18b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/*
26d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * adl_pci6208.c
36d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Comedi driver for ADLink 6208 series cards
46d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten *
56d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * COMEDI - Linux Control and Measurement Device Interface
66d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
76d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten *
86d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * This program is free software; you can redistribute it and/or modify
96d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * it under the terms of the GNU General Public License as published by
106d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * the Free Software Foundation; either version 2 of the License, or
116d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * (at your option) any later version.
126d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten *
136d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * This program is distributed in the hope that it will be useful,
146d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * but WITHOUT ANY WARRANTY; without even the implied warranty of
156d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
166d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * GNU General Public License for more details.
176d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten */
188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
198b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/*
206d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Driver: adl_pci6208
216d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
226d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Devices: (ADLink) PCI-6208 [adl_pci6208]
236d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten *	    (ADLink) PCI-6216 [adl_pci6216]
246d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Author: nsyeow <nsyeow@pd.jaring.my>
256d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Updated: Fri, 30 Jan 2004 14:44:27 +0800
266d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Status: untested
276d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten *
286d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten * Configuration Options: not applicable, uses PCI auto config
296d09991e9cf23327849c6db632b42874e5d8ee93H Hartley Sweeten */
30a7c6de4cf6712771155778c454a762cc2b38e12dH Hartley Sweeten
31ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h>
32b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten#include <linux/delay.h>
3333782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten#include <linux/pci.h>
3433782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten
358b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow#include "../comedidev.h"
368b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
377b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten/*
387b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten * PCI-6208/6216-GL register map
397b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten */
407b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_AO_CONTROL(x)		(0x00 + (2 * (x)))
417b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_AO_STATUS		0x00
427b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_AO_STATUS_DATA_SEND	(1 << 0)
437b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO			0x40
447b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DO_MASK		(0x0f)
457b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DO_SHIFT		(0)
467b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DI_MASK		(0xf0)
477b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DI_SHIFT		(4)
487b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten
490a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten#define PCI6208_MAX_AO_CHANNELS		16
505c67df8b98316fbfede8d4d6bac64d52d4327357H Hartley Sweeten
515e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweetenenum pci6208_boardid {
525e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	BOARD_PCI6208,
535e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	BOARD_PCI6216,
545e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten};
555e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten
56c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pembertonstruct pci6208_board {
578b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	const char *name;
588b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	int ao_chans;
59c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton};
60c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton
61c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pembertonstatic const struct pci6208_board pci6208_boards[] = {
625e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	[BOARD_PCI6208] = {
630a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten		.name		= "adl_pci6208",
64dcff1681cb49b2b2be3a3cddee620a81fc81e8e6H Hartley Sweeten		.ao_chans	= 8,
655e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	},
665e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	[BOARD_PCI6216] = {
670a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten		.name		= "adl_pci6216",
680a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten		.ao_chans	= 16,
69dcff1681cb49b2b2be3a3cddee620a81fc81e8e6H Hartley Sweeten	},
708b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow};
718b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
723d393c865b745a37a53081203b49278476a47a56Bill Pembertonstruct pci6208_private {
735c67df8b98316fbfede8d4d6bac64d52d4327357H Hartley Sweeten	unsigned int ao_readback[PCI6208_MAX_AO_CHANNELS];
743d393c865b745a37a53081203b49278476a47a56Bill Pemberton};
758b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
76b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweetenstatic int pci6208_ao_wait_for_data_send(struct comedi_device *dev,
77b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten					 unsigned int timeout)
78b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten{
79b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten	unsigned int status;
80b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten
81b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten	while (timeout--) {
82b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten		status = inw(dev->iobase + PCI6208_AO_STATUS);
83b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten		if ((status & PCI6208_AO_STATUS_DATA_SEND) == 0)
84b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten			return 0;
85b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten		udelay(1);
86b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten	}
87b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten
88b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten	return -ETIME;
89b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten}
90b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten
91a99a29437080eb85f15bc6744150885ee01c1505H Hartley Sweetenstatic int pci6208_ao_insn_write(struct comedi_device *dev,
92a99a29437080eb85f15bc6744150885ee01c1505H Hartley Sweeten				 struct comedi_subdevice *s,
93a99a29437080eb85f15bc6744150885ee01c1505H Hartley Sweeten				 struct comedi_insn *insn,
94a99a29437080eb85f15bc6744150885ee01c1505H Hartley Sweeten				 unsigned int *data)
958b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{
96949a18d39d75e92f516d562befe5447d368ab67dH Hartley Sweeten	struct pci6208_private *devpriv = dev->private;
97a99a29437080eb85f15bc6744150885ee01c1505H Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
9820fb170b293218ef66ce885df3a77903e3d11572H Hartley Sweeten	unsigned int val = devpriv->ao_readback[chan];
99b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten	int ret;
1008366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	int i;
101a7c6de4cf6712771155778c454a762cc2b38e12dH Hartley Sweeten
1028b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	for (i = 0; i < insn->n; i++) {
10320fb170b293218ef66ce885df3a77903e3d11572H Hartley Sweeten		val = data[i];
1048366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten
105b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten		/* D/A transfer rate is 2.2us, wait up to 10us */
106b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten		ret = pci6208_ao_wait_for_data_send(dev, 10);
107b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten		if (ret)
108b609a5959f5ee44342d08ad37faba11bfbeb8b92H Hartley Sweeten			return ret;
1098366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten
1108a6573a875dea244a5b6ca27174f1a3f3898d8eeH Hartley Sweeten		/* the hardware expects two's complement values */
1118a6573a875dea244a5b6ca27174f1a3f3898d8eeH Hartley Sweeten		outw(comedi_offset_munge(s, val),
1128a6573a875dea244a5b6ca27174f1a3f3898d8eeH Hartley Sweeten		     dev->iobase + PCI6208_AO_CONTROL(chan));
1138b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	}
11420fb170b293218ef66ce885df3a77903e3d11572H Hartley Sweeten	devpriv->ao_readback[chan] = val;
1158b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
1168366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	return insn->n;
1178b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow}
1188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
119c354fe06cf04481273f3fee8c5424d0665267d80H Hartley Sweetenstatic int pci6208_ao_insn_read(struct comedi_device *dev,
120c354fe06cf04481273f3fee8c5424d0665267d80H Hartley Sweeten				struct comedi_subdevice *s,
121c354fe06cf04481273f3fee8c5424d0665267d80H Hartley Sweeten				struct comedi_insn *insn,
122c354fe06cf04481273f3fee8c5424d0665267d80H Hartley Sweeten				unsigned int *data)
1238b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{
124949a18d39d75e92f516d562befe5447d368ab67dH Hartley Sweeten	struct pci6208_private *devpriv = dev->private;
125c354fe06cf04481273f3fee8c5424d0665267d80H Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
1267c1e5bc7544db67985fed627cba206fc5dee6405H Hartley Sweeten	int i;
1278b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
1288b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	for (i = 0; i < insn->n; i++)
1298b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow		data[i] = devpriv->ao_readback[chan];
1308b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
1317c1e5bc7544db67985fed627cba206fc5dee6405H Hartley Sweeten	return insn->n;
1328b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow}
1338b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
134270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweetenstatic int pci6208_di_insn_bits(struct comedi_device *dev,
135270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_subdevice *s,
136270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_insn *insn,
137270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				unsigned int *data)
138fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten{
139270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	unsigned int val;
140270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
141270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = inw(dev->iobase + PCI6208_DIO);
142270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = (val & PCI6208_DIO_DI_MASK) >> PCI6208_DIO_DI_SHIFT;
143270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
144270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	data[1] = val;
145270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
146270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	return insn->n;
147270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten}
148270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
149270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweetenstatic int pci6208_do_insn_bits(struct comedi_device *dev,
150270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_subdevice *s,
151270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_insn *insn,
152270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				unsigned int *data)
153270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten{
15497f4289ad08cffe55de06d4ac4f89ac540450aeeH Hartley Sweeten	if (comedi_dio_update_state(s, data))
155fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten		outw(s->state, dev->iobase + PCI6208_DIO);
156fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
157fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten	data[1] = s->state;
158fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
159fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten	return insn->n;
160fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten}
161fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
162a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int pci6208_auto_attach(struct comedi_device *dev,
1635e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten			       unsigned long context)
164c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten{
165750af5e568d060ec6994cdcb4e86cdddfcd473c0Ian Abbott	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1665e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	const struct pci6208_board *boardinfo = NULL;
167949a18d39d75e92f516d562befe5447d368ab67dH Hartley Sweeten	struct pci6208_private *devpriv;
168c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	struct comedi_subdevice *s;
169270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	unsigned int val;
1709d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten	int ret;
171c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
1725e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	if (context < ARRAY_SIZE(pci6208_boards))
1735e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten		boardinfo = &pci6208_boards[context];
174744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	if (!boardinfo)
175744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten		return -ENODEV;
176744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	dev->board_ptr = boardinfo;
177744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	dev->board_name = boardinfo->name;
178744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten
1790bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
180c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten	if (!devpriv)
181c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten		return -ENOMEM;
182c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
183818f569fe930c5b8a05d1a44ece3c63c99c13c88H Hartley Sweeten	ret = comedi_pci_enable(dev);
1843cf05ddb0d7c5612ee70f250f22427462d820fe1H Hartley Sweeten	if (ret)
1859d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten		return ret;
186f8ec639268156073bf8214a5b9446890764448c8H Hartley Sweeten	dev->iobase = pci_resource_start(pcidev, 2);
187c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
188270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	ret = comedi_alloc_subdevices(dev, 3);
1899d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten	if (ret)
1909d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten		return ret;
191c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
1921f6115a4875f3192658e8b7f63e4197cc36aec78H Hartley Sweeten	s = &dev->subdevices[0];
193c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	/* analog output subdevice */
194111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->type		= COMEDI_SUBD_AO;
195111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->subdev_flags	= SDF_WRITABLE;
196744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	s->n_chan	= boardinfo->ao_chans;
197111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->maxdata	= 0xffff;
198111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->range_table	= &range_bipolar10;
199a99a29437080eb85f15bc6744150885ee01c1505H Hartley Sweeten	s->insn_write	= pci6208_ao_insn_write;
200c354fe06cf04481273f3fee8c5424d0665267d80H Hartley Sweeten	s->insn_read	= pci6208_ao_insn_read;
201c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
2021f6115a4875f3192658e8b7f63e4197cc36aec78H Hartley Sweeten	s = &dev->subdevices[1];
203270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	/* digital input subdevice */
204270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->type		= COMEDI_SUBD_DI;
205270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->subdev_flags	= SDF_READABLE;
206270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->n_chan	= 4;
207111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->maxdata	= 1;
208111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->range_table	= &range_digital;
209270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->insn_bits	= pci6208_di_insn_bits;
210111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten
2111f6115a4875f3192658e8b7f63e4197cc36aec78H Hartley Sweeten	s = &dev->subdevices[2];
212270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	/* digital output subdevice */
213270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->type		= COMEDI_SUBD_DO;
214270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->subdev_flags	= SDF_WRITABLE;
215270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->n_chan	= 4;
216270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->maxdata	= 1;
217270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->range_table	= &range_digital;
218270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->insn_bits	= pci6208_do_insn_bits;
219270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
220270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	/*
221270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	 * Get the read back signals from the digital outputs
222270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	 * and save it as the initial state for the subdevice.
223270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	 */
224270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = inw(dev->iobase + PCI6208_DIO);
225270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = (val & PCI6208_DIO_DO_MASK) >> PCI6208_DIO_DO_SHIFT;
226270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->state	= val;
227c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
22898bcf9119cbcab67768a548bcb6dfc2b9464cb96H Hartley Sweeten	return 0;
229c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten}
230c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
23175e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic struct comedi_driver adl_pci6208_driver = {
23275e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.driver_name	= "adl_pci6208",
233c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	.module		= THIS_MODULE,
234750af5e568d060ec6994cdcb4e86cdddfcd473c0Ian Abbott	.auto_attach	= pci6208_auto_attach,
2357f072f54ae5dc9965cbe450419b1389d13e2b849H Hartley Sweeten	.detach		= comedi_pci_disable,
236c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten};
237c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
238a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int adl_pci6208_pci_probe(struct pci_dev *dev,
239b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten				 const struct pci_device_id *id)
240c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten{
241b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten	return comedi_pci_auto_config(dev, &adl_pci6208_driver,
242b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten				      id->driver_data);
243c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten}
244c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
24575e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = {
2465e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	{ PCI_VDEVICE(ADLINK, 0x6208), BOARD_PCI6208 },
2475e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	{ PCI_VDEVICE(ADLINK, 0x6216), BOARD_PCI6216 },
248c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	{ 0 }
249c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten};
25075e6301baa78b2dff00e2cc3051301c32618acd7H Hartley SweetenMODULE_DEVICE_TABLE(pci, adl_pci6208_pci_table);
251c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
25275e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic struct pci_driver adl_pci6208_pci_driver = {
25375e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.name		= "adl_pci6208",
25475e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.id_table	= adl_pci6208_pci_table,
25575e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.probe		= adl_pci6208_pci_probe,
2569901a4d75d007686e8f6473189cafc4b216b7449Peter Huewe	.remove		= comedi_pci_auto_unconfig,
257c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten};
25875e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenmodule_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver);
259c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
26090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
261968265fd9c97fa02a65c2798ba03be229936fb77H Hartley SweetenMODULE_DESCRIPTION("Comedi driver for ADLink 6208 series cards");
26290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
263