]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/comedi/drivers/pcm3730.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[mv-sheeva.git] / drivers / staging / comedi / drivers / pcm3730.c
1 /*
2  * comedi/drivers/pcm3730.c
3  * Driver for PCM3730 and clones
4  * Blaine Lee
5  * from pcl725 by David S.
6  */
7 /*
8 Driver: pcm3730
9 Description: PCM3730
10 Author: Blaine Lee
11 Devices: [Advantech] PCM-3730 (pcm3730)
12 Status: unknown
13
14 Configuration options:
15   [0] - I/O port base
16 */
17
18 #include "../comedidev.h"
19
20 #include <linux/ioport.h>
21
22 #define PCM3730_SIZE 4          /*  consecutive io port addresses */
23
24 #define PCM3730_DOA 0           /*  offsets for each port */
25 #define PCM3730_DOB 2
26 #define PCM3730_DOC 3
27 #define PCM3730_DIA 0
28 #define PCM3730_DIB 2
29 #define PCM3730_DIC 3
30
31 static int pcm3730_attach(struct comedi_device *dev,
32                           struct comedi_devconfig *it);
33 static int pcm3730_detach(struct comedi_device *dev);
34 static struct comedi_driver driver_pcm3730 = {
35         .driver_name = "pcm3730",
36         .module = THIS_MODULE,
37         .attach = pcm3730_attach,
38         .detach = pcm3730_detach,
39 };
40
41 COMEDI_INITCLEANUP(driver_pcm3730);
42
43 static int pcm3730_do_insn_bits(struct comedi_device *dev,
44                                 struct comedi_subdevice *s,
45                                 struct comedi_insn *insn, unsigned int *data)
46 {
47         if (insn->n != 2)
48                 return -EINVAL;
49         if (data[0]) {
50                 s->state &= ~data[0];
51                 s->state |= (data[0] & data[1]);
52                 outb(s->state, dev->iobase + (unsigned long)(s->private));
53         }
54         data[1] = s->state;
55
56         return 2;
57 }
58
59 static int pcm3730_di_insn_bits(struct comedi_device *dev,
60                                 struct comedi_subdevice *s,
61                                 struct comedi_insn *insn, unsigned int *data)
62 {
63         if (insn->n != 2)
64                 return -EINVAL;
65         data[1] = inb(dev->iobase + (unsigned long)(s->private));
66         return 2;
67 }
68
69 static int pcm3730_attach(struct comedi_device *dev,
70                           struct comedi_devconfig *it)
71 {
72         struct comedi_subdevice *s;
73         unsigned long iobase;
74
75         iobase = it->options[0];
76         printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
77         if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
78                 printk("I/O port conflict\n");
79                 return -EIO;
80         }
81         dev->iobase = iobase;
82         dev->board_name = "pcm3730";
83         dev->iobase = dev->iobase;
84         dev->irq = 0;
85
86         if (alloc_subdevices(dev, 6) < 0)
87                 return -ENOMEM;
88
89         s = dev->subdevices + 0;
90         s->type = COMEDI_SUBD_DO;
91         s->subdev_flags = SDF_WRITABLE;
92         s->maxdata = 1;
93         s->n_chan = 8;
94         s->insn_bits = pcm3730_do_insn_bits;
95         s->range_table = &range_digital;
96         s->private = (void *)PCM3730_DOA;
97
98         s = dev->subdevices + 1;
99         s->type = COMEDI_SUBD_DO;
100         s->subdev_flags = SDF_WRITABLE;
101         s->maxdata = 1;
102         s->n_chan = 8;
103         s->insn_bits = pcm3730_do_insn_bits;
104         s->range_table = &range_digital;
105         s->private = (void *)PCM3730_DOB;
106
107         s = dev->subdevices + 2;
108         s->type = COMEDI_SUBD_DO;
109         s->subdev_flags = SDF_WRITABLE;
110         s->maxdata = 1;
111         s->n_chan = 8;
112         s->insn_bits = pcm3730_do_insn_bits;
113         s->range_table = &range_digital;
114         s->private = (void *)PCM3730_DOC;
115
116         s = dev->subdevices + 3;
117         s->type = COMEDI_SUBD_DI;
118         s->subdev_flags = SDF_READABLE;
119         s->maxdata = 1;
120         s->n_chan = 8;
121         s->insn_bits = pcm3730_di_insn_bits;
122         s->range_table = &range_digital;
123         s->private = (void *)PCM3730_DIA;
124
125         s = dev->subdevices + 4;
126         s->type = COMEDI_SUBD_DI;
127         s->subdev_flags = SDF_READABLE;
128         s->maxdata = 1;
129         s->n_chan = 8;
130         s->insn_bits = pcm3730_di_insn_bits;
131         s->range_table = &range_digital;
132         s->private = (void *)PCM3730_DIB;
133
134         s = dev->subdevices + 5;
135         s->type = COMEDI_SUBD_DI;
136         s->subdev_flags = SDF_READABLE;
137         s->maxdata = 1;
138         s->n_chan = 8;
139         s->insn_bits = pcm3730_di_insn_bits;
140         s->range_table = &range_digital;
141         s->private = (void *)PCM3730_DIC;
142
143         printk(KERN_INFO "\n");
144
145         return 0;
146 }
147
148 static int pcm3730_detach(struct comedi_device *dev)
149 {
150         printk(KERN_INFO "comedi%d: pcm3730: remove\n", dev->minor);
151
152         if (dev->iobase)
153                 release_region(dev->iobase, PCM3730_SIZE);
154
155         return 0;
156 }