drivers/wifi: Remove unnecessary data structure copy
[coreboot2.git] / src / soc / rockchip / rk3399 / spi_bitbang.c
blob8bc45e50be7015c2da32b412e2676a74a9cf87e9
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* Compile this driver in place of common/spi.c for bitbang testing.
4 NOTE: Also need to adjust board-specific code for GPIO pinmux! */
6 #include <assert.h>
7 #include <gpio.h>
8 #include <soc/spi.h>
9 #include <spi_bitbang.h>
10 #include <spi_flash.h>
11 #include <stddef.h>
13 struct rockchip_bitbang_slave {
14 struct spi_bitbang_ops ops;
15 gpio_t miso;
16 gpio_t mosi;
17 gpio_t clk;
18 gpio_t cs;
21 static int get_miso(const struct spi_bitbang_ops *ops)
23 const struct rockchip_bitbang_slave *slave =
24 container_of(ops, const struct rockchip_bitbang_slave, ops);
25 return gpio_get(slave->miso);
28 static void set_mosi(const struct spi_bitbang_ops *ops, int value)
30 const struct rockchip_bitbang_slave *slave =
31 container_of(ops, const struct rockchip_bitbang_slave, ops);
32 gpio_set(slave->mosi, value);
35 static void set_clk(const struct spi_bitbang_ops *ops, int value)
37 const struct rockchip_bitbang_slave *slave =
38 container_of(ops, const struct rockchip_bitbang_slave, ops);
39 gpio_set(slave->clk, value);
42 static void set_cs(const struct spi_bitbang_ops *ops, int value)
44 const struct rockchip_bitbang_slave *slave =
45 container_of(ops, const struct rockchip_bitbang_slave, ops);
46 gpio_set(slave->cs, value);
49 /* Can't use GPIO() here because of bug in GCC version used by ChromiumOS. */
50 static const struct rockchip_bitbang_slave slaves[] = {
51 [0] = {
52 .ops = { get_miso, set_mosi, set_clk, set_cs },
53 .miso = { .port = 3, .bank = GPIO_A, .idx = 4 },
54 .mosi = { .port = 3, .bank = GPIO_A, .idx = 5 },
55 .clk = { .port = 3, .bank = GPIO_A, .idx = 6 },
56 .cs = { .port = 3, .bank = GPIO_A, .idx = 7 },
58 [1] = {
59 .ops = { get_miso, set_mosi, set_clk, set_cs },
60 .miso = { .port = 1, .bank = GPIO_A, .idx = 7 },
61 .mosi = { .port = 1, .bank = GPIO_B, .idx = 0 },
62 .clk = { .port = 1, .bank = GPIO_B, .idx = 1 },
63 .cs = { .port = 1, .bank = GPIO_B, .idx = 2 },
65 [2] = {
66 .ops = { get_miso, set_mosi, set_clk, set_cs },
67 .miso = { .port = 2, .bank = GPIO_B, .idx = 1 },
68 .mosi = { .port = 2, .bank = GPIO_B, .idx = 2 },
69 .clk = { .port = 2, .bank = GPIO_B, .idx = 3 },
70 .cs = { .port = 2, .bank = GPIO_B, .idx = 4 },
72 [3] = {
73 .ops = { get_miso, set_mosi, set_clk, set_cs },
74 .miso = { .port = 1, .bank = GPIO_B, .idx = 7 },
75 .mosi = { .port = 1, .bank = GPIO_C, .idx = 0 },
76 .clk = { .port = 1, .bank = GPIO_C, .idx = 1 },
77 .cs = { .port = 1, .bank = GPIO_C, .idx = 2 },
79 [4] = {
80 .ops = { get_miso, set_mosi, set_clk, set_cs },
81 .miso = { .port = 3, .bank = GPIO_A, .idx = 0 },
82 .mosi = { .port = 3, .bank = GPIO_A, .idx = 1 },
83 .clk = { .port = 3, .bank = GPIO_A, .idx = 2 },
84 .cs = { .port = 3, .bank = GPIO_A, .idx = 3 },
86 [5] = {
87 .ops = { get_miso, set_mosi, set_clk, set_cs },
88 .miso = { .port = 2, .bank = GPIO_C, .idx = 4 },
89 .mosi = { .port = 2, .bank = GPIO_C, .idx = 5 },
90 .clk = { .port = 2, .bank = GPIO_C, .idx = 6 },
91 .cs = { .port = 2, .bank = GPIO_C, .idx = 7 },
95 void rockchip_spi_init(unsigned int bus, unsigned int ignored_speed_hz)
97 assert(bus >= 0 && bus < ARRAY_SIZE(slaves));
99 gpio_output(slaves[bus].cs, 1);
100 gpio_output(slaves[bus].clk, 0);
101 gpio_input(slaves[bus].miso);
102 gpio_output(slaves[bus].mosi, 0);
105 void rockchip_spi_set_sample_delay(unsigned int bus, unsigned int delay_ns)
107 /* not supported, and not necessary for slow bitbang speeds */
110 static int spi_ctrlr_claim_bus(const struct spi_slave *slave)
112 assert(slave->bus >= 0 && slave->bus < ARRAY_SIZE(slaves));
113 return spi_bitbang_claim_bus(&slaves[slave->bus].ops);
116 static void spi_ctrlr_release_bus(const struct spi_slave *slave)
118 assert(slave->bus >= 0 && slave->bus < ARRAY_SIZE(slaves));
119 spi_bitbang_release_bus(&slaves[slave->bus].ops);
122 static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,
123 size_t bytes_out, void *din, size_t bytes_in)
125 assert(slave->bus >= 0 && slave->bus < ARRAY_SIZE(slaves));
126 return spi_bitbang_xfer(&slaves[slave->bus].ops,
127 dout, bytes_out, din, bytes_in);
130 static const struct spi_ctrlr spi_ctrlr = {
131 .claim_bus = spi_ctrlr_claim_bus,
132 .release_bus = spi_ctrlr_release_bus,
133 .xfer = spi_ctrlr_xfer,
134 .max_xfer_size = 65535,
137 const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
139 .ctrlr = &spi_ctrlr,
140 .bus_start = 0,
141 .bus_end = ARRAY_SIZE(slaves) - 1,
145 const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);