contec_pci_dio.c revision b31654fe4b79ee650d12e194016c47e3640f440d
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 "../comedidev.h"
34
35#define PCI_DEVICE_ID_PIO1616L 0x8172
36
37/*
38 * Register map
39 */
40#define PIO1616L_DI_REG		0x00
41#define PIO1616L_DO_REG		0x02
42
43static int contec_do_insn_bits(struct comedi_device *dev,
44			       struct comedi_subdevice *s,
45			       struct comedi_insn *insn, unsigned int *data)
46{
47	unsigned int mask = data[0];
48	unsigned int bits = data[1];
49
50	if (mask) {
51		s->state &= ~mask;
52		s->state |= (bits & mask);
53
54		outw(s->state, dev->iobase + PIO1616L_DO_REG);
55	}
56
57	data[1] = s->state;
58
59	return insn->n;
60}
61
62static int contec_di_insn_bits(struct comedi_device *dev,
63			       struct comedi_subdevice *s,
64			       struct comedi_insn *insn, unsigned int *data)
65{
66	data[1] = inw(dev->iobase + PIO1616L_DI_REG);
67
68	return insn->n;
69}
70
71static int contec_attach_pci(struct comedi_device *dev,
72			     struct pci_dev *pcidev)
73{
74	struct comedi_subdevice *s;
75	int ret;
76
77	comedi_set_hw_dev(dev, &pcidev->dev);
78
79	dev->board_name = dev->driver->driver_name;
80
81	ret = comedi_pci_enable(pcidev, dev->board_name);
82	if (ret)
83		return ret;
84	dev->iobase = pci_resource_start(pcidev, 0);
85
86	ret = comedi_alloc_subdevices(dev, 2);
87	if (ret)
88		return ret;
89
90	s = &dev->subdevices[0];
91	s->type		= COMEDI_SUBD_DI;
92	s->subdev_flags	= SDF_READABLE;
93	s->n_chan	= 16;
94	s->maxdata	= 1;
95	s->range_table	= &range_digital;
96	s->insn_bits	= contec_di_insn_bits;
97
98	s = &dev->subdevices[1];
99	s->type		= COMEDI_SUBD_DO;
100	s->subdev_flags	= SDF_WRITABLE;
101	s->n_chan	= 16;
102	s->maxdata	= 1;
103	s->range_table	= &range_digital;
104	s->insn_bits	= contec_do_insn_bits;
105
106	dev_info(dev->class_dev, "%s attached\n", dev->board_name);
107
108	return 0;
109}
110
111static void contec_detach(struct comedi_device *dev)
112{
113	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
114
115	if (pcidev) {
116		if (dev->iobase)
117			comedi_pci_disable(pcidev);
118	}
119}
120
121static struct comedi_driver contec_pci_dio_driver = {
122	.driver_name	= "contec_pci_dio",
123	.module		= THIS_MODULE,
124	.attach_pci	= contec_attach_pci,
125	.detach		= contec_detach,
126};
127
128static int __devinit contec_pci_dio_pci_probe(struct pci_dev *dev,
129					      const struct pci_device_id *ent)
130{
131	return comedi_pci_auto_config(dev, &contec_pci_dio_driver);
132}
133
134static void __devexit contec_pci_dio_pci_remove(struct pci_dev *dev)
135{
136	comedi_pci_auto_unconfig(dev);
137}
138
139static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = {
140	{ PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) },
141	{ 0 }
142};
143MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table);
144
145static struct pci_driver contec_pci_dio_pci_driver = {
146	.name		= "contec_pci_dio",
147	.id_table	= contec_pci_dio_pci_table,
148	.probe		= contec_pci_dio_pci_probe,
149	.remove		= __devexit_p(contec_pci_dio_pci_remove),
150};
151module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver);
152
153MODULE_AUTHOR("Comedi http://www.comedi.org");
154MODULE_DESCRIPTION("Comedi low-level driver");
155MODULE_LICENSE("GPL");
156