1/* 2 * COMEDI driver for generic PCI based 8255 digital i/o boards 3 * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com> 4 * 5 * Based on the tested adl_pci7296 driver written by: 6 * Jon Grierson <jd@renko.co.uk> 7 * and the experimental cb_pcidio driver written by: 8 * Yoshiya Matsuzaka 9 * 10 * COMEDI - Linux Control and Measurement Device Interface 11 * Copyright (C) 2000 David A. Schleef <ds@schleef.org> 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 */ 23 24/* 25Driver: 8255_pci 26Description: Generic PCI based 8255 Digital I/O boards 27Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels 28 (ADLink) PCI-7248 [adl_pci-7248] - 48 channels 29 (ADLink) PCI-7296 [adl_pci-7296] - 96 channels 30 (Measurement Computing) PCI-DIO24 [cb_pci-dio24] - 24 channels 31 (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels 32 (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels 33 (Measurement Computing) PCI-DIO96H [cb_pci-dio96h] - 96 channels 34 (National Instruments) PCI-DIO-96 [ni_pci-dio-96] - 96 channels 35 (National Instruments) PCI-DIO-96B [ni_pci-dio-96b] - 96 channels 36 (National Instruments) PXI-6508 [ni_pxi-6508] - 96 channels 37 (National Instruments) PCI-6503 [ni_pci-6503] - 24 channels 38 (National Instruments) PCI-6503B [ni_pci-6503b] - 24 channels 39 (National Instruments) PCI-6503X [ni_pci-6503x] - 24 channels 40 (National Instruments) PXI-6503 [ni_pxi-6503] - 24 channels 41Author: H Hartley Sweeten <hsweeten@visionengravers.com> 42Updated: Wed, 12 Sep 2012 11:52:01 -0700 43Status: untested 44 45Some of these boards also have an 8254 programmable timer/counter 46chip. This chip is not currently supported by this driver. 47 48Interrupt support for these boards is also not currently supported. 49 50Configuration Options: not applicable, uses PCI auto config 51*/ 52 53#include <linux/module.h> 54#include <linux/pci.h> 55 56#include "../comedidev.h" 57 58#include "8255.h" 59 60enum pci_8255_boardid { 61 BOARD_ADLINK_PCI7224, 62 BOARD_ADLINK_PCI7248, 63 BOARD_ADLINK_PCI7296, 64 BOARD_CB_PCIDIO24, 65 BOARD_CB_PCIDIO24H, 66 BOARD_CB_PCIDIO48H_OLD, 67 BOARD_CB_PCIDIO48H_NEW, 68 BOARD_CB_PCIDIO96H, 69 BOARD_NI_PCIDIO96, 70 BOARD_NI_PCIDIO96B, 71 BOARD_NI_PXI6508, 72 BOARD_NI_PCI6503, 73 BOARD_NI_PCI6503B, 74 BOARD_NI_PCI6503X, 75 BOARD_NI_PXI_6503, 76}; 77 78struct pci_8255_boardinfo { 79 const char *name; 80 int dio_badr; 81 int n_8255; 82 unsigned int has_mite:1; 83}; 84 85static const struct pci_8255_boardinfo pci_8255_boards[] = { 86 [BOARD_ADLINK_PCI7224] = { 87 .name = "adl_pci-7224", 88 .dio_badr = 2, 89 .n_8255 = 1, 90 }, 91 [BOARD_ADLINK_PCI7248] = { 92 .name = "adl_pci-7248", 93 .dio_badr = 2, 94 .n_8255 = 2, 95 }, 96 [BOARD_ADLINK_PCI7296] = { 97 .name = "adl_pci-7296", 98 .dio_badr = 2, 99 .n_8255 = 4, 100 }, 101 [BOARD_CB_PCIDIO24] = { 102 .name = "cb_pci-dio24", 103 .dio_badr = 2, 104 .n_8255 = 1, 105 }, 106 [BOARD_CB_PCIDIO24H] = { 107 .name = "cb_pci-dio24h", 108 .dio_badr = 2, 109 .n_8255 = 1, 110 }, 111 [BOARD_CB_PCIDIO48H_OLD] = { 112 .name = "cb_pci-dio48h", 113 .dio_badr = 1, 114 .n_8255 = 2, 115 }, 116 [BOARD_CB_PCIDIO48H_NEW] = { 117 .name = "cb_pci-dio48h", 118 .dio_badr = 2, 119 .n_8255 = 2, 120 }, 121 [BOARD_CB_PCIDIO96H] = { 122 .name = "cb_pci-dio96h", 123 .dio_badr = 2, 124 .n_8255 = 4, 125 }, 126 [BOARD_NI_PCIDIO96] = { 127 .name = "ni_pci-dio-96", 128 .dio_badr = 1, 129 .n_8255 = 4, 130 .has_mite = 1, 131 }, 132 [BOARD_NI_PCIDIO96B] = { 133 .name = "ni_pci-dio-96b", 134 .dio_badr = 1, 135 .n_8255 = 4, 136 .has_mite = 1, 137 }, 138 [BOARD_NI_PXI6508] = { 139 .name = "ni_pxi-6508", 140 .dio_badr = 1, 141 .n_8255 = 4, 142 .has_mite = 1, 143 }, 144 [BOARD_NI_PCI6503] = { 145 .name = "ni_pci-6503", 146 .dio_badr = 1, 147 .n_8255 = 1, 148 .has_mite = 1, 149 }, 150 [BOARD_NI_PCI6503B] = { 151 .name = "ni_pci-6503b", 152 .dio_badr = 1, 153 .n_8255 = 1, 154 .has_mite = 1, 155 }, 156 [BOARD_NI_PCI6503X] = { 157 .name = "ni_pci-6503x", 158 .dio_badr = 1, 159 .n_8255 = 1, 160 .has_mite = 1, 161 }, 162 [BOARD_NI_PXI_6503] = { 163 .name = "ni_pxi-6503", 164 .dio_badr = 1, 165 .n_8255 = 1, 166 .has_mite = 1, 167 }, 168}; 169 170/* ripped from mite.h and mite_setup2() to avoid mite dependancy */ 171#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ 172#define WENAB (1 << 7) /* window enable */ 173 174static int pci_8255_mite_init(struct pci_dev *pcidev) 175{ 176 void __iomem *mite_base; 177 u32 main_phys_addr; 178 179 /* ioremap the MITE registers (BAR 0) temporarily */ 180 mite_base = pci_ioremap_bar(pcidev, 0); 181 if (!mite_base) 182 return -ENOMEM; 183 184 /* set data window to main registers (BAR 1) */ 185 main_phys_addr = pci_resource_start(pcidev, 1); 186 writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR); 187 188 /* finished with MITE registers */ 189 iounmap(mite_base); 190 return 0; 191} 192 193static int pci_8255_auto_attach(struct comedi_device *dev, 194 unsigned long context) 195{ 196 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 197 const struct pci_8255_boardinfo *board = NULL; 198 struct comedi_subdevice *s; 199 int ret; 200 int i; 201 202 if (context < ARRAY_SIZE(pci_8255_boards)) 203 board = &pci_8255_boards[context]; 204 if (!board) 205 return -ENODEV; 206 dev->board_ptr = board; 207 dev->board_name = board->name; 208 209 ret = comedi_pci_enable(dev); 210 if (ret) 211 return ret; 212 213 if (board->has_mite) { 214 ret = pci_8255_mite_init(pcidev); 215 if (ret) 216 return ret; 217 } 218 219 if ((pci_resource_flags(pcidev, board->dio_badr) & IORESOURCE_MEM)) { 220 dev->mmio = pci_ioremap_bar(pcidev, board->dio_badr); 221 if (!dev->mmio) 222 return -ENOMEM; 223 } else { 224 dev->iobase = pci_resource_start(pcidev, board->dio_badr); 225 } 226 227 /* 228 * One, two, or four subdevices are setup by this driver depending 229 * on the number of channels provided by the board. Each subdevice 230 * has 24 channels supported by the 8255 module. 231 */ 232 ret = comedi_alloc_subdevices(dev, board->n_8255); 233 if (ret) 234 return ret; 235 236 for (i = 0; i < board->n_8255; i++) { 237 s = &dev->subdevices[i]; 238 if (dev->mmio) 239 ret = subdev_8255_mm_init(dev, s, NULL, i * I8255_SIZE); 240 else 241 ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); 242 if (ret) 243 return ret; 244 } 245 246 return 0; 247} 248 249static struct comedi_driver pci_8255_driver = { 250 .driver_name = "8255_pci", 251 .module = THIS_MODULE, 252 .auto_attach = pci_8255_auto_attach, 253 .detach = comedi_pci_detach, 254}; 255 256static int pci_8255_pci_probe(struct pci_dev *dev, 257 const struct pci_device_id *id) 258{ 259 return comedi_pci_auto_config(dev, &pci_8255_driver, id->driver_data); 260} 261 262static const struct pci_device_id pci_8255_pci_table[] = { 263 { PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 }, 264 { PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 }, 265 { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 }, 266 { PCI_VDEVICE(CB, 0x0028), BOARD_CB_PCIDIO24 }, 267 { PCI_VDEVICE(CB, 0x0014), BOARD_CB_PCIDIO24H }, 268 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, 0x0000, 0x0000), 269 .driver_data = BOARD_CB_PCIDIO48H_OLD }, 270 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CB, 0x000b, PCI_VENDOR_ID_CB, 0x000b), 271 .driver_data = BOARD_CB_PCIDIO48H_NEW }, 272 { PCI_VDEVICE(CB, 0x0017), BOARD_CB_PCIDIO96H }, 273 { PCI_VDEVICE(NI, 0x0160), BOARD_NI_PCIDIO96 }, 274 { PCI_VDEVICE(NI, 0x1630), BOARD_NI_PCIDIO96B }, 275 { PCI_VDEVICE(NI, 0x13c0), BOARD_NI_PXI6508 }, 276 { PCI_VDEVICE(NI, 0x0400), BOARD_NI_PCI6503 }, 277 { PCI_VDEVICE(NI, 0x1250), BOARD_NI_PCI6503B }, 278 { PCI_VDEVICE(NI, 0x17d0), BOARD_NI_PCI6503X }, 279 { PCI_VDEVICE(NI, 0x1800), BOARD_NI_PXI_6503 }, 280 { 0 } 281}; 282MODULE_DEVICE_TABLE(pci, pci_8255_pci_table); 283 284static struct pci_driver pci_8255_pci_driver = { 285 .name = "8255_pci", 286 .id_table = pci_8255_pci_table, 287 .probe = pci_8255_pci_probe, 288 .remove = comedi_pci_auto_unconfig, 289}; 290module_comedi_pci_driver(pci_8255_driver, pci_8255_pci_driver); 291 292MODULE_DESCRIPTION("COMEDI - Generic PCI based 8255 Digital I/O boards"); 293MODULE_AUTHOR("Comedi http://www.comedi.org"); 294MODULE_LICENSE("GPL"); 295