The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ichiic/ig4_pci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2014 The DragonFly Project.  All rights reserved.
    3  *
    4  * This code is derived from software contributed to The DragonFly Project
    5  * by Matthew Dillon <dillon@backplane.com> and was subsequently ported
    6  * to FreeBSD by Michael Gmelin <freebsd@grem.de>
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  *
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in
   16  *    the documentation and/or other materials provided with the
   17  *    distribution.
   18  * 3. Neither the name of The DragonFly Project nor the names of its
   19  *    contributors may be used to endorse or promote products derived
   20  *    from this software without specific, prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
   26  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
   28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   32  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD: releng/11.2/sys/dev/ichiic/ig4_pci.c 331834 2018-03-31 00:30:47Z gonzo $");
   38 
   39 /*
   40  * Intel fourth generation mobile cpus integrated I2C device.
   41  *
   42  * See ig4_reg.h for datasheet reference and notes.
   43  */
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/kernel.h>
   48 #include <sys/module.h>
   49 #include <sys/errno.h>
   50 #include <sys/lock.h>
   51 #include <sys/mutex.h>
   52 #include <sys/sx.h>
   53 #include <sys/syslog.h>
   54 #include <sys/bus.h>
   55 
   56 #include <machine/bus.h>
   57 #include <sys/rman.h>
   58 #include <machine/resource.h>
   59 
   60 #include <dev/pci/pcivar.h>
   61 #include <dev/pci/pcireg.h>
   62 #include <dev/iicbus/iiconf.h>
   63 
   64 #include <dev/ichiic/ig4_reg.h>
   65 #include <dev/ichiic/ig4_var.h>
   66 
   67 static int ig4iic_pci_detach(device_t dev);
   68 
   69 #define PCI_CHIP_LYNXPT_LP_I2C_1        0x9c618086
   70 #define PCI_CHIP_LYNXPT_LP_I2C_2        0x9c628086
   71 #define PCI_CHIP_BRASWELL_I2C_1         0x22c18086
   72 #define PCI_CHIP_BRASWELL_I2C_2         0x22c28086
   73 #define PCI_CHIP_BRASWELL_I2C_3         0x22c38086
   74 #define PCI_CHIP_BRASWELL_I2C_5         0x22c58086
   75 #define PCI_CHIP_BRASWELL_I2C_6         0x22c68086
   76 #define PCI_CHIP_BRASWELL_I2C_7         0x22c78086
   77 #define PCI_CHIP_SKYLAKE_I2C_0          0x9d608086
   78 #define PCI_CHIP_SKYLAKE_I2C_1          0x9d618086
   79 #define PCI_CHIP_SKYLAKE_I2C_2          0x9d628086
   80 #define PCI_CHIP_SKYLAKE_I2C_3          0x9d638086
   81 #define PCI_CHIP_SKYLAKE_I2C_4          0x9d648086
   82 #define PCI_CHIP_SKYLAKE_I2C_5          0x9d658086
   83 
   84 static int
   85 ig4iic_pci_probe(device_t dev)
   86 {
   87         ig4iic_softc_t *sc = device_get_softc(dev);
   88 
   89         switch(pci_get_devid(dev)) {
   90         case PCI_CHIP_LYNXPT_LP_I2C_1:
   91                 device_set_desc(dev, "Intel Lynx Point-LP I2C Controller-1");
   92                 sc->version = IG4_HASWELL;
   93                 break;
   94         case PCI_CHIP_LYNXPT_LP_I2C_2:
   95                 device_set_desc(dev, "Intel Lynx Point-LP I2C Controller-2");
   96                 sc->version = IG4_HASWELL;
   97                 break;
   98         case PCI_CHIP_BRASWELL_I2C_1:
   99                 device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 1");
  100                 sc->version = IG4_ATOM;
  101                 break;
  102         case PCI_CHIP_BRASWELL_I2C_2:
  103                 device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 2");
  104                 sc->version = IG4_ATOM;
  105                 break;
  106         case PCI_CHIP_BRASWELL_I2C_3:
  107                 device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 3");
  108                 sc->version = IG4_ATOM;
  109                 break;
  110         case PCI_CHIP_BRASWELL_I2C_5:
  111                 device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 5");
  112                 sc->version = IG4_ATOM;
  113                 break;
  114         case PCI_CHIP_BRASWELL_I2C_6:
  115                 device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 6");
  116                 sc->version = IG4_ATOM;
  117                 break;
  118         case PCI_CHIP_BRASWELL_I2C_7:
  119                 device_set_desc(dev, "Intel Braswell Serial I/O I2C Port 7");
  120                 sc->version = IG4_ATOM;
  121                 break;
  122         case PCI_CHIP_SKYLAKE_I2C_0:
  123                 device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-0");
  124                 sc->version = IG4_SKYLAKE;
  125                 break;
  126         case PCI_CHIP_SKYLAKE_I2C_1:
  127                 device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-1");
  128                 sc->version = IG4_SKYLAKE;
  129                 break;
  130         case PCI_CHIP_SKYLAKE_I2C_2:
  131                 device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-2");
  132                 sc->version = IG4_SKYLAKE;
  133                 break;
  134         case PCI_CHIP_SKYLAKE_I2C_3:
  135                 device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-3");
  136                 sc->version = IG4_SKYLAKE;
  137                 break;
  138         case PCI_CHIP_SKYLAKE_I2C_4:
  139                 device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-4");
  140                 sc->version = IG4_SKYLAKE;
  141                 break;
  142         case PCI_CHIP_SKYLAKE_I2C_5:
  143                 device_set_desc(dev, "Intel Sunrise Point-LP I2C Controller-5");
  144                 sc->version = IG4_SKYLAKE;
  145                 break;
  146         default:
  147                 return (ENXIO);
  148         }
  149         return (BUS_PROBE_DEFAULT);
  150 }
  151 
  152 static int
  153 ig4iic_pci_attach(device_t dev)
  154 {
  155         ig4iic_softc_t *sc = device_get_softc(dev);
  156         int error;
  157 
  158         sc->dev = dev;
  159         sc->regs_rid = PCIR_BAR(0);
  160         sc->regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  161                                           &sc->regs_rid, RF_ACTIVE);
  162         if (sc->regs_res == NULL) {
  163                 device_printf(dev, "unable to map registers\n");
  164                 ig4iic_pci_detach(dev);
  165                 return (ENXIO);
  166         }
  167         sc->intr_rid = 0;
  168         if (pci_alloc_msi(dev, &sc->intr_rid)) {
  169                 device_printf(dev, "Using MSI\n");
  170         }
  171         sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
  172                                           &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE);
  173         if (sc->intr_res == NULL) {
  174                 device_printf(dev, "unable to map interrupt\n");
  175                 ig4iic_pci_detach(dev);
  176                 return (ENXIO);
  177         }
  178         sc->platform_attached = 1;
  179 
  180         error = ig4iic_attach(sc);
  181         if (error)
  182                 ig4iic_pci_detach(dev);
  183 
  184         return (error);
  185 }
  186 
  187 static int
  188 ig4iic_pci_detach(device_t dev)
  189 {
  190         ig4iic_softc_t *sc = device_get_softc(dev);
  191         int error;
  192 
  193         if (sc->platform_attached) {
  194                 error = ig4iic_detach(sc);
  195                 if (error)
  196                         return (error);
  197                 sc->platform_attached = 0;
  198         }
  199 
  200         if (sc->intr_res) {
  201                 bus_release_resource(dev, SYS_RES_IRQ,
  202                                      sc->intr_rid, sc->intr_res);
  203                 sc->intr_res = NULL;
  204         }
  205         if (sc->intr_rid != 0)
  206                 pci_release_msi(dev);
  207         if (sc->regs_res) {
  208                 bus_release_resource(dev, SYS_RES_MEMORY,
  209                                      sc->regs_rid, sc->regs_res);
  210                 sc->regs_res = NULL;
  211         }
  212 
  213         return (0);
  214 }
  215 
  216 static device_method_t ig4iic_pci_methods[] = {
  217         /* Device interface */
  218         DEVMETHOD(device_probe, ig4iic_pci_probe),
  219         DEVMETHOD(device_attach, ig4iic_pci_attach),
  220         DEVMETHOD(device_detach, ig4iic_pci_detach),
  221 
  222         DEVMETHOD(iicbus_transfer, ig4iic_transfer),
  223         DEVMETHOD(iicbus_reset, ig4iic_reset),
  224         DEVMETHOD(iicbus_callback, iicbus_null_callback),
  225 
  226         DEVMETHOD_END
  227 };
  228 
  229 static driver_t ig4iic_pci_driver = {
  230         "ig4iic_pci",
  231         ig4iic_pci_methods,
  232         sizeof(struct ig4iic_softc)
  233 };
  234 
  235 static devclass_t ig4iic_pci_devclass;
  236 
  237 DRIVER_MODULE_ORDERED(ig4iic_pci, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0,
  238     SI_ORDER_ANY);
  239 MODULE_DEPEND(ig4iic_pci, pci, 1, 1, 1);
  240 MODULE_DEPEND(ig4iic_pci, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
  241 MODULE_VERSION(ig4iic_pci, 1);

Cache object: 1f3fd0c5df98ef19dea0c0df3736af9d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.