156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware/*
256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    comedi/drivers/aio_iiro_16.c
456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
56cd5a9a35c3de4ed28b55212698fe69c328e4206Uwe Kleine-König    Driver for Access I/O Products PC-104 AIO-IIRO-16 Digital I/O board
656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    Copyright (C) 2006 C&C Technologies, Inc.
756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    This program is free software; you can redistribute it and/or modify
956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    it under the terms of the GNU General Public License as published by
1056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    the Free Software Foundation; either version 2 of the License, or
1156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    (at your option) any later version.
1256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
1356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    This program is distributed in the hope that it will be useful,
1456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    but WITHOUT ANY WARRANTY; without even the implied warranty of
1556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    GNU General Public License for more details.
1756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
1856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    You should have received a copy of the GNU General Public License
1956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    along with this program; if not, write to the Free Software
2056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware*/
2256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
2356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware/*
2456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
2556af390d24e57d089bf331843f7e2b3b067b2a90Zachary WareDriver: aio_iiro_16
266cd5a9a35c3de4ed28b55212698fe69c328e4206Uwe Kleine-KönigDescription: Access I/O Products PC-104 IIRO16 Relay And Isolated Input Board
2756af390d24e57d089bf331843f7e2b3b067b2a90Zachary WareAuthor: Zachary Ware <zach.ware@cctechnol.com>
2856af390d24e57d089bf331843f7e2b3b067b2a90Zachary WareDevices:
296cd5a9a35c3de4ed28b55212698fe69c328e4206Uwe Kleine-König [Access I/O] PC-104 AIO12-8
3056af390d24e57d089bf331843f7e2b3b067b2a90Zachary WareStatus: experimental
3156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
3256af390d24e57d089bf331843f7e2b3b067b2a90Zachary WareConfiguration Options:
3356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware  [0] - I/O port base address
3456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
3556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware*/
3656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
3756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#include "../comedidev.h"
3856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#include <linux/ioport.h>
3956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
4056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#define AIO_IIRO_16_SIZE	0x08
4156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#define AIO_IIRO_16_RELAY_0_7	0x00
4256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#define AIO_IIRO_16_INPUT_0_7	0x01
4356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#define AIO_IIRO_16_IRQ		0x02
4456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#define AIO_IIRO_16_RELAY_8_15	0x04
4556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware#define AIO_IIRO_16_INPUT_8_15	0x05
4656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
4728fa7754e5a3fe9f696643808862d37b5ffc3083Bill Pembertonstruct aio_iiro_16_board {
4856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	const char *name;
4956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	int do_;
5056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	int di;
5128fa7754e5a3fe9f696643808862d37b5ffc3083Bill Pemberton};
5256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
5328fa7754e5a3fe9f696643808862d37b5ffc3083Bill Pembertonstatic const struct aio_iiro_16_board aio_iiro_16_boards[] = {
5456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	{
550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "aio_iiro_16",
560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .di = 16,
570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .do_ = 16},
5856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware};
5956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
6028fa7754e5a3fe9f696643808862d37b5ffc3083Bill Pemberton#define	thisboard	((const struct aio_iiro_16_board *) dev->board_ptr)
6156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
6255d996391fa73df06e33609f0d6f82de775d1045Bill Pembertonstruct aio_iiro_16_private {
6356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	int data;
6456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	struct pci_dev *pci_dev;
65790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	unsigned int ao_readback[2];
6655d996391fa73df06e33609f0d6f82de775d1045Bill Pemberton};
6756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
6855d996391fa73df06e33609f0d6f82de775d1045Bill Pemberton#define	devpriv	((struct aio_iiro_16_private *) dev->private)
6956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int aio_iiro_16_attach(struct comedi_device *dev,
710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      struct comedi_devconfig *it);
7256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
73da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int aio_iiro_16_detach(struct comedi_device *dev);
7456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
75139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_aio_iiro_16 = {
7668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "aio_iiro_16",
7768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
7868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = aio_iiro_16_attach,
7968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = aio_iiro_16_detach,
8068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.board_name = &aio_iiro_16_boards[0].name,
8168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.offset = sizeof(struct aio_iiro_16_board),
828629efa4cbf6f89a54a85af4b8bc31762af01800Bill Pemberton	.num_names = ARRAY_SIZE(aio_iiro_16_boards),
8356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware};
8456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
85da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  struct comedi_subdevice *s,
870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  struct comedi_insn *insn,
880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  unsigned int *data);
8956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
90da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					   struct comedi_subdevice *s,
920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					   struct comedi_insn *insn,
930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					   unsigned int *data);
9456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int aio_iiro_16_attach(struct comedi_device *dev,
960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      struct comedi_devconfig *it)
9756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware{
9856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	int iobase;
9934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
10056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
101e20ad20d849eb902628553be1fd2dc9ccc40a4bdBenjamin Adolphi	printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor);
10256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
10356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	dev->board_name = thisboard->name;
10456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
10556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	iobase = it->options[0];
10656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
10756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	if (!request_region(iobase, AIO_IIRO_16_SIZE, dev->board_name)) {
10856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		printk("I/O port conflict");
10956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		return -EIO;
11056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	}
11156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
11256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	dev->iobase = iobase;
11356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
11455d996391fa73df06e33609f0d6f82de775d1045Bill Pemberton	if (alloc_private(dev, sizeof(struct aio_iiro_16_private)) < 0)
11556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		return -ENOMEM;
11656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
11756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	if (alloc_subdevices(dev, 2) < 0)
11856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		return -ENOMEM;
11956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
12056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s = dev->subdevices + 0;
12156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->type = COMEDI_SUBD_DIO;
12256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->subdev_flags = SDF_WRITABLE;
12356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->n_chan = 16;
12456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->maxdata = 1;
12556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->range_table = &range_digital;
12656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->insn_bits = aio_iiro_16_dio_insn_bits_write;
12756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
12856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s = dev->subdevices + 1;
12956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->type = COMEDI_SUBD_DIO;
13056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->subdev_flags = SDF_READABLE;
13156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->n_chan = 16;
13256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->maxdata = 1;
13356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->range_table = &range_digital;
13456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	s->insn_bits = aio_iiro_16_dio_insn_bits_read;
13556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
13656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	printk("attached\n");
13756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
13856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	return 1;
13956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware}
14056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
141da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int aio_iiro_16_detach(struct comedi_device *dev)
14256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware{
143e20ad20d849eb902628553be1fd2dc9ccc40a4bdBenjamin Adolphi	printk(KERN_INFO "comedi%d: aio_iiro_16: remove\n", dev->minor);
14456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
14556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	if (dev->iobase)
14656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		release_region(dev->iobase, AIO_IIRO_16_SIZE);
14756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
14856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	return 0;
14956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware}
15056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
151da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
1520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					   struct comedi_subdevice *s,
1530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					   struct comedi_insn *insn,
1540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					   unsigned int *data)
15556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware{
15656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	if (insn->n != 2)
15756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		return -EINVAL;
15856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
15956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	if (data[0]) {
16056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		s->state &= ~data[0];
16156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		s->state |= data[0] & data[1];
16256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
16356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		outb((s->state >> 8) & 0xff,
1640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     dev->iobase + AIO_IIRO_16_RELAY_8_15);
16556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	}
16656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
16756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	data[1] = s->state;
16856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
16956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	return 2;
17056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware}
17156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
172da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
1730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  struct comedi_subdevice *s,
1740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  struct comedi_insn *insn,
1750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  unsigned int *data)
17656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware{
17756af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	if (insn->n != 2)
17856af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware		return -EINVAL;
17956af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
18056af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	data[1] = 0;
18156af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
18256af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
18356af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
18456af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware	return 2;
18556af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware}
18656af390d24e57d089bf331843f7e2b3b067b2a90Zachary Ware
1877114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_aio_iiro_16_init_module(void)
1887114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
1897114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	return comedi_driver_register(&driver_aio_iiro_16);
1907114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
1917114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
1927114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_aio_iiro_16_cleanup_module(void)
1937114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
1947114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	comedi_driver_unregister(&driver_aio_iiro_16);
1957114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
1967114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
1977114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_aio_iiro_16_init_module);
1987114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_aio_iiro_16_cleanup_module);
19990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
20090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
20190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
20290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
203