diff --git a/bsps/arm/include/dev/spi/imx-spi-gpio.h b/bsps/arm/include/dev/spi/imx-spi-gpio.h new file mode 100644 index 0000000000..31f8fab8fa --- /dev/null +++ b/bsps/arm/include/dev/spi/imx-spi-gpio.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSDeviceIMXSPIGPIO + * + * @brief This header file provides the interfaces of + * @ref RTEMSDeviceIMXSPIGPIO. + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * 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. + */ + +#ifndef _RTEMS_DEV_SPI_IMX_SPI_GPIO_H +#define _RTEMS_DEV_SPI_IMX_SPI_GPIO_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup RTEMSDeviceIMXSPIGPIO + * + * @ingroup RTEMSDeviceSPIGPIO + * + * @brief A SPI bus driver that uses the i.MX/i.MXRT GPIO pins + * + * @{ + */ + +/** + * @brief Register all compatible nodes from the device tree. + * + * Search nodes in the device tree that are compatible to 'spi-gpio' and try to + * register the driver for them. Expects a node that looks (for example) like + * the following: + * + * ``` + * gpiospi: spi { + * status = "okay"; + * compatible = "spi-gpio"; + * #address-cells = <0x1>; + * #size-cells = <0x0>; + * + * sck-gpios = <&gpio2 27 0>; + * miso-gpios = <&gpio2 25 0>; + * mosi-gpios = <&gpio4 14 0>; + * cs-gpios = <&gpio4 10 1>; + * num-chipselects = <1>; + * + * rtems,path = "/dev/gpiospi"; + * }; + * ``` + */ +rtems_status_code imx_spi_gpio_init(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_DEV_SPI_IMX_SPI_GPIO_H */ diff --git a/bsps/arm/shared/spi/imx-spi-gpio.c b/bsps/arm/shared/spi/imx-spi-gpio.c new file mode 100644 index 0000000000..9d165ec365 --- /dev/null +++ b/bsps/arm/shared/spi/imx-spi-gpio.c @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSDeviceIMXSPIGPIO + * + * @brief This file provides the implementation of @ref RTEMSDeviceIMXSPIGPIO. + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * 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 +#include +#include + +#include +#include +#include +#include + +struct imx_spi_gpio_bus { + spi_bus base; + struct spi_gpio_params p; + + struct imx_gpio_pin sck; + struct imx_gpio_pin mosi; + struct imx_gpio_pin miso; + struct imx_gpio_pin cs[SPI_GPIO_MAX_CS]; +}; + +static void imx_spi_gpio_set(void *arg, bool level) +{ + struct imx_gpio_pin *pin = arg; + imx_gpio_set_output(pin, level ? 1 : 0); +} + +static bool imx_spi_gpio_get(void *arg) +{ + struct imx_gpio_pin *pin = arg; + return (imx_gpio_get_input(pin) != 0); +} + +rtems_status_code imx_spi_gpio_init(void) +{ + const void *fdt; + int node; + rtems_status_code sc = RTEMS_SUCCESSFUL; + + fdt = bsp_fdt_get(); + node = -1; + + do { + node = fdt_node_offset_by_compatible(fdt, node, "spi-gpio"); + + if (node >= 0 && imxrt_fdt_node_is_enabled(fdt, node)) { + struct imx_spi_gpio_bus *bus; + const char *bus_path; + const uint32_t *val; + int num_cs; + + if (sc == RTEMS_SUCCESSFUL) { + bus = (struct imx_spi_gpio_bus*) spi_bus_alloc_and_init(sizeof(*bus)); + if (bus == NULL) { + sc = RTEMS_UNSATISFIED; + } + } + + if (sc == RTEMS_SUCCESSFUL) { + bus_path = fdt_getprop(fdt, node, "rtems,path", NULL); + if (bus_path == NULL) { + sc = RTEMS_UNSATISFIED; + } + } + + if (sc == RTEMS_SUCCESSFUL) { + sc = imx_gpio_init_from_fdt_property( + &bus->sck, node, "sck-gpios", IMX_GPIO_MODE_OUTPUT, 0); + bus->p.set_clk = imx_spi_gpio_set; + bus->p.set_clk_arg = &bus->sck; + } + + if (sc == RTEMS_SUCCESSFUL) { + sc = imx_gpio_init_from_fdt_property( + &bus->miso, node, "miso-gpios", IMX_GPIO_MODE_INPUT, 0); + bus->p.get_miso = imx_spi_gpio_get; + bus->p.get_miso_arg = &bus->miso; + } + + if (sc == RTEMS_SUCCESSFUL) { + sc = imx_gpio_init_from_fdt_property( + &bus->mosi, node, "mosi-gpios", IMX_GPIO_MODE_OUTPUT, 0); + bus->p.set_mosi = imx_spi_gpio_set; + bus->p.set_mosi_arg = &bus->mosi; + } + + if (sc == RTEMS_SUCCESSFUL) { + val = fdt_getprop(fdt, node, "num-chipselects", NULL); + if (val != NULL) { + ssize_t i; + + num_cs = fdt32_to_cpu(val[0]); + + for (i = 0; i < num_cs && sc == RTEMS_SUCCESSFUL; ++i) { + sc = imx_gpio_init_from_fdt_property( + &bus->cs[i], node, "cs-gpios", IMX_GPIO_MODE_OUTPUT, 0); + bus->p.set_cs[i] = imx_spi_gpio_set; + bus->p.set_cs_arg[i] = &bus->cs[i]; + bus->p.cs_idle[i] = (imx_gpio_get_active_level(&bus->cs[i]) == 0); + } + } + } + + if (sc == RTEMS_SUCCESSFUL) { + sc = spi_gpio_init(bus_path, &bus->p); + } + + if (sc != RTEMS_SUCCESSFUL && bus != NULL) { + spi_bus_destroy_and_free(&bus->base); + } + } + } while (node >= 0 && sc == RTEMS_SUCCESSFUL); + + return sc; +} diff --git a/spec/build/bsps/arm/imxrt/grp.yml b/spec/build/bsps/arm/imxrt/grp.yml index 12e50c5376..aecf380801 100644 --- a/spec/build/bsps/arm/imxrt/grp.yml +++ b/spec/build/bsps/arm/imxrt/grp.yml @@ -64,6 +64,10 @@ links: uid: ../../objirq - role: build-dependency uid: ../../objdevfsledma +- role: build-dependency + uid: ../objdevimxspigpio +- role: build-dependency + uid: ../../objdevspigpio - role: build-dependency uid: ../../objmem - role: build-dependency diff --git a/spec/build/bsps/arm/objdevimxspigpio.yml b/spec/build/bsps/arm/objdevimxspigpio.yml new file mode 100644 index 0000000000..1dea17bf29 --- /dev/null +++ b/spec/build/bsps/arm/objdevimxspigpio.yml @@ -0,0 +1,17 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: objects +cflags: [] +copyrights: +- Copyright (C) 2024 embedded brains GmbH & Co. KG +cppflags: [] +cxxflags: [] +enabled-by: true +includes: [] +install: +- destination: ${BSP_INCLUDEDIR}/dev/spi + source: + - bsps/arm/include/dev/spi/imx-spi-gpio.h +links: [] +source: +- bsps/arm/shared/spi/imx-spi-gpio.c +type: build