From eb95689a826422af07e80e16f806f2a25a23428c Mon Sep 17 00:00:00 2001 From: Philip Paeps Date: Fri, 20 Dec 2019 03:40:46 +0000 Subject: [PATCH] iicoc: split up common core and PCI bus specifics The OpenCores I2C IP core can be found on any bus. Split out the PCI bus specifics into their own file, only compiled on systems with PCI. Reviewed by: kp Sponsored by: Axiado --- sys/conf/files | 1 + sys/dev/iicbus/iicoc.c | 151 +++++-------------------------------- sys/dev/iicbus/iicoc.h | 26 +++++++ sys/dev/iicbus/iicoc_pci.c | 143 +++++++++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+), 134 deletions(-) create mode 100644 sys/dev/iicbus/iicoc_pci.c diff --git a/sys/conf/files b/sys/conf/files index 558da746fdf2..4c3d0bcc9437 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1797,6 +1797,7 @@ dev/iicbus/iiconf.c optional iicbus dev/iicbus/iicsmb.c optional iicsmb \ dependency "iicbus_if.h" dev/iicbus/iicoc.c optional iicoc +dev/iicbus/iicoc_pci.c optional iicoc pci dev/iicbus/isl12xx.c optional isl12xx dev/iicbus/lm75.c optional lm75 dev/iicbus/nxprtc.c optional nxprtc | pcf8563 diff --git a/sys/dev/iicbus/iicoc.c b/sys/dev/iicbus/iicoc.c index 273b0597d8ba..e243e7128be7 100644 --- a/sys/dev/iicbus/iicoc.c +++ b/sys/dev/iicbus/iicoc.c @@ -45,41 +45,12 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include - #include "iicbus_if.h" #include "iicoc.h" -static devclass_t iicoc_devclass; +devclass_t iicoc_devclass; -/* - * Device methods - */ -static int iicoc_probe(device_t); -static int iicoc_attach(device_t); -static int iicoc_detach(device_t); - -static int iicoc_start(device_t dev, u_char slave, int timeout); -static int iicoc_stop(device_t dev); -static int iicoc_read(device_t dev, char *buf, - int len, int *read, int last, int delay); -static int iicoc_write(device_t dev, const char *buf, - int len, int *sent, int timeout); -static int iicoc_repeated_start(device_t dev, u_char slave, int timeout); - -struct iicoc_softc { - device_t dev; /* Self */ - u_int reg_shift; /* Chip specific */ - u_int clockfreq; - u_int i2cfreq; - struct resource *mem_res; /* Memory resource */ - int mem_rid; - int sc_started; - uint8_t i2cdev_addr; - device_t iicbus; - struct mtx sc_mtx; -}; +DRIVER_MODULE(iicbus, iicoc, iicbus_driver, iicbus_devclass, 0, 0); static void iicoc_dev_write(device_t dev, int reg, int value) @@ -155,7 +126,7 @@ iicoc_wr_ack_cmd(device_t dev, uint8_t data, uint8_t cmd) return (0); } -static int +int iicoc_init(device_t dev) { struct iicoc_softc *sc; @@ -176,70 +147,8 @@ iicoc_init(device_t dev) return ((value & OC_CONTROL_EN) == 0); } -static int -iicoc_probe(device_t dev) -{ - struct iicoc_softc *sc; - - sc = device_get_softc(dev); - if ((pci_get_vendor(dev) == 0x184e) && - (pci_get_device(dev) == 0x1011)) { - sc->clockfreq = XLP_I2C_CLKFREQ; - sc->i2cfreq = XLP_I2C_FREQ; - sc->reg_shift = 2; - device_set_desc(dev, "Netlogic XLP I2C Controller"); - return (BUS_PROBE_DEFAULT); - } - return (ENXIO); -} - - -/* - * We add all the devices which we know about. - * The generic attach routine will attach them if they are alive. - */ -static int -iicoc_attach(device_t dev) -{ - int bus; - struct iicoc_softc *sc; - - sc = device_get_softc(dev); - bus = device_get_unit(dev); - - sc->dev = dev; - mtx_init(&sc->sc_mtx, "iicoc", "iicoc", MTX_DEF); - sc->mem_rid = 0; - sc->mem_res = bus_alloc_resource_anywhere(dev, - SYS_RES_MEMORY, &sc->mem_rid, 0x100, RF_ACTIVE); - - if (sc->mem_res == NULL) { - device_printf(dev, "Could not allocate bus resource.\n"); - return (-1); - } - iicoc_init(dev); - sc->iicbus = device_add_child(dev, "iicbus", -1); - if (sc->iicbus == NULL) { - device_printf(dev, "Could not allocate iicbus instance.\n"); - return (-1); - } - bus_generic_attach(dev); - - return (0); -} - -static int -iicoc_detach(device_t dev) -{ - - bus_generic_detach(dev); - device_delete_children(dev); - - return (0); -} - -static int -iicoc_start(device_t dev, u_char slave, int timeout) +int +iicoc_iicbus_start(device_t dev, u_char slave, int timeout) { int error = IIC_EBUSERR; struct iicoc_softc *sc; @@ -277,8 +186,8 @@ iicoc_start(device_t dev, u_char slave, int timeout) return (error); } -static int -iicoc_stop(device_t dev) +int +iicoc_iicbus_stop(device_t dev) { int error = 0; struct iicoc_softc *sc; @@ -291,8 +200,9 @@ iicoc_stop(device_t dev) return (error); } -static int -iicoc_write(device_t dev, const char *buf, int len, int *sent, int timeout) +int +iicoc_iicbus_write(device_t dev, const char *buf, int len, int *sent, + int timeout) { uint8_t value; int i; @@ -320,8 +230,9 @@ iicoc_write(device_t dev, const char *buf, int len, int *sent, int timeout) return (IIC_EBUSERR); } -static int -iicoc_read(device_t dev, char *buf, int len, int *read, int last, int delay) +int +iicoc_iicbus_read(device_t dev, char *buf, int len, int *read, int last, + int delay) { int data, i; uint8_t cmd; @@ -345,8 +256,8 @@ iicoc_read(device_t dev, char *buf, int len, int *read, int last, int delay) return (IIC_EBUSERR); } -static int -iicoc_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) +int +iicoc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) { int error; struct iicoc_softc *sc; @@ -358,37 +269,9 @@ iicoc_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) return (error); } -static int -iicoc_repeated_start(device_t dev, u_char slave, int timeout) +int +iicoc_iicbus_repeated_start(device_t dev, u_char slave, int timeout) { return 0; } - -static device_method_t iicoc_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, iicoc_probe), - DEVMETHOD(device_attach, iicoc_attach), - DEVMETHOD(device_detach, iicoc_detach), - - /* iicbus interface */ - DEVMETHOD(iicbus_callback, iicbus_null_callback), - DEVMETHOD(iicbus_repeated_start, iicoc_repeated_start), - DEVMETHOD(iicbus_start, iicoc_start), - DEVMETHOD(iicbus_stop, iicoc_stop), - DEVMETHOD(iicbus_reset, iicoc_reset), - DEVMETHOD(iicbus_write, iicoc_write), - DEVMETHOD(iicbus_read, iicoc_read), - DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), - - DEVMETHOD_END -}; - -static driver_t iicoc_driver = { - "iicoc", - iicoc_methods, - sizeof(struct iicoc_softc), -}; - -DRIVER_MODULE(iicoc, pci, iicoc_driver, iicoc_devclass, 0, 0); -DRIVER_MODULE(iicbus, iicoc, iicbus_driver, iicbus_devclass, 0, 0); diff --git a/sys/dev/iicbus/iicoc.h b/sys/dev/iicbus/iicoc.h index 3a677c0ff8d5..c9b91ef1a895 100644 --- a/sys/dev/iicbus/iicoc.h +++ b/sys/dev/iicbus/iicoc.h @@ -77,4 +77,30 @@ #define OC_STATUS_TIP 0x02 /* Transfer in Progress */ #define OC_STATUS_IF 0x01 /* Intr. Pending Flag */ +struct iicoc_softc { + device_t dev; /* Self */ + u_int reg_shift; /* Chip specific */ + u_int clockfreq; + u_int i2cfreq; + struct resource *mem_res; /* Memory resource */ + int mem_rid; + int sc_started; + uint8_t i2cdev_addr; + device_t iicbus; + struct mtx sc_mtx; +}; + #endif + +extern devclass_t iicoc_devclass; + +int iicoc_iicbus_start(device_t dev, u_char slave, int timeout); +int iicoc_iicbus_stop(device_t dev); +int iicoc_iicbus_read(device_t dev, char *buf, int len, int *read, int last, + int delay); +int iicoc_iicbus_write(device_t dev, const char *buf, int len, int *sent, + int timeout); +int iicoc_iicbus_repeated_start(device_t dev, u_char slave, int timeout); +int iicoc_iicbus_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr); + +int iicoc_init(device_t dev); diff --git a/sys/dev/iicbus/iicoc_pci.c b/sys/dev/iicbus/iicoc_pci.c new file mode 100644 index 000000000000..9f5de1d5062d --- /dev/null +++ b/sys/dev/iicbus/iicoc_pci.c @@ -0,0 +1,143 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2003-2012 Broadcom Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "iicbus_if.h" +#include "iicoc.h" + +static int +iicoc_detach(device_t dev) +{ + struct iicoc_softc *sc; + + sc = device_get_softc(dev); + device_delete_children(dev); + bus_generic_detach(dev); + bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, &sc->mem_res); + mtx_destroy(&sc->sc_mtx); + + return (0); +} + +/* + * We add all the devices which we know about. + * The generic attach routine will attach them if they are alive. + */ +static int +iicoc_attach(device_t dev) +{ + int bus; + struct iicoc_softc *sc; + + sc = device_get_softc(dev); + bus = device_get_unit(dev); + + sc->dev = dev; + mtx_init(&sc->sc_mtx, "iicoc", "iicoc", MTX_DEF); + sc->mem_rid = 0; + sc->mem_res = bus_alloc_resource_anywhere(dev, + SYS_RES_MEMORY, &sc->mem_rid, 0x100, RF_ACTIVE); + + if (sc->mem_res == NULL) { + device_printf(dev, "Could not allocate bus resource.\n"); + return (-1); + } + iicoc_init(dev); + sc->iicbus = device_add_child(dev, "iicbus", -1); + if (sc->iicbus == NULL) { + device_printf(dev, "Could not allocate iicbus instance.\n"); + bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, + &sc->mem_res); + mtx_destroy(&sc->sc_mtx); + return (-1); + } + bus_generic_attach(dev); + + return (0); +} + +static int +iicoc_probe(device_t dev) +{ + struct iicoc_softc *sc; + + sc = device_get_softc(dev); + if ((pci_get_vendor(dev) == 0x184e) && + (pci_get_device(dev) == 0x1011)) { + sc->clockfreq = XLP_I2C_CLKFREQ; + sc->i2cfreq = XLP_I2C_FREQ; + sc->reg_shift = 2; + device_set_desc(dev, "Netlogic XLP I2C Controller"); + return (BUS_PROBE_DEFAULT); + } + return (ENXIO); +} + +static device_method_t iicoc_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, iicoc_probe), + DEVMETHOD(device_attach, iicoc_attach), + DEVMETHOD(device_detach, iicoc_detach), + + /* iicbus interface */ + DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD(iicbus_repeated_start, iicoc_iicbus_repeated_start), + DEVMETHOD(iicbus_start, iicoc_iicbus_start), + DEVMETHOD(iicbus_stop, iicoc_iicbus_stop), + DEVMETHOD(iicbus_reset, iicoc_iicbus_reset), + DEVMETHOD(iicbus_write, iicoc_iicbus_write), + DEVMETHOD(iicbus_read, iicoc_iicbus_read), + DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), + + DEVMETHOD_END +}; + +static driver_t iicoc_driver = { + "iicoc", + iicoc_methods, + sizeof(struct iicoc_softc), +}; + +DRIVER_MODULE(iicoc, pci, iicoc_driver, iicoc_devclass, 0, 0);