Index: sys/arm/freescale/vybrid/vf_i2c.h =================================================================== --- /dev/null +++ sys/arm/freescale/vybrid/vf_i2c.h @@ -0,0 +1,56 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Ruslan Bukin + * 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 AUTHOR 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 AUTHOR 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. + */ + +#ifndef __VF_I2C_H__ +#define __VF_I2C_H__ + +#define VF_I2C_DEVSTR "Vybrid Family Inter-Integrated Circuit (I2C)" + +#define HW_UNKNOWN 0x00 +#define HW_MVF600 0x01 +#define HW_VF610 0x02 + +struct i2c_softc { + struct resource *res[2]; + bus_space_tag_t bst; + bus_space_handle_t bsh; +#ifdef EXT_RESOURCES + clk_t clock; + uint32_t freq; +#endif + device_t dev; + device_t iicbus; + struct mtx mutex; + uintptr_t hwtype; +}; + +extern driver_t vf_i2c_driver; + +device_attach_t vf_i2c_attach_common; + +#endif /* !__VF_I2C_H__ */ Index: sys/arm/freescale/vybrid/vf_i2c.c =================================================================== --- sys/arm/freescale/vybrid/vf_i2c.c +++ sys/arm/freescale/vybrid/vf_i2c.c @@ -53,10 +53,6 @@ #include "iicbus_if.h" -#include -#include -#include - #ifdef EXT_RESOURCES #include #endif @@ -66,6 +62,7 @@ #include #include +#include #define I2C_IBAD 0x0 /* I2C Bus Address Register */ #define I2C_IBFD 0x1 /* I2C Bus Frequency Divider Register */ @@ -97,37 +94,18 @@ #define vf_i2c_dbg(_sc, fmt, args...) #endif -#define HW_UNKNOWN 0x00 -#define HW_MVF600 0x01 -#define HW_VF610 0x02 - static int i2c_repeated_start(device_t, u_char, int); static int i2c_start(device_t, u_char, int); static int i2c_stop(device_t); static int i2c_reset(device_t, u_char, u_char, u_char *); static int i2c_read(device_t, char *, int, int *, int, int); static int i2c_write(device_t, const char *, int, int *, int); -static phandle_t i2c_get_node(device_t, device_t); struct i2c_div_type { uint32_t reg_val; uint32_t div; }; -struct i2c_softc { - struct resource *res[2]; - bus_space_tag_t bst; - bus_space_handle_t bsh; -#ifdef EXT_RESOURCES - clk_t clock; - uint32_t freq; -#endif - device_t dev; - device_t iicbus; - struct mtx mutex; - uintptr_t hwtype; -}; - static struct resource_spec i2c_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { SYS_RES_IRQ, 0, RF_ACTIVE }, @@ -151,54 +129,12 @@ }; #endif -static const struct ofw_compat_data i2c_compat_data[] = { - {"fsl,mvf600-i2c", HW_MVF600}, - {"fsl,vf610-i2c", HW_VF610}, - {NULL, HW_UNKNOWN} -}; - -static int -i2c_probe(device_t dev) +int +vf_i2c_attach_common(device_t dev) { - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_search_compatible(dev, i2c_compat_data)->ocd_data) - return (ENXIO); - - device_set_desc(dev, "Vybrid Family Inter-Integrated Circuit (I2C)"); - return (BUS_PROBE_DEFAULT); -} - -static int -i2c_attach(device_t dev) -{ - struct i2c_softc *sc; -#ifdef EXT_RESOURCES - phandle_t node; -#endif + struct i2c_softc *sc = device_get_softc(dev); int error; - sc = device_get_softc(dev); - sc->dev = dev; - sc->hwtype = ofw_bus_search_compatible(dev, i2c_compat_data)->ocd_data; -#ifdef EXT_RESOURCES - node = ofw_bus_get_node(dev); - - error = clk_get_by_ofw_index(dev, node, 0, &sc->clock); - if (error != 0) { - sc->freq = 0; - device_printf(dev, "Parent clock not found.\n"); - } else { - if (OF_hasprop(node, "clock-frequency")) - OF_getencprop(node, "clock-frequency", &sc->freq, - sizeof(sc->freq)); - else - sc->freq = 100000; - } -#endif - mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); error = bus_alloc_resources(dev, i2c_spec, sc->res); @@ -576,20 +512,9 @@ return (IIC_NOERR); } -static phandle_t -i2c_get_node(device_t bus, device_t dev) -{ - - return ofw_bus_get_node(bus); -} - static device_method_t i2c_methods[] = { - DEVMETHOD(device_probe, i2c_probe), - DEVMETHOD(device_attach, i2c_attach), DEVMETHOD(device_detach, i2c_detach), - DEVMETHOD(ofw_bus_get_node, i2c_get_node), - DEVMETHOD(iicbus_callback, iicbus_null_callback), DEVMETHOD(iicbus_repeated_start, i2c_repeated_start), DEVMETHOD(iicbus_start, i2c_start), @@ -602,14 +527,8 @@ { 0, 0 } }; -static driver_t i2c_driver = { +driver_t vf_i2c_driver = { "i2c", i2c_methods, sizeof(struct i2c_softc), }; - -static devclass_t i2c_devclass; - -DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0); -DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); -DRIVER_MODULE(ofw_iicbus, i2c, ofw_iicbus_driver, ofw_iicbus_devclass, 0, 0); Index: sys/arm/freescale/vybrid/vf_i2c_acpi.c =================================================================== --- /dev/null +++ sys/arm/freescale/vybrid/vf_i2c_acpi.c @@ -0,0 +1,113 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Ruslan Bukin + * 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 AUTHOR 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 AUTHOR 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 "opt_acpi.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +/* Required for the softc */ +#ifdef EXT_RESOURCES +#include +#endif + +#include + +static char *vf_i2c_ids[] = { + "NXP0001", + NULL +}; + +static int +i2c_acpi_probe(device_t dev) +{ + int rv; + + if (acpi_disabled("vf_i2c")) + return (ENXIO); + + rv = ACPI_ID_PROBE(device_get_parent(dev), dev, vf_i2c_ids, NULL); + if (rv > 0) + return (rv); + + device_set_desc(dev, VF_I2C_DEVSTR); + return (BUS_PROBE_DEFAULT); +} + +static int +i2c_acpi_attach(device_t dev) +{ + struct i2c_softc *sc; + + sc = device_get_softc(dev); + sc->dev = dev; + sc->hwtype = HW_VF610; + sc->freq = 0; + + return vf_i2c_attach_common(dev); +} + +static device_method_t i2c_acpi_methods[] = { + DEVMETHOD(device_probe, i2c_acpi_probe), + DEVMETHOD(device_attach, i2c_acpi_attach), + + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), + + { 0, 0 } +}; + +DEFINE_CLASS_1(i2c, vf_i2c_acpi_driver, i2c_acpi_methods, + sizeof(struct i2c_softc), vf_i2c_driver); + +static devclass_t vf_i2c_acpi_devclass; + +DRIVER_MODULE(i2c, acpi, vf_i2c_acpi_driver, vf_i2c_acpi_devclass, 0, 0); +DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); +DRIVER_MODULE(acpi_iicbus, i2c, acpi_iicbus_driver, iicbus_devclass, 0, 0); Index: sys/arm/freescale/vybrid/vf_i2c_fdt.c =================================================================== --- /dev/null +++ sys/arm/freescale/vybrid/vf_i2c_fdt.c @@ -0,0 +1,124 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Ruslan Bukin + * 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 AUTHOR 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 AUTHOR 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 + +#ifdef EXT_RESOURCES +#include +#endif + +#include + +static const struct ofw_compat_data i2c_compat_data[] = { + {"fsl,mvf600-i2c", HW_MVF600}, + {"fsl,vf610-i2c", HW_VF610}, + {NULL, HW_UNKNOWN} +}; + +static int +i2c_fdt_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, i2c_compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, VF_I2C_DEVSTR); + return (BUS_PROBE_DEFAULT); +} + +static int +i2c_fdt_attach(device_t dev) +{ + struct i2c_softc *sc; +#ifdef EXT_RESOURCES + phandle_t node; +#endif + int error; + + sc = device_get_softc(dev); + sc->dev = dev; + sc->hwtype = ofw_bus_search_compatible(dev, i2c_compat_data)->ocd_data; +#ifdef EXT_RESOURCES + node = ofw_bus_get_node(dev); + + error = clk_get_by_ofw_index(dev, node, 0, &sc->clock); + if (error != 0) { + sc->freq = 0; + device_printf(dev, "Parent clock not found.\n"); + } else { + if (OF_hasprop(node, "clock-frequency")) + OF_getencprop(node, "clock-frequency", &sc->freq, + sizeof(sc->freq)); + else + sc->freq = 100000; + } +#endif + + return vf_i2c_attach_common(dev); +} + +static phandle_t +i2c_get_node(device_t bus, device_t dev) +{ + + return ofw_bus_get_node(bus); +} + +static device_method_t i2c_fdt_methods[] = { + DEVMETHOD(device_probe, i2c_fdt_probe), + DEVMETHOD(device_attach, i2c_fdt_attach), + + DEVMETHOD(ofw_bus_get_node, i2c_get_node), + + { 0, 0 } +}; + +DEFINE_CLASS_1(i2c, vf_i2c_fdt_driver, i2c_fdt_methods, + sizeof(struct i2c_softc), vf_i2c_driver); + +static devclass_t vf_i2c_fdt_devclass; + +DRIVER_MODULE(i2c, simplebus, vf_i2c_fdt_driver, vf_i2c_fdt_devclass, 0, 0); +DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0); +DRIVER_MODULE(ofw_iicbus, i2c, ofw_iicbus_driver, ofw_iicbus_devclass, 0, 0); Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -107,7 +107,9 @@ arm/broadcom/bcm2835/bcm2835_wdog.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2836.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt soc_brcm_bcm2837 | dwcotg fdt soc_brcm_bcm2838 -arm/freescale/vybrid/vf_i2c.c optional vf_i2c iicbus SOC_NXP_LS1046A +arm/freescale/vybrid/vf_i2c.c optional iicbus +arm/freescale/vybrid/vf_i2c_acpi.c optional iicbus acpi +arm/freescale/vybrid/vf_i2c_fdt.c optional iicbus fdt # SOC_NXP_LS1046A arm/mv/a37x0_gpio.c optional a37x0_gpio gpio fdt arm/mv/a37x0_iic.c optional a37x0_iic iicbus fdt arm/mv/a37x0_spi.c optional a37x0_spi spibus fdt