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! */
9 #include <spi_bitbang.h>
10 #include <spi_flash.h>
13 struct rockchip_bitbang_slave
{
14 struct spi_bitbang_ops ops
;
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
[] = {
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 },
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 },
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 },
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 },
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 },
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
[] = {
141 .bus_end
= ARRAY_SIZE(slaves
) - 1,
145 const size_t spi_ctrlr_bus_map_count
= ARRAY_SIZE(spi_ctrlr_bus_map
);