1*8ffdff6aSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0+ 2*8ffdff6aSGreg Kroah-Hartman /* 3*8ffdff6aSGreg Kroah-Hartman * comedi/drivers/ni_labpc_pci.c 4*8ffdff6aSGreg Kroah-Hartman * Driver for National Instruments Lab-PC PCI-1200 5*8ffdff6aSGreg Kroah-Hartman * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net> 6*8ffdff6aSGreg Kroah-Hartman */ 7*8ffdff6aSGreg Kroah-Hartman 8*8ffdff6aSGreg Kroah-Hartman /* 9*8ffdff6aSGreg Kroah-Hartman * Driver: ni_labpc_pci 10*8ffdff6aSGreg Kroah-Hartman * Description: National Instruments Lab-PC PCI-1200 11*8ffdff6aSGreg Kroah-Hartman * Devices: [National Instruments] PCI-1200 (ni_pci-1200) 12*8ffdff6aSGreg Kroah-Hartman * Author: Frank Mori Hess <fmhess@users.sourceforge.net> 13*8ffdff6aSGreg Kroah-Hartman * Status: works 14*8ffdff6aSGreg Kroah-Hartman * 15*8ffdff6aSGreg Kroah-Hartman * This is the PCI-specific support split off from the ni_labpc driver. 16*8ffdff6aSGreg Kroah-Hartman * 17*8ffdff6aSGreg Kroah-Hartman * Configuration Options: not applicable, uses PCI auto config 18*8ffdff6aSGreg Kroah-Hartman * 19*8ffdff6aSGreg Kroah-Hartman * NI manuals: 20*8ffdff6aSGreg Kroah-Hartman * 340914a (pci-1200) 21*8ffdff6aSGreg Kroah-Hartman */ 22*8ffdff6aSGreg Kroah-Hartman 23*8ffdff6aSGreg Kroah-Hartman #include <linux/module.h> 24*8ffdff6aSGreg Kroah-Hartman #include <linux/interrupt.h> 25*8ffdff6aSGreg Kroah-Hartman 26*8ffdff6aSGreg Kroah-Hartman #include "../comedi_pci.h" 27*8ffdff6aSGreg Kroah-Hartman 28*8ffdff6aSGreg Kroah-Hartman #include "ni_labpc.h" 29*8ffdff6aSGreg Kroah-Hartman 30*8ffdff6aSGreg Kroah-Hartman enum labpc_pci_boardid { 31*8ffdff6aSGreg Kroah-Hartman BOARD_NI_PCI1200, 32*8ffdff6aSGreg Kroah-Hartman }; 33*8ffdff6aSGreg Kroah-Hartman 34*8ffdff6aSGreg Kroah-Hartman static const struct labpc_boardinfo labpc_pci_boards[] = { 35*8ffdff6aSGreg Kroah-Hartman [BOARD_NI_PCI1200] = { 36*8ffdff6aSGreg Kroah-Hartman .name = "ni_pci-1200", 37*8ffdff6aSGreg Kroah-Hartman .ai_speed = 10000, 38*8ffdff6aSGreg Kroah-Hartman .ai_scan_up = 1, 39*8ffdff6aSGreg Kroah-Hartman .has_ao = 1, 40*8ffdff6aSGreg Kroah-Hartman .is_labpc1200 = 1, 41*8ffdff6aSGreg Kroah-Hartman }, 42*8ffdff6aSGreg Kroah-Hartman }; 43*8ffdff6aSGreg Kroah-Hartman 44*8ffdff6aSGreg Kroah-Hartman /* ripped from mite.h and mite_setup2() to avoid mite dependency */ 45*8ffdff6aSGreg Kroah-Hartman #define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */ 46*8ffdff6aSGreg Kroah-Hartman #define WENAB BIT(7) /* window enable */ 47*8ffdff6aSGreg Kroah-Hartman 48*8ffdff6aSGreg Kroah-Hartman static int labpc_pci_mite_init(struct pci_dev *pcidev) 49*8ffdff6aSGreg Kroah-Hartman { 50*8ffdff6aSGreg Kroah-Hartman void __iomem *mite_base; 51*8ffdff6aSGreg Kroah-Hartman u32 main_phys_addr; 52*8ffdff6aSGreg Kroah-Hartman 53*8ffdff6aSGreg Kroah-Hartman /* ioremap the MITE registers (BAR 0) temporarily */ 54*8ffdff6aSGreg Kroah-Hartman mite_base = pci_ioremap_bar(pcidev, 0); 55*8ffdff6aSGreg Kroah-Hartman if (!mite_base) 56*8ffdff6aSGreg Kroah-Hartman return -ENOMEM; 57*8ffdff6aSGreg Kroah-Hartman 58*8ffdff6aSGreg Kroah-Hartman /* set data window to main registers (BAR 1) */ 59*8ffdff6aSGreg Kroah-Hartman main_phys_addr = pci_resource_start(pcidev, 1); 60*8ffdff6aSGreg Kroah-Hartman writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR); 61*8ffdff6aSGreg Kroah-Hartman 62*8ffdff6aSGreg Kroah-Hartman /* finished with MITE registers */ 63*8ffdff6aSGreg Kroah-Hartman iounmap(mite_base); 64*8ffdff6aSGreg Kroah-Hartman return 0; 65*8ffdff6aSGreg Kroah-Hartman } 66*8ffdff6aSGreg Kroah-Hartman 67*8ffdff6aSGreg Kroah-Hartman static int labpc_pci_auto_attach(struct comedi_device *dev, 68*8ffdff6aSGreg Kroah-Hartman unsigned long context) 69*8ffdff6aSGreg Kroah-Hartman { 70*8ffdff6aSGreg Kroah-Hartman struct pci_dev *pcidev = comedi_to_pci_dev(dev); 71*8ffdff6aSGreg Kroah-Hartman const struct labpc_boardinfo *board = NULL; 72*8ffdff6aSGreg Kroah-Hartman int ret; 73*8ffdff6aSGreg Kroah-Hartman 74*8ffdff6aSGreg Kroah-Hartman if (context < ARRAY_SIZE(labpc_pci_boards)) 75*8ffdff6aSGreg Kroah-Hartman board = &labpc_pci_boards[context]; 76*8ffdff6aSGreg Kroah-Hartman if (!board) 77*8ffdff6aSGreg Kroah-Hartman return -ENODEV; 78*8ffdff6aSGreg Kroah-Hartman dev->board_ptr = board; 79*8ffdff6aSGreg Kroah-Hartman dev->board_name = board->name; 80*8ffdff6aSGreg Kroah-Hartman 81*8ffdff6aSGreg Kroah-Hartman ret = comedi_pci_enable(dev); 82*8ffdff6aSGreg Kroah-Hartman if (ret) 83*8ffdff6aSGreg Kroah-Hartman return ret; 84*8ffdff6aSGreg Kroah-Hartman 85*8ffdff6aSGreg Kroah-Hartman ret = labpc_pci_mite_init(pcidev); 86*8ffdff6aSGreg Kroah-Hartman if (ret) 87*8ffdff6aSGreg Kroah-Hartman return ret; 88*8ffdff6aSGreg Kroah-Hartman 89*8ffdff6aSGreg Kroah-Hartman dev->mmio = pci_ioremap_bar(pcidev, 1); 90*8ffdff6aSGreg Kroah-Hartman if (!dev->mmio) 91*8ffdff6aSGreg Kroah-Hartman return -ENOMEM; 92*8ffdff6aSGreg Kroah-Hartman 93*8ffdff6aSGreg Kroah-Hartman return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED); 94*8ffdff6aSGreg Kroah-Hartman } 95*8ffdff6aSGreg Kroah-Hartman 96*8ffdff6aSGreg Kroah-Hartman static void labpc_pci_detach(struct comedi_device *dev) 97*8ffdff6aSGreg Kroah-Hartman { 98*8ffdff6aSGreg Kroah-Hartman labpc_common_detach(dev); 99*8ffdff6aSGreg Kroah-Hartman comedi_pci_detach(dev); 100*8ffdff6aSGreg Kroah-Hartman } 101*8ffdff6aSGreg Kroah-Hartman 102*8ffdff6aSGreg Kroah-Hartman static struct comedi_driver labpc_pci_comedi_driver = { 103*8ffdff6aSGreg Kroah-Hartman .driver_name = "labpc_pci", 104*8ffdff6aSGreg Kroah-Hartman .module = THIS_MODULE, 105*8ffdff6aSGreg Kroah-Hartman .auto_attach = labpc_pci_auto_attach, 106*8ffdff6aSGreg Kroah-Hartman .detach = labpc_pci_detach, 107*8ffdff6aSGreg Kroah-Hartman }; 108*8ffdff6aSGreg Kroah-Hartman 109*8ffdff6aSGreg Kroah-Hartman static const struct pci_device_id labpc_pci_table[] = { 110*8ffdff6aSGreg Kroah-Hartman { PCI_VDEVICE(NI, 0x161), BOARD_NI_PCI1200 }, 111*8ffdff6aSGreg Kroah-Hartman { 0 } 112*8ffdff6aSGreg Kroah-Hartman }; 113*8ffdff6aSGreg Kroah-Hartman MODULE_DEVICE_TABLE(pci, labpc_pci_table); 114*8ffdff6aSGreg Kroah-Hartman 115*8ffdff6aSGreg Kroah-Hartman static int labpc_pci_probe(struct pci_dev *dev, 116*8ffdff6aSGreg Kroah-Hartman const struct pci_device_id *id) 117*8ffdff6aSGreg Kroah-Hartman { 118*8ffdff6aSGreg Kroah-Hartman return comedi_pci_auto_config(dev, &labpc_pci_comedi_driver, 119*8ffdff6aSGreg Kroah-Hartman id->driver_data); 120*8ffdff6aSGreg Kroah-Hartman } 121*8ffdff6aSGreg Kroah-Hartman 122*8ffdff6aSGreg Kroah-Hartman static struct pci_driver labpc_pci_driver = { 123*8ffdff6aSGreg Kroah-Hartman .name = "labpc_pci", 124*8ffdff6aSGreg Kroah-Hartman .id_table = labpc_pci_table, 125*8ffdff6aSGreg Kroah-Hartman .probe = labpc_pci_probe, 126*8ffdff6aSGreg Kroah-Hartman .remove = comedi_pci_auto_unconfig, 127*8ffdff6aSGreg Kroah-Hartman }; 128*8ffdff6aSGreg Kroah-Hartman module_comedi_pci_driver(labpc_pci_comedi_driver, labpc_pci_driver); 129*8ffdff6aSGreg Kroah-Hartman 130*8ffdff6aSGreg Kroah-Hartman MODULE_DESCRIPTION("Comedi: National Instruments Lab-PC PCI-1200 driver"); 131*8ffdff6aSGreg Kroah-Hartman MODULE_AUTHOR("Comedi https://www.comedi.org"); 132*8ffdff6aSGreg Kroah-Hartman MODULE_LICENSE("GPL"); 133