adl_pci6208.c revision ce157f8032bbd46d9427034c335b0afd751da25d
18b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/*
28b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    comedi/drivers/adl_pci6208.c
38b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
48b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    Hardware driver for ADLink 6208 series cards:
58b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	card	     | voltage output    | current output
68b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	-------------+-------------------+---------------
78b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	PCI-6208V    |  8 channels       | -
88b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	PCI-6216V    | 16 channels       | -
98b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	PCI-6208A    |  8 channels       | 8 channels
108b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
118b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    COMEDI - Linux Control and Measurement Device Interface
128b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
138b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
148b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    This program is free software; you can redistribute it and/or modify
158b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    it under the terms of the GNU General Public License as published by
168b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    the Free Software Foundation; either version 2 of the License, or
178b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    (at your option) any later version.
188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
198b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    This program is distributed in the hope that it will be useful,
208b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    but WITHOUT ANY WARRANTY; without even the implied warranty of
218b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
228b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow    GNU General Public License for more details.
238b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow*/
248b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow/*
258b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowDriver: adl_pci6208
260a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley SweetenDescription: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
270a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley SweetenDevices: (ADLink) PCI-6208 [adl_pci6208]
280a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten	 (ADLink) PCI-6216 [adl_pci6216]
298b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowAuthor: nsyeow <nsyeow@pd.jaring.my>
308b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowUpdated: Fri, 30 Jan 2004 14:44:27 +0800
318b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowStatus: untested
328b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
33744a8398e1f48d5349409b1fa9232a109b223458H Hartley SweetenConfiguration Options: not applicable, uses PCI auto config
348b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
358b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeowReferences:
368b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	- ni_660x.c
378b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	- adl_pci9111.c		copied the entire pci setup section
388b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	- adl_pci9118.c
398b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow*/
40a7c6de4cf6712771155778c454a762cc2b38e12dH Hartley Sweeten
41ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h>
4233782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten#include <linux/pci.h>
4333782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten
448b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow#include "../comedidev.h"
458b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
467b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten/*
477b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten * PCI-6208/6216-GL register map
487b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten */
497b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_AO_CONTROL(x)		(0x00 + (2 * (x)))
507b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_AO_STATUS		0x00
517b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_AO_STATUS_DATA_SEND	(1 << 0)
527b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO			0x40
537b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DO_MASK		(0x0f)
547b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DO_SHIFT		(0)
557b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DI_MASK		(0xf0)
567b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten#define PCI6208_DIO_DI_SHIFT		(4)
577b6afad100f50130e6c5a347760e83b83aaa7cc7H Hartley Sweeten
580a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten#define PCI6208_MAX_AO_CHANNELS		16
595c67df8b98316fbfede8d4d6bac64d52d4327357H Hartley Sweeten
605e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweetenenum pci6208_boardid {
615e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	BOARD_PCI6208,
625e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	BOARD_PCI6216,
635e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten};
645e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten
65c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pembertonstruct pci6208_board {
668b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	const char *name;
678b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	int ao_chans;
68c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton};
69c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pemberton
70c1b31c44a38e2b5153193680e4bee4856b3307e1Bill Pembertonstatic const struct pci6208_board pci6208_boards[] = {
715e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	[BOARD_PCI6208] = {
720a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten		.name		= "adl_pci6208",
73dcff1681cb49b2b2be3a3cddee620a81fc81e8e6H Hartley Sweeten		.ao_chans	= 8,
745e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	},
755e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	[BOARD_PCI6216] = {
760a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten		.name		= "adl_pci6216",
770a1e6c1fdbdcdbbf9457bc812e145062d59a68c2H Hartley Sweeten		.ao_chans	= 16,
78dcff1681cb49b2b2be3a3cddee620a81fc81e8e6H Hartley Sweeten	},
798b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow};
808b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
813d393c865b745a37a53081203b49278476a47a56Bill Pembertonstruct pci6208_private {
825c67df8b98316fbfede8d4d6bac64d52d4327357H Hartley Sweeten	unsigned int ao_readback[PCI6208_MAX_AO_CHANNELS];
833d393c865b745a37a53081203b49278476a47a56Bill Pemberton};
848b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci6208_ao_winsn(struct comedi_device *dev,
860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    struct comedi_subdevice *s,
870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    struct comedi_insn *insn, unsigned int *data)
888b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{
89949a18d39d75e92f516d562befe5447d368ab67dH Hartley Sweeten	struct pci6208_private *devpriv = dev->private;
908366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	int chan = CR_CHAN(insn->chanspec);
918b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	unsigned long invert = 1 << (16 - 1);
928366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	unsigned long value = 0;
938366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	unsigned short status;
948366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	int i;
95a7c6de4cf6712771155778c454a762cc2b38e12dH Hartley Sweeten
968b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	for (i = 0; i < insn->n; i++) {
978366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten		value = data[i] ^ invert;
988366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten
998b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow		do {
1008366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten			status = inw(dev->iobase + PCI6208_AO_STATUS);
1018366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten		} while (status & PCI6208_AO_STATUS_DATA_SEND);
1028366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten
1038366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten		outw(value, dev->iobase + PCI6208_AO_CONTROL(chan));
1048b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	}
1058366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	devpriv->ao_readback[chan] = value;
1068b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
1078366404bf1c034d902af06a6a6d88fe77a2cc7fbH Hartley Sweeten	return insn->n;
1088b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow}
1098b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
1100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci6208_ao_rinsn(struct comedi_device *dev,
1110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    struct comedi_subdevice *s,
1120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    struct comedi_insn *insn, unsigned int *data)
1138b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow{
114949a18d39d75e92f516d562befe5447d368ab67dH Hartley Sweeten	struct pci6208_private *devpriv = dev->private;
1158b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	int chan = CR_CHAN(insn->chanspec);
1167c1e5bc7544db67985fed627cba206fc5dee6405H Hartley Sweeten	int i;
1178b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
1188b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow	for (i = 0; i < insn->n; i++)
1198b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow		data[i] = devpriv->ao_readback[chan];
1208b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
1217c1e5bc7544db67985fed627cba206fc5dee6405H Hartley Sweeten	return insn->n;
1228b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow}
1238b93f9034efbf2874d8809a9b8233e596bcbd5b1nsyeow
124270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweetenstatic int pci6208_di_insn_bits(struct comedi_device *dev,
125270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_subdevice *s,
126270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_insn *insn,
127270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				unsigned int *data)
128fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten{
129270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	unsigned int val;
130270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
131270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = inw(dev->iobase + PCI6208_DIO);
132270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = (val & PCI6208_DIO_DI_MASK) >> PCI6208_DIO_DI_SHIFT;
133270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
134270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	data[1] = val;
135270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
136270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	return insn->n;
137270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten}
138270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
139270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweetenstatic int pci6208_do_insn_bits(struct comedi_device *dev,
140270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_subdevice *s,
141270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				struct comedi_insn *insn,
142270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten				unsigned int *data)
143270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten{
144270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	unsigned int mask = data[0];
145fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten	unsigned int bits = data[1];
146fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
147fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten	if (mask) {
148fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten		s->state &= ~mask;
149270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten		s->state |= (bits & mask);
150fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
151fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten		outw(s->state, dev->iobase + PCI6208_DIO);
152fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten	}
153fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
154fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten	data[1] = s->state;
155fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
156fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten	return insn->n;
157fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten}
158fc2536fd814ea1e4399ccbfc913b5742e467320aH Hartley Sweeten
159a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int pci6208_auto_attach(struct comedi_device *dev,
1605e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten			       unsigned long context)
161c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten{
162750af5e568d060ec6994cdcb4e86cdddfcd473c0Ian Abbott	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1635e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	const struct pci6208_board *boardinfo = NULL;
164949a18d39d75e92f516d562befe5447d368ab67dH Hartley Sweeten	struct pci6208_private *devpriv;
165c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	struct comedi_subdevice *s;
166270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	unsigned int val;
1679d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten	int ret;
168c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
1695e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	if (context < ARRAY_SIZE(pci6208_boards))
1705e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten		boardinfo = &pci6208_boards[context];
171744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	if (!boardinfo)
172744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten		return -ENODEV;
173744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	dev->board_ptr = boardinfo;
174744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	dev->board_name = boardinfo->name;
175744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten
1760bdab509bf9c6d838dc0a3b1d68bbf841fc20b5aH Hartley Sweeten	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
177c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten	if (!devpriv)
178c34fa261b0ac3a862ccd3f71ee55a16b920dfc83H Hartley Sweeten		return -ENOMEM;
179c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
180818f569fe930c5b8a05d1a44ece3c63c99c13c88H Hartley Sweeten	ret = comedi_pci_enable(dev);
1813cf05ddb0d7c5612ee70f250f22427462d820fe1H Hartley Sweeten	if (ret)
1829d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten		return ret;
183f8ec639268156073bf8214a5b9446890764448c8H Hartley Sweeten	dev->iobase = pci_resource_start(pcidev, 2);
184c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
185270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	ret = comedi_alloc_subdevices(dev, 3);
1869d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten	if (ret)
1879d639b6b252759e6333aa576645f25624c4b9a99H Hartley Sweeten		return ret;
188c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
1891f6115a4875f3192658e8b7f63e4197cc36aec78H Hartley Sweeten	s = &dev->subdevices[0];
190c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	/* analog output subdevice */
191111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->type		= COMEDI_SUBD_AO;
192111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->subdev_flags	= SDF_WRITABLE;
193744a8398e1f48d5349409b1fa9232a109b223458H Hartley Sweeten	s->n_chan	= boardinfo->ao_chans;
194111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->maxdata	= 0xffff;
195111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->range_table	= &range_bipolar10;
196111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->insn_write	= pci6208_ao_winsn;
197111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->insn_read	= pci6208_ao_rinsn;
198c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
1991f6115a4875f3192658e8b7f63e4197cc36aec78H Hartley Sweeten	s = &dev->subdevices[1];
200270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	/* digital input subdevice */
201270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->type		= COMEDI_SUBD_DI;
202270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->subdev_flags	= SDF_READABLE;
203270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->n_chan	= 4;
204111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->maxdata	= 1;
205111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->range_table	= &range_digital;
206270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->insn_bits	= pci6208_di_insn_bits;
207111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten
2081f6115a4875f3192658e8b7f63e4197cc36aec78H Hartley Sweeten	s = &dev->subdevices[2];
209270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	/* digital output subdevice */
210270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->type		= COMEDI_SUBD_DO;
211270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->subdev_flags	= SDF_WRITABLE;
212270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->n_chan	= 4;
213270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->maxdata	= 1;
214270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->range_table	= &range_digital;
215270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->insn_bits	= pci6208_do_insn_bits;
216270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten
217270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	/*
218270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	 * Get the read back signals from the digital outputs
219270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	 * and save it as the initial state for the subdevice.
220270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	 */
221270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = inw(dev->iobase + PCI6208_DIO);
222270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	val = (val & PCI6208_DIO_DO_MASK) >> PCI6208_DIO_DO_SHIFT;
223270809a80fb610b54de5ee792a607dc37a71195cH Hartley Sweeten	s->state	= val;
224111b62e48139767a42fc87b422f39b5909c27ac6H Hartley Sweeten	s->io_bits	= 0x0f;
225c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
226b4dda059056a9be086fc95abe2a7410b87e6c33fH Hartley Sweeten	dev_info(dev->class_dev, "%s: %s, I/O base=0x%04lx\n",
227b4dda059056a9be086fc95abe2a7410b87e6c33fH Hartley Sweeten		dev->driver->driver_name, dev->board_name, dev->iobase);
228c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
22998bcf9119cbcab67768a548bcb6dfc2b9464cb96H Hartley Sweeten	return 0;
230c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten}
231c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
23275e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic struct comedi_driver adl_pci6208_driver = {
23375e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.driver_name	= "adl_pci6208",
234c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	.module		= THIS_MODULE,
235750af5e568d060ec6994cdcb4e86cdddfcd473c0Ian Abbott	.auto_attach	= pci6208_auto_attach,
2367f072f54ae5dc9965cbe450419b1389d13e2b849H Hartley Sweeten	.detach		= comedi_pci_disable,
237c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten};
238c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
239a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int adl_pci6208_pci_probe(struct pci_dev *dev,
240b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten				 const struct pci_device_id *id)
241c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten{
242b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten	return comedi_pci_auto_config(dev, &adl_pci6208_driver,
243b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten				      id->driver_data);
244c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten}
245c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
24675e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = {
2475e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	{ PCI_VDEVICE(ADLINK, 0x6208), BOARD_PCI6208 },
2485e42525df0a7a1262069d433b1015d0cf2107cb1H Hartley Sweeten	{ PCI_VDEVICE(ADLINK, 0x6216), BOARD_PCI6216 },
249c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten	{ 0 }
250c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten};
25175e6301baa78b2dff00e2cc3051301c32618acd7H Hartley SweetenMODULE_DEVICE_TABLE(pci, adl_pci6208_pci_table);
252c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
25375e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic struct pci_driver adl_pci6208_pci_driver = {
25475e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.name		= "adl_pci6208",
25575e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.id_table	= adl_pci6208_pci_table,
25675e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.probe		= adl_pci6208_pci_probe,
2579901a4d75d007686e8f6473189cafc4b216b7449Peter Huewe	.remove		= comedi_pci_auto_unconfig,
258c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten};
25975e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenmodule_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver);
260c8d87bcc2263401e60c08611e16e6a6481f29ef4H Hartley Sweeten
26190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
26290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
26390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
264