File indexing completed on 2025-05-11 08:23:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <bsp/fatal.h>
0037 #include <bsp/fdt.h>
0038 #include <bsp/imx-gpio.h>
0039
0040 #include <dev/spi/spi.h>
0041 #include <libfdt.h>
0042 #include <dev/spi/spi-gpio.h>
0043 #include <dev/spi/imx-spi-gpio.h>
0044
0045 struct imx_spi_gpio_bus {
0046 spi_bus base;
0047 struct spi_gpio_params p;
0048
0049 struct imx_gpio_pin sck;
0050 struct imx_gpio_pin mosi;
0051 struct imx_gpio_pin miso;
0052 struct imx_gpio_pin cs[SPI_GPIO_MAX_CS];
0053 };
0054
0055 static void imx_spi_gpio_set(void *arg, bool level)
0056 {
0057 struct imx_gpio_pin *pin = arg;
0058 imx_gpio_set_output(pin, level ? 1 : 0);
0059 }
0060
0061 static bool imx_spi_gpio_get(void *arg)
0062 {
0063 struct imx_gpio_pin *pin = arg;
0064 return (imx_gpio_get_input(pin) != 0);
0065 }
0066
0067 rtems_status_code imx_spi_gpio_init(void)
0068 {
0069 const void *fdt;
0070 int node;
0071 rtems_status_code sc = RTEMS_SUCCESSFUL;
0072
0073 fdt = bsp_fdt_get();
0074 node = -1;
0075
0076 do {
0077 node = fdt_node_offset_by_compatible(fdt, node, "spi-gpio");
0078
0079 if (node >= 0 && imxrt_fdt_node_is_enabled(fdt, node)) {
0080 struct imx_spi_gpio_bus *bus;
0081 const char *bus_path;
0082 const uint32_t *val;
0083 int num_cs;
0084
0085 if (sc == RTEMS_SUCCESSFUL) {
0086 bus = (struct imx_spi_gpio_bus*) spi_bus_alloc_and_init(sizeof(*bus));
0087 if (bus == NULL) {
0088 sc = RTEMS_UNSATISFIED;
0089 }
0090 }
0091
0092 if (sc == RTEMS_SUCCESSFUL) {
0093 bus_path = fdt_getprop(fdt, node, "rtems,path", NULL);
0094 if (bus_path == NULL) {
0095 sc = RTEMS_UNSATISFIED;
0096 }
0097 }
0098
0099 if (sc == RTEMS_SUCCESSFUL) {
0100 sc = imx_gpio_init_from_fdt_property(
0101 &bus->sck, node, "sck-gpios", IMX_GPIO_MODE_OUTPUT, 0);
0102 bus->p.set_clk = imx_spi_gpio_set;
0103 bus->p.set_clk_arg = &bus->sck;
0104 }
0105
0106 if (sc == RTEMS_SUCCESSFUL) {
0107 sc = imx_gpio_init_from_fdt_property(
0108 &bus->miso, node, "miso-gpios", IMX_GPIO_MODE_INPUT, 0);
0109 bus->p.get_miso = imx_spi_gpio_get;
0110 bus->p.get_miso_arg = &bus->miso;
0111 }
0112
0113 if (sc == RTEMS_SUCCESSFUL) {
0114 sc = imx_gpio_init_from_fdt_property(
0115 &bus->mosi, node, "mosi-gpios", IMX_GPIO_MODE_OUTPUT, 0);
0116 bus->p.set_mosi = imx_spi_gpio_set;
0117 bus->p.set_mosi_arg = &bus->mosi;
0118 }
0119
0120 if (sc == RTEMS_SUCCESSFUL) {
0121 val = fdt_getprop(fdt, node, "num-chipselects", NULL);
0122 if (val != NULL) {
0123 ssize_t i;
0124
0125 num_cs = fdt32_to_cpu(val[0]);
0126
0127 for (i = 0; i < num_cs && sc == RTEMS_SUCCESSFUL; ++i) {
0128 sc = imx_gpio_init_from_fdt_property(
0129 &bus->cs[i], node, "cs-gpios", IMX_GPIO_MODE_OUTPUT, 0);
0130 bus->p.set_cs[i] = imx_spi_gpio_set;
0131 bus->p.set_cs_arg[i] = &bus->cs[i];
0132 bus->p.cs_idle[i] = (imx_gpio_get_active_level(&bus->cs[i]) == 0);
0133 }
0134 }
0135 }
0136
0137 if (sc == RTEMS_SUCCESSFUL) {
0138 sc = spi_gpio_init(bus_path, &bus->p);
0139 }
0140
0141 if (sc != RTEMS_SUCCESSFUL && bus != NULL) {
0142 spi_bus_destroy_and_free(&bus->base);
0143 }
0144 }
0145 } while (node >= 0 && sc == RTEMS_SUCCESSFUL);
0146
0147 return sc;
0148 }