root/drivers/staging/comedi/drivers/8255.c

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

DEFINITIONS

This source file includes following definitions.
  1. dev_8255_attach
  2. dev_8255_detach

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * comedi/drivers/8255.c
   4  * Driver for 8255
   5  *
   6  * COMEDI - Linux Control and Measurement Device Interface
   7  * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
   8  */
   9 
  10 /*
  11  * Driver: 8255
  12  * Description: generic 8255 support
  13  * Devices: [standard] 8255 (8255)
  14  * Author: ds
  15  * Status: works
  16  * Updated: Fri,  7 Jun 2002 12:56:45 -0700
  17  *
  18  * The classic in digital I/O.  The 8255 appears in Comedi as a single
  19  * digital I/O subdevice with 24 channels.  The channel 0 corresponds
  20  * to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
  21  * 7.  Direction configuration is done in blocks, with channels 0-7,
  22  * 8-15, 16-19, and 20-23 making up the 4 blocks.  The only 8255 mode
  23  * supported is mode 0.
  24  *
  25  * You should enable compilation this driver if you plan to use a board
  26  * that has an 8255 chip.  For multifunction boards, the main driver will
  27  * configure the 8255 subdevice automatically.
  28  *
  29  * This driver also works independently with ISA and PCI cards that
  30  * directly map the 8255 registers to I/O ports, including cards with
  31  * multiple 8255 chips.  To configure the driver for such a card, the
  32  * option list should be a list of the I/O port bases for each of the
  33  * 8255 chips.  For example,
  34  *
  35  *   comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
  36  *
  37  * Note that most PCI 8255 boards do NOT work with this driver, and
  38  * need a separate driver as a wrapper.  For those that do work, the
  39  * I/O port base address can be found in the output of 'lspci -v'.
  40  */
  41 
  42 #include <linux/module.h>
  43 #include "../comedidev.h"
  44 
  45 #include "8255.h"
  46 
  47 static int dev_8255_attach(struct comedi_device *dev,
  48                            struct comedi_devconfig *it)
  49 {
  50         struct comedi_subdevice *s;
  51         unsigned long iobase;
  52         int ret;
  53         int i;
  54 
  55         for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
  56                 iobase = it->options[i];
  57                 if (!iobase)
  58                         break;
  59         }
  60         if (i == 0) {
  61                 dev_warn(dev->class_dev, "no devices specified\n");
  62                 return -EINVAL;
  63         }
  64 
  65         ret = comedi_alloc_subdevices(dev, i);
  66         if (ret)
  67                 return ret;
  68 
  69         for (i = 0; i < dev->n_subdevices; i++) {
  70                 s = &dev->subdevices[i];
  71                 iobase = it->options[i];
  72 
  73                 /*
  74                  * __comedi_request_region() does not set dev->iobase.
  75                  *
  76                  * For 8255 devices that are manually attached using
  77                  * comedi_config, the 'iobase' is the actual I/O port
  78                  * base address of the chip.
  79                  */
  80                 ret = __comedi_request_region(dev, iobase, I8255_SIZE);
  81                 if (ret) {
  82                         s->type = COMEDI_SUBD_UNUSED;
  83                 } else {
  84                         ret = subdev_8255_init(dev, s, NULL, iobase);
  85                         if (ret) {
  86                                 /*
  87                                  * Release the I/O port region here, as the
  88                                  * "detach" handler cannot find it.
  89                                  */
  90                                 release_region(iobase, I8255_SIZE);
  91                                 s->type = COMEDI_SUBD_UNUSED;
  92                                 return ret;
  93                         }
  94                 }
  95         }
  96 
  97         return 0;
  98 }
  99 
 100 static void dev_8255_detach(struct comedi_device *dev)
 101 {
 102         struct comedi_subdevice *s;
 103         int i;
 104 
 105         for (i = 0; i < dev->n_subdevices; i++) {
 106                 s = &dev->subdevices[i];
 107                 if (s->type != COMEDI_SUBD_UNUSED) {
 108                         unsigned long regbase = subdev_8255_regbase(s);
 109 
 110                         release_region(regbase, I8255_SIZE);
 111                 }
 112         }
 113 }
 114 
 115 static struct comedi_driver dev_8255_driver = {
 116         .driver_name    = "8255",
 117         .module         = THIS_MODULE,
 118         .attach         = dev_8255_attach,
 119         .detach         = dev_8255_detach,
 120 };
 121 module_comedi_driver(dev_8255_driver);
 122 
 123 MODULE_AUTHOR("Comedi http://www.comedi.org");
 124 MODULE_DESCRIPTION("Comedi driver for standalone 8255 devices");
 125 MODULE_LICENSE("GPL");

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