1501d675db67e43cff47fa8138374679122baefb4David Schleef/*
2501d675db67e43cff47fa8138374679122baefb4David Schleef * comedi/drivers/pcl725.c
3501d675db67e43cff47fa8138374679122baefb4David Schleef * Driver for PCL725 and clones
4501d675db67e43cff47fa8138374679122baefb4David Schleef * David A. Schleef
5501d675db67e43cff47fa8138374679122baefb4David Schleef */
6501d675db67e43cff47fa8138374679122baefb4David Schleef/*
7501d675db67e43cff47fa8138374679122baefb4David SchleefDriver: pcl725
8501d675db67e43cff47fa8138374679122baefb4David SchleefDescription: Advantech PCL-725 (& compatibles)
9501d675db67e43cff47fa8138374679122baefb4David SchleefAuthor: ds
10501d675db67e43cff47fa8138374679122baefb4David SchleefStatus: unknown
11501d675db67e43cff47fa8138374679122baefb4David SchleefDevices: [Advantech] PCL-725 (pcl725)
12501d675db67e43cff47fa8138374679122baefb4David Schleef*/
13501d675db67e43cff47fa8138374679122baefb4David Schleef
14501d675db67e43cff47fa8138374679122baefb4David Schleef#include "../comedidev.h"
15501d675db67e43cff47fa8138374679122baefb4David Schleef
16501d675db67e43cff47fa8138374679122baefb4David Schleef#include <linux/ioport.h>
17501d675db67e43cff47fa8138374679122baefb4David Schleef
18501d675db67e43cff47fa8138374679122baefb4David Schleef#define PCL725_SIZE 2
19501d675db67e43cff47fa8138374679122baefb4David Schleef
20501d675db67e43cff47fa8138374679122baefb4David Schleef#define PCL725_DO 0
21501d675db67e43cff47fa8138374679122baefb4David Schleef#define PCL725_DI 1
22501d675db67e43cff47fa8138374679122baefb4David Schleef
230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pcl725_attach(struct comedi_device *dev,
240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			 struct comedi_devconfig *it);
25da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_detach(struct comedi_device *dev);
26139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_pcl725 = {
2768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "pcl725",
2868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
2968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = pcl725_attach,
3068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = pcl725_detach,
31501d675db67e43cff47fa8138374679122baefb4David Schleef};
32501d675db67e43cff47fa8138374679122baefb4David Schleef
337114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_pcl725_init_module(void)
347114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
357114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	return comedi_driver_register(&driver_pcl725);
367114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
377114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
387114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_pcl725_cleanup_module(void)
397114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
407114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	comedi_driver_unregister(&driver_pcl725);
417114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
427114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
437114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_pcl725_init_module);
447114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_pcl725_cleanup_module);
45501d675db67e43cff47fa8138374679122baefb4David Schleef
46da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			  struct comedi_insn *insn, unsigned int *data)
48501d675db67e43cff47fa8138374679122baefb4David Schleef{
49501d675db67e43cff47fa8138374679122baefb4David Schleef	if (insn->n != 2)
50501d675db67e43cff47fa8138374679122baefb4David Schleef		return -EINVAL;
51501d675db67e43cff47fa8138374679122baefb4David Schleef
52501d675db67e43cff47fa8138374679122baefb4David Schleef	if (data[0]) {
53501d675db67e43cff47fa8138374679122baefb4David Schleef		s->state &= ~data[0];
54501d675db67e43cff47fa8138374679122baefb4David Schleef		s->state |= (data[0] & data[1]);
55501d675db67e43cff47fa8138374679122baefb4David Schleef		outb(s->state, dev->iobase + PCL725_DO);
56501d675db67e43cff47fa8138374679122baefb4David Schleef	}
57501d675db67e43cff47fa8138374679122baefb4David Schleef
58501d675db67e43cff47fa8138374679122baefb4David Schleef	data[1] = s->state;
59501d675db67e43cff47fa8138374679122baefb4David Schleef
60501d675db67e43cff47fa8138374679122baefb4David Schleef	return 2;
61501d675db67e43cff47fa8138374679122baefb4David Schleef}
62501d675db67e43cff47fa8138374679122baefb4David Schleef
63da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s,
640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			  struct comedi_insn *insn, unsigned int *data)
65501d675db67e43cff47fa8138374679122baefb4David Schleef{
66501d675db67e43cff47fa8138374679122baefb4David Schleef	if (insn->n != 2)
67501d675db67e43cff47fa8138374679122baefb4David Schleef		return -EINVAL;
68501d675db67e43cff47fa8138374679122baefb4David Schleef
69501d675db67e43cff47fa8138374679122baefb4David Schleef	data[1] = inb(dev->iobase + PCL725_DI);
70501d675db67e43cff47fa8138374679122baefb4David Schleef
71501d675db67e43cff47fa8138374679122baefb4David Schleef	return 2;
72501d675db67e43cff47fa8138374679122baefb4David Schleef}
73501d675db67e43cff47fa8138374679122baefb4David Schleef
74da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
75501d675db67e43cff47fa8138374679122baefb4David Schleef{
7634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
77501d675db67e43cff47fa8138374679122baefb4David Schleef	unsigned long iobase;
78501d675db67e43cff47fa8138374679122baefb4David Schleef
79501d675db67e43cff47fa8138374679122baefb4David Schleef	iobase = it->options[0];
80acb60e915a68c44757e12c45a8cede11339b6172Benjamin Adolphi	printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
81501d675db67e43cff47fa8138374679122baefb4David Schleef	if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
82501d675db67e43cff47fa8138374679122baefb4David Schleef		printk("I/O port conflict\n");
83501d675db67e43cff47fa8138374679122baefb4David Schleef		return -EIO;
84501d675db67e43cff47fa8138374679122baefb4David Schleef	}
85501d675db67e43cff47fa8138374679122baefb4David Schleef	dev->board_name = "pcl725";
86501d675db67e43cff47fa8138374679122baefb4David Schleef	dev->iobase = iobase;
87501d675db67e43cff47fa8138374679122baefb4David Schleef	dev->irq = 0;
88501d675db67e43cff47fa8138374679122baefb4David Schleef
89501d675db67e43cff47fa8138374679122baefb4David Schleef	if (alloc_subdevices(dev, 2) < 0)
90501d675db67e43cff47fa8138374679122baefb4David Schleef		return -ENOMEM;
91501d675db67e43cff47fa8138374679122baefb4David Schleef
92501d675db67e43cff47fa8138374679122baefb4David Schleef	s = dev->subdevices + 0;
93501d675db67e43cff47fa8138374679122baefb4David Schleef	/* do */
94501d675db67e43cff47fa8138374679122baefb4David Schleef	s->type = COMEDI_SUBD_DO;
95501d675db67e43cff47fa8138374679122baefb4David Schleef	s->subdev_flags = SDF_WRITABLE;
96501d675db67e43cff47fa8138374679122baefb4David Schleef	s->maxdata = 1;
97501d675db67e43cff47fa8138374679122baefb4David Schleef	s->n_chan = 8;
98501d675db67e43cff47fa8138374679122baefb4David Schleef	s->insn_bits = pcl725_do_insn;
99501d675db67e43cff47fa8138374679122baefb4David Schleef	s->range_table = &range_digital;
100501d675db67e43cff47fa8138374679122baefb4David Schleef
101501d675db67e43cff47fa8138374679122baefb4David Schleef	s = dev->subdevices + 1;
102501d675db67e43cff47fa8138374679122baefb4David Schleef	/* di */
103501d675db67e43cff47fa8138374679122baefb4David Schleef	s->type = COMEDI_SUBD_DI;
104501d675db67e43cff47fa8138374679122baefb4David Schleef	s->subdev_flags = SDF_READABLE;
105501d675db67e43cff47fa8138374679122baefb4David Schleef	s->maxdata = 1;
106501d675db67e43cff47fa8138374679122baefb4David Schleef	s->n_chan = 8;
107501d675db67e43cff47fa8138374679122baefb4David Schleef	s->insn_bits = pcl725_di_insn;
108501d675db67e43cff47fa8138374679122baefb4David Schleef	s->range_table = &range_digital;
109501d675db67e43cff47fa8138374679122baefb4David Schleef
110acb60e915a68c44757e12c45a8cede11339b6172Benjamin Adolphi	printk(KERN_INFO "\n");
111501d675db67e43cff47fa8138374679122baefb4David Schleef
112501d675db67e43cff47fa8138374679122baefb4David Schleef	return 0;
113501d675db67e43cff47fa8138374679122baefb4David Schleef}
114501d675db67e43cff47fa8138374679122baefb4David Schleef
115da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pcl725_detach(struct comedi_device *dev)
116501d675db67e43cff47fa8138374679122baefb4David Schleef{
117acb60e915a68c44757e12c45a8cede11339b6172Benjamin Adolphi	printk(KERN_INFO "comedi%d: pcl725: remove\n", dev->minor);
118501d675db67e43cff47fa8138374679122baefb4David Schleef
119501d675db67e43cff47fa8138374679122baefb4David Schleef	if (dev->iobase)
120501d675db67e43cff47fa8138374679122baefb4David Schleef		release_region(dev->iobase, PCL725_SIZE);
121501d675db67e43cff47fa8138374679122baefb4David Schleef
122501d675db67e43cff47fa8138374679122baefb4David Schleef	return 0;
123501d675db67e43cff47fa8138374679122baefb4David Schleef}
12490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
12590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
12690f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
12790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
128