xref: /openbmc/linux/drivers/comedi/drivers/pcl724.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
18ffdff6aSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
28ffdff6aSGreg Kroah-Hartman /*
38ffdff6aSGreg Kroah-Hartman  * pcl724.c
48ffdff6aSGreg Kroah-Hartman  * Comedi driver for 8255 based ISA and PC/104 DIO boards
58ffdff6aSGreg Kroah-Hartman  *
68ffdff6aSGreg Kroah-Hartman  * Michal Dobes <dobes@tesnet.cz>
78ffdff6aSGreg Kroah-Hartman  */
88ffdff6aSGreg Kroah-Hartman 
98ffdff6aSGreg Kroah-Hartman /*
108ffdff6aSGreg Kroah-Hartman  * Driver: pcl724
118ffdff6aSGreg Kroah-Hartman  * Description: Comedi driver for 8255 based ISA DIO boards
128ffdff6aSGreg Kroah-Hartman  * Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
138ffdff6aSGreg Kroah-Hartman  *  [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio),
148ffdff6aSGreg Kroah-Hartman  *  [WinSystems] PCM-IO48 (pcmio48),
158ffdff6aSGreg Kroah-Hartman  *  [Diamond Systems] ONYX-MM-DIO (onyx-mm-dio)
168ffdff6aSGreg Kroah-Hartman  * Author: Michal Dobes <dobes@tesnet.cz>
178ffdff6aSGreg Kroah-Hartman  * Status: untested
188ffdff6aSGreg Kroah-Hartman  *
198ffdff6aSGreg Kroah-Hartman  * Configuration options:
208ffdff6aSGreg Kroah-Hartman  *   [0] - IO Base
218ffdff6aSGreg Kroah-Hartman  *   [1] - IRQ (not supported)
228ffdff6aSGreg Kroah-Hartman  *   [2] - number of DIO (pcl722 and acl7122 boards)
238ffdff6aSGreg Kroah-Hartman  *	   0, 144: 144 DIO configuration
248ffdff6aSGreg Kroah-Hartman  *	   1,  96:  96 DIO configuration
258ffdff6aSGreg Kroah-Hartman  */
268ffdff6aSGreg Kroah-Hartman 
278ffdff6aSGreg Kroah-Hartman #include <linux/module.h>
28df0e68c1SIan Abbott #include <linux/comedi/comedidev.h>
29*631e272bSIan Abbott #include <linux/comedi/comedi_8255.h>
308ffdff6aSGreg Kroah-Hartman 
318ffdff6aSGreg Kroah-Hartman struct pcl724_board {
328ffdff6aSGreg Kroah-Hartman 	const char *name;
338ffdff6aSGreg Kroah-Hartman 	unsigned int io_range;
348ffdff6aSGreg Kroah-Hartman 	unsigned int can_have96:1;
358ffdff6aSGreg Kroah-Hartman 	unsigned int is_pet48:1;
368ffdff6aSGreg Kroah-Hartman 	int numofports;
378ffdff6aSGreg Kroah-Hartman };
388ffdff6aSGreg Kroah-Hartman 
398ffdff6aSGreg Kroah-Hartman static const struct pcl724_board boardtypes[] = {
408ffdff6aSGreg Kroah-Hartman 	{
418ffdff6aSGreg Kroah-Hartman 		.name		= "pcl724",
428ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x04,
438ffdff6aSGreg Kroah-Hartman 		.numofports	= 1,	/* 24 DIO channels */
448ffdff6aSGreg Kroah-Hartman 	}, {
458ffdff6aSGreg Kroah-Hartman 		.name		= "pcl722",
468ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x20,
478ffdff6aSGreg Kroah-Hartman 		.can_have96	= 1,
488ffdff6aSGreg Kroah-Hartman 		.numofports	= 6,	/* 144 (or 96) DIO channels */
498ffdff6aSGreg Kroah-Hartman 	}, {
508ffdff6aSGreg Kroah-Hartman 		.name		= "pcl731",
518ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x08,
528ffdff6aSGreg Kroah-Hartman 		.numofports	= 2,	/* 48 DIO channels */
538ffdff6aSGreg Kroah-Hartman 	}, {
548ffdff6aSGreg Kroah-Hartman 		.name		= "acl7122",
558ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x20,
568ffdff6aSGreg Kroah-Hartman 		.can_have96	= 1,
578ffdff6aSGreg Kroah-Hartman 		.numofports	= 6,	/* 144 (or 96) DIO channels */
588ffdff6aSGreg Kroah-Hartman 	}, {
598ffdff6aSGreg Kroah-Hartman 		.name		= "acl7124",
608ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x04,
618ffdff6aSGreg Kroah-Hartman 		.numofports	= 1,	/* 24 DIO channels */
628ffdff6aSGreg Kroah-Hartman 	}, {
638ffdff6aSGreg Kroah-Hartman 		.name		= "pet48dio",
648ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x02,
658ffdff6aSGreg Kroah-Hartman 		.is_pet48	= 1,
668ffdff6aSGreg Kroah-Hartman 		.numofports	= 2,	/* 48 DIO channels */
678ffdff6aSGreg Kroah-Hartman 	}, {
688ffdff6aSGreg Kroah-Hartman 		.name		= "pcmio48",
698ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x08,
708ffdff6aSGreg Kroah-Hartman 		.numofports	= 2,	/* 48 DIO channels */
718ffdff6aSGreg Kroah-Hartman 	}, {
728ffdff6aSGreg Kroah-Hartman 		.name		= "onyx-mm-dio",
738ffdff6aSGreg Kroah-Hartman 		.io_range	= 0x10,
748ffdff6aSGreg Kroah-Hartman 		.numofports	= 2,	/* 48 DIO channels */
758ffdff6aSGreg Kroah-Hartman 	},
768ffdff6aSGreg Kroah-Hartman };
778ffdff6aSGreg Kroah-Hartman 
pcl724_8255mapped_io(struct comedi_device * dev,int dir,int port,int data,unsigned long iobase)788ffdff6aSGreg Kroah-Hartman static int pcl724_8255mapped_io(struct comedi_device *dev,
798ffdff6aSGreg Kroah-Hartman 				int dir, int port, int data,
808ffdff6aSGreg Kroah-Hartman 				unsigned long iobase)
818ffdff6aSGreg Kroah-Hartman {
828ffdff6aSGreg Kroah-Hartman 	int movport = I8255_SIZE * (iobase >> 12);
838ffdff6aSGreg Kroah-Hartman 
848ffdff6aSGreg Kroah-Hartman 	iobase &= 0x0fff;
858ffdff6aSGreg Kroah-Hartman 
868ffdff6aSGreg Kroah-Hartman 	outb(port + movport, iobase);
878ffdff6aSGreg Kroah-Hartman 	if (dir) {
888ffdff6aSGreg Kroah-Hartman 		outb(data, iobase + 1);
898ffdff6aSGreg Kroah-Hartman 		return 0;
908ffdff6aSGreg Kroah-Hartman 	}
918ffdff6aSGreg Kroah-Hartman 	return inb(iobase + 1);
928ffdff6aSGreg Kroah-Hartman }
938ffdff6aSGreg Kroah-Hartman 
pcl724_attach(struct comedi_device * dev,struct comedi_devconfig * it)948ffdff6aSGreg Kroah-Hartman static int pcl724_attach(struct comedi_device *dev,
958ffdff6aSGreg Kroah-Hartman 			 struct comedi_devconfig *it)
968ffdff6aSGreg Kroah-Hartman {
978ffdff6aSGreg Kroah-Hartman 	const struct pcl724_board *board = dev->board_ptr;
988ffdff6aSGreg Kroah-Hartman 	struct comedi_subdevice *s;
998ffdff6aSGreg Kroah-Hartman 	unsigned long iobase;
1008ffdff6aSGreg Kroah-Hartman 	unsigned int iorange;
1018ffdff6aSGreg Kroah-Hartman 	int n_subdevices;
1028ffdff6aSGreg Kroah-Hartman 	int ret;
1038ffdff6aSGreg Kroah-Hartman 	int i;
1048ffdff6aSGreg Kroah-Hartman 
1058ffdff6aSGreg Kroah-Hartman 	iorange = board->io_range;
1068ffdff6aSGreg Kroah-Hartman 	n_subdevices = board->numofports;
1078ffdff6aSGreg Kroah-Hartman 
1088ffdff6aSGreg Kroah-Hartman 	/* Handle PCL-724 in 96 DIO configuration */
1098ffdff6aSGreg Kroah-Hartman 	if (board->can_have96 &&
1108ffdff6aSGreg Kroah-Hartman 	    (it->options[2] == 1 || it->options[2] == 96)) {
1118ffdff6aSGreg Kroah-Hartman 		iorange = 0x10;
1128ffdff6aSGreg Kroah-Hartman 		n_subdevices = 4;
1138ffdff6aSGreg Kroah-Hartman 	}
1148ffdff6aSGreg Kroah-Hartman 
1158ffdff6aSGreg Kroah-Hartman 	ret = comedi_request_region(dev, it->options[0], iorange);
1168ffdff6aSGreg Kroah-Hartman 	if (ret)
1178ffdff6aSGreg Kroah-Hartman 		return ret;
1188ffdff6aSGreg Kroah-Hartman 
1198ffdff6aSGreg Kroah-Hartman 	ret = comedi_alloc_subdevices(dev, n_subdevices);
1208ffdff6aSGreg Kroah-Hartman 	if (ret)
1218ffdff6aSGreg Kroah-Hartman 		return ret;
1228ffdff6aSGreg Kroah-Hartman 
1238ffdff6aSGreg Kroah-Hartman 	for (i = 0; i < dev->n_subdevices; i++) {
1248ffdff6aSGreg Kroah-Hartman 		s = &dev->subdevices[i];
1258ffdff6aSGreg Kroah-Hartman 		if (board->is_pet48) {
1268ffdff6aSGreg Kroah-Hartman 			iobase = dev->iobase + (i * 0x1000);
1278ffdff6aSGreg Kroah-Hartman 			ret = subdev_8255_init(dev, s, pcl724_8255mapped_io,
1288ffdff6aSGreg Kroah-Hartman 					       iobase);
1298ffdff6aSGreg Kroah-Hartman 		} else {
1308ffdff6aSGreg Kroah-Hartman 			ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
1318ffdff6aSGreg Kroah-Hartman 		}
1328ffdff6aSGreg Kroah-Hartman 		if (ret)
1338ffdff6aSGreg Kroah-Hartman 			return ret;
1348ffdff6aSGreg Kroah-Hartman 	}
1358ffdff6aSGreg Kroah-Hartman 
1368ffdff6aSGreg Kroah-Hartman 	return 0;
1378ffdff6aSGreg Kroah-Hartman }
1388ffdff6aSGreg Kroah-Hartman 
1398ffdff6aSGreg Kroah-Hartman static struct comedi_driver pcl724_driver = {
1408ffdff6aSGreg Kroah-Hartman 	.driver_name	= "pcl724",
1418ffdff6aSGreg Kroah-Hartman 	.module		= THIS_MODULE,
1428ffdff6aSGreg Kroah-Hartman 	.attach		= pcl724_attach,
1438ffdff6aSGreg Kroah-Hartman 	.detach		= comedi_legacy_detach,
1448ffdff6aSGreg Kroah-Hartman 	.board_name	= &boardtypes[0].name,
1458ffdff6aSGreg Kroah-Hartman 	.num_names	= ARRAY_SIZE(boardtypes),
1468ffdff6aSGreg Kroah-Hartman 	.offset		= sizeof(struct pcl724_board),
1478ffdff6aSGreg Kroah-Hartman };
1488ffdff6aSGreg Kroah-Hartman module_comedi_driver(pcl724_driver);
1498ffdff6aSGreg Kroah-Hartman 
1508ffdff6aSGreg Kroah-Hartman MODULE_AUTHOR("Comedi https://www.comedi.org");
1518ffdff6aSGreg Kroah-Hartman MODULE_DESCRIPTION("Comedi driver for 8255 based ISA and PC/104 DIO boards");
1528ffdff6aSGreg Kroah-Hartman MODULE_LICENSE("GPL");
153