coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
spi_bitbang.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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! */
5 
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>
12 
14  struct spi_bitbang_ops ops;
19 };
20 
21 static int get_miso(const struct spi_bitbang_ops *ops)
22 {
23  const struct rockchip_bitbang_slave *slave =
25  return gpio_get(slave->miso);
26 }
27 
28 static void set_mosi(const struct spi_bitbang_ops *ops, int value)
29 {
30  const struct rockchip_bitbang_slave *slave =
32  gpio_set(slave->mosi, value);
33 }
34 
35 static void set_clk(const struct spi_bitbang_ops *ops, int value)
36 {
37  const struct rockchip_bitbang_slave *slave =
39  gpio_set(slave->clk, value);
40 }
41 
42 static void set_cs(const struct spi_bitbang_ops *ops, int value)
43 {
44  const struct rockchip_bitbang_slave *slave =
47 }
48 
49 /* Can't use GPIO() here because of bug in GCC version used by Chromium OS. */
50 static const struct rockchip_bitbang_slave slaves[] = {
51  [0] = {
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 },
57  },
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 },
64  },
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 },
71  },
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 },
78  },
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 },
85  },
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 },
92  },
93 };
94 
95 void rockchip_spi_init(unsigned int bus, unsigned int ignored_speed_hz)
96 {
97  assert(bus >= 0 && bus < ARRAY_SIZE(slaves));
98 
99  gpio_output(slaves[bus].cs, 1);
100  gpio_output(slaves[bus].clk, 0);
102  gpio_output(slaves[bus].mosi, 0);
103 }
104 
105 void rockchip_spi_set_sample_delay(unsigned int bus, unsigned int delay_ns)
106 {
107  /* not supported, and not necessary for slow bitbang speeds */
108 }
109 
110 static int spi_ctrlr_claim_bus(const struct spi_slave *slave)
111 {
112  assert(slave->bus >= 0 && slave->bus < ARRAY_SIZE(slaves));
114 }
115 
116 static void spi_ctrlr_release_bus(const struct spi_slave *slave)
117 {
118  assert(slave->bus >= 0 && slave->bus < ARRAY_SIZE(slaves));
120 }
121 
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)
124 {
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);
128 }
129 
130 static const struct spi_ctrlr spi_ctrlr = {
132  .release_bus = spi_ctrlr_release_bus,
133  .xfer = spi_ctrlr_xfer,
134  .max_xfer_size = 65535,
135 };
136 
137 const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
138  {
139  .ctrlr = &spi_ctrlr,
140  .bus_start = 0,
141  .bus_end = ARRAY_SIZE(slaves) - 1,
142  },
143 };
144 
pte_t value
Definition: mmu.c:91
#define assert(statement)
Definition: assert.h:74
int spi_bitbang_xfer(const struct spi_bitbang_ops *ops, const void *dout, size_t bytes_out, void *din, size_t bytes_in)
Definition: bitbang.c:29
int spi_bitbang_claim_bus(const struct spi_bitbang_ops *ops)
Definition: bitbang.c:17
void spi_bitbang_release_bus(const struct spi_bitbang_ops *ops)
Definition: bitbang.c:23
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define container_of(ptr, type, member)
container_of - cast a member of a structure out to the containing structure
Definition: helpers.h:33
int gpio_get(gpio_t gpio)
Definition: gpio.c:166
void gpio_input(gpio_t gpio)
Definition: gpio.c:189
void gpio_output(gpio_t gpio, int value)
Definition: gpio.c:194
void gpio_set(gpio_t gpio, int value)
Definition: gpio.c:174
static struct device_operations ops
Definition: ipmi_kcs_ops.c:416
@ GPIO_B
Definition: gpio.h:48
@ GPIO_C
Definition: gpio.h:49
@ GPIO_A
Definition: gpio.h:47
static void spi_ctrlr_release_bus(const struct spi_slave *slave)
Definition: spi_bitbang.c:116
static const struct spi_ctrlr spi_ctrlr
Definition: spi_bitbang.c:130
static const struct rockchip_bitbang_slave slaves[]
Definition: spi_bitbang.c:50
void rockchip_spi_init(unsigned int bus, unsigned int ignored_speed_hz)
Definition: spi_bitbang.c:95
static void set_cs(const struct spi_bitbang_ops *ops, int value)
Definition: spi_bitbang.c:42
const struct spi_ctrlr_buses spi_ctrlr_bus_map[]
Definition: spi_bitbang.c:137
void rockchip_spi_set_sample_delay(unsigned int bus, unsigned int delay_ns)
Definition: spi_bitbang.c:105
static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, void *din, size_t bytes_in)
Definition: spi_bitbang.c:122
static int get_miso(const struct spi_bitbang_ops *ops)
Definition: spi_bitbang.c:21
static void set_mosi(const struct spi_bitbang_ops *ops, int value)
Definition: spi_bitbang.c:28
static int spi_ctrlr_claim_bus(const struct spi_slave *slave)
Definition: spi_bitbang.c:110
static void set_clk(const struct spi_bitbang_ops *ops, int value)
Definition: spi_bitbang.c:35
const size_t spi_ctrlr_bus_map_count
Definition: spi_bitbang.c:145
static struct spi_slave slave
Definition: spiconsole.c:7
Definition: device.h:76
struct spi_bitbang_ops ops
Definition: spi_bitbang.c:14
const struct spi_ctrlr * ctrlr
Definition: spi-generic.h:175
int(* claim_bus)(const struct spi_slave *slave)
Definition: spi-generic.h:149
unsigned int bus
Definition: spi-generic.h:41
unsigned int cs
Definition: spi-generic.h:42