root/drivers/staging/comedi/drivers/pcl724.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcl724_8255mapped_io
  2. pcl724_attach

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * pcl724.c
   4  * Comedi driver for 8255 based ISA and PC/104 DIO boards
   5  *
   6  * Michal Dobes <dobes@tesnet.cz>
   7  */
   8 
   9 /*
  10  * Driver: pcl724
  11  * Description: Comedi driver for 8255 based ISA DIO boards
  12  * Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
  13  *  [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio),
  14  *  [WinSystems] PCM-IO48 (pcmio48),
  15  *  [Diamond Systems] ONYX-MM-DIO (onyx-mm-dio)
  16  * Author: Michal Dobes <dobes@tesnet.cz>
  17  * Status: untested
  18  *
  19  * Configuration options:
  20  *   [0] - IO Base
  21  *   [1] - IRQ (not supported)
  22  *   [2] - number of DIO (pcl722 and acl7122 boards)
  23  *         0, 144: 144 DIO configuration
  24  *         1,  96:  96 DIO configuration
  25  */
  26 
  27 #include <linux/module.h>
  28 #include "../comedidev.h"
  29 
  30 #include "8255.h"
  31 
  32 struct pcl724_board {
  33         const char *name;
  34         unsigned int io_range;
  35         unsigned int can_have96:1;
  36         unsigned int is_pet48:1;
  37         int numofports;
  38 };
  39 
  40 static const struct pcl724_board boardtypes[] = {
  41         {
  42                 .name           = "pcl724",
  43                 .io_range       = 0x04,
  44                 .numofports     = 1,    /* 24 DIO channels */
  45         }, {
  46                 .name           = "pcl722",
  47                 .io_range       = 0x20,
  48                 .can_have96     = 1,
  49                 .numofports     = 6,    /* 144 (or 96) DIO channels */
  50         }, {
  51                 .name           = "pcl731",
  52                 .io_range       = 0x08,
  53                 .numofports     = 2,    /* 48 DIO channels */
  54         }, {
  55                 .name           = "acl7122",
  56                 .io_range       = 0x20,
  57                 .can_have96     = 1,
  58                 .numofports     = 6,    /* 144 (or 96) DIO channels */
  59         }, {
  60                 .name           = "acl7124",
  61                 .io_range       = 0x04,
  62                 .numofports     = 1,    /* 24 DIO channels */
  63         }, {
  64                 .name           = "pet48dio",
  65                 .io_range       = 0x02,
  66                 .is_pet48       = 1,
  67                 .numofports     = 2,    /* 48 DIO channels */
  68         }, {
  69                 .name           = "pcmio48",
  70                 .io_range       = 0x08,
  71                 .numofports     = 2,    /* 48 DIO channels */
  72         }, {
  73                 .name           = "onyx-mm-dio",
  74                 .io_range       = 0x10,
  75                 .numofports     = 2,    /* 48 DIO channels */
  76         },
  77 };
  78 
  79 static int pcl724_8255mapped_io(struct comedi_device *dev,
  80                                 int dir, int port, int data,
  81                                 unsigned long iobase)
  82 {
  83         int movport = I8255_SIZE * (iobase >> 12);
  84 
  85         iobase &= 0x0fff;
  86 
  87         outb(port + movport, iobase);
  88         if (dir) {
  89                 outb(data, iobase + 1);
  90                 return 0;
  91         }
  92         return inb(iobase + 1);
  93 }
  94 
  95 static int pcl724_attach(struct comedi_device *dev,
  96                          struct comedi_devconfig *it)
  97 {
  98         const struct pcl724_board *board = dev->board_ptr;
  99         struct comedi_subdevice *s;
 100         unsigned long iobase;
 101         unsigned int iorange;
 102         int n_subdevices;
 103         int ret;
 104         int i;
 105 
 106         iorange = board->io_range;
 107         n_subdevices = board->numofports;
 108 
 109         /* Handle PCL-724 in 96 DIO configuration */
 110         if (board->can_have96 &&
 111             (it->options[2] == 1 || it->options[2] == 96)) {
 112                 iorange = 0x10;
 113                 n_subdevices = 4;
 114         }
 115 
 116         ret = comedi_request_region(dev, it->options[0], iorange);
 117         if (ret)
 118                 return ret;
 119 
 120         ret = comedi_alloc_subdevices(dev, n_subdevices);
 121         if (ret)
 122                 return ret;
 123 
 124         for (i = 0; i < dev->n_subdevices; i++) {
 125                 s = &dev->subdevices[i];
 126                 if (board->is_pet48) {
 127                         iobase = dev->iobase + (i * 0x1000);
 128                         ret = subdev_8255_init(dev, s, pcl724_8255mapped_io,
 129                                                iobase);
 130                 } else {
 131                         ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE);
 132                 }
 133                 if (ret)
 134                         return ret;
 135         }
 136 
 137         return 0;
 138 }
 139 
 140 static struct comedi_driver pcl724_driver = {
 141         .driver_name    = "pcl724",
 142         .module         = THIS_MODULE,
 143         .attach         = pcl724_attach,
 144         .detach         = comedi_legacy_detach,
 145         .board_name     = &boardtypes[0].name,
 146         .num_names      = ARRAY_SIZE(boardtypes),
 147         .offset         = sizeof(struct pcl724_board),
 148 };
 149 module_comedi_driver(pcl724_driver);
 150 
 151 MODULE_AUTHOR("Comedi http://www.comedi.org");
 152 MODULE_DESCRIPTION("Comedi driver for 8255 based ISA and PC/104 DIO boards");
 153 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */