contec_pci_dio.c revision 33782dd5edf8db3cdb7c81a3523bf743dd0209b7
1/*
2    comedi/drivers/contec_pci_dio.c
3
4    COMEDI - Linux Control and Measurement Device Interface
5    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22/*
23Driver: contec_pci_dio
24Description: Contec PIO1616L digital I/O board
25Devices: [Contec] PIO1616L (contec_pci_dio)
26Author: Stefano Rivoir <s.rivoir@gts.it>
27Updated: Wed, 27 Jun 2007 13:00:06 +0100
28Status: works
29
30Configuration Options: not applicable, uses comedi PCI auto config
31*/
32
33#include <linux/pci.h>
34
35#include "../comedidev.h"
36
37#define PCI_DEVICE_ID_PIO1616L 0x8172
38
39/*
40 * Register map
41 */
42#define PIO1616L_DI_REG		0x00
43#define PIO1616L_DO_REG		0x02
44
45static int contec_do_insn_bits(struct comedi_device *dev,
46			       struct comedi_subdevice *s,
47			       struct comedi_insn *insn, unsigned int *data)
48{
49	unsigned int mask = data[0];
50	unsigned int bits = data[1];
51
52	if (mask) {
53		s->state &= ~mask;
54		s->state |= (bits & mask);
55
56		outw(s->state, dev->iobase + PIO1616L_DO_REG);
57	}
58
59	data[1] = s->state;
60
61	return insn->n;
62}
63
64static int contec_di_insn_bits(struct comedi_device *dev,
65			       struct comedi_subdevice *s,
66			       struct comedi_insn *insn, unsigned int *data)
67{
68	data[1] = inw(dev->iobase + PIO1616L_DI_REG);
69
70	return insn->n;
71}
72
73static int contec_auto_attach(struct comedi_device *dev,
74					unsigned long context_unused)
75{
76	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
77	struct comedi_subdevice *s;
78	int ret;
79
80	dev->board_name = dev->driver->driver_name;
81
82	ret = comedi_pci_enable(pcidev, dev->board_name);
83	if (ret)
84		return ret;
85	dev->iobase = pci_resource_start(pcidev, 0);
86
87	ret = comedi_alloc_subdevices(dev, 2);
88	if (ret)
89		return ret;
90
91	s = &dev->subdevices[0];
92	s->type		= COMEDI_SUBD_DI;
93	s->subdev_flags	= SDF_READABLE;
94	s->n_chan	= 16;
95	s->maxdata	= 1;
96	s->range_table	= &range_digital;
97	s->insn_bits	= contec_di_insn_bits;
98
99	s = &dev->subdevices[1];
100	s->type		= COMEDI_SUBD_DO;
101	s->subdev_flags	= SDF_WRITABLE;
102	s->n_chan	= 16;
103	s->maxdata	= 1;
104	s->range_table	= &range_digital;
105	s->insn_bits	= contec_do_insn_bits;
106
107	dev_info(dev->class_dev, "%s attached\n", dev->board_name);
108
109	return 0;
110}
111
112static void contec_detach(struct comedi_device *dev)
113{
114	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
115
116	if (pcidev) {
117		if (dev->iobase)
118			comedi_pci_disable(pcidev);
119	}
120}
121
122static struct comedi_driver contec_pci_dio_driver = {
123	.driver_name	= "contec_pci_dio",
124	.module		= THIS_MODULE,
125	.auto_attach	= contec_auto_attach,
126	.detach		= contec_detach,
127};
128
129static int contec_pci_dio_pci_probe(struct pci_dev *dev,
130					      const struct pci_device_id *ent)
131{
132	return comedi_pci_auto_config(dev, &contec_pci_dio_driver);
133}
134
135static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = {
136	{ PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) },
137	{ 0 }
138};
139MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table);
140
141static struct pci_driver contec_pci_dio_pci_driver = {
142	.name		= "contec_pci_dio",
143	.id_table	= contec_pci_dio_pci_table,
144	.probe		= contec_pci_dio_pci_probe,
145	.remove		= comedi_pci_auto_unconfig,
146};
147module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver);
148
149MODULE_AUTHOR("Comedi http://www.comedi.org");
150MODULE_DESCRIPTION("Comedi low-level driver");
151MODULE_LICENSE("GPL");
152