1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2014 Google, Inc
6 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
8 * Influenced by code from:
9 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
20 DECLARE_GLOBAL_DATA_PTR
;
22 struct soft_spi_platdata
{
24 struct gpio_desc sclk
;
25 struct gpio_desc mosi
;
26 struct gpio_desc miso
;
31 #define SPI_MASTER_NO_RX BIT(0)
32 #define SPI_MASTER_NO_TX BIT(1)
34 struct soft_spi_priv
{
38 static int soft_spi_scl(struct udevice
*dev
, int bit
)
40 struct udevice
*bus
= dev_get_parent(dev
);
41 struct soft_spi_platdata
*plat
= dev_get_platdata(bus
);
43 dm_gpio_set_value(&plat
->sclk
, bit
);
48 static int soft_spi_sda(struct udevice
*dev
, int bit
)
50 struct udevice
*bus
= dev_get_parent(dev
);
51 struct soft_spi_platdata
*plat
= dev_get_platdata(bus
);
53 dm_gpio_set_value(&plat
->mosi
, bit
);
58 static int soft_spi_cs_activate(struct udevice
*dev
)
60 struct udevice
*bus
= dev_get_parent(dev
);
61 struct soft_spi_platdata
*plat
= dev_get_platdata(bus
);
63 dm_gpio_set_value(&plat
->cs
, 0);
64 dm_gpio_set_value(&plat
->sclk
, 0);
65 dm_gpio_set_value(&plat
->cs
, 1);
70 static int soft_spi_cs_deactivate(struct udevice
*dev
)
72 struct udevice
*bus
= dev_get_parent(dev
);
73 struct soft_spi_platdata
*plat
= dev_get_platdata(bus
);
75 dm_gpio_set_value(&plat
->cs
, 0);
80 static int soft_spi_claim_bus(struct udevice
*dev
)
83 * Make sure the SPI clock is in idle state as defined for
86 return soft_spi_scl(dev
, 0);
89 static int soft_spi_release_bus(struct udevice
*dev
)
95 /*-----------------------------------------------------------------------
98 * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
99 * "bitlen" bits in the SPI MISO port. That's just the way SPI works.
101 * The source of the outgoing bits is the "dout" parameter and the
102 * destination of the input bits is the "din" parameter. Note that "dout"
103 * and "din" can point to the same memory location, in which case the
104 * input data overwrites the output data (since both are buffered by
105 * temporary variables, this is OK).
107 static int soft_spi_xfer(struct udevice
*dev
, unsigned int bitlen
,
108 const void *dout
, void *din
, unsigned long flags
)
110 struct udevice
*bus
= dev_get_parent(dev
);
111 struct soft_spi_priv
*priv
= dev_get_priv(bus
);
112 struct soft_spi_platdata
*plat
= dev_get_platdata(bus
);
115 const u8
*txd
= dout
;
117 int cpha
= priv
->mode
& SPI_CPHA
;
120 debug("spi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
121 dev
->parent
->name
, dev
->name
, *(uint
*)txd
, *(uint
*)rxd
,
124 if (flags
& SPI_XFER_BEGIN
)
125 soft_spi_cs_activate(dev
);
127 for (j
= 0; j
< bitlen
; j
++) {
129 * Check if it is time to work on a new byte.
144 soft_spi_scl(dev
, 0);
145 if ((plat
->flags
& SPI_MASTER_NO_TX
) == 0)
146 soft_spi_sda(dev
, !!(tmpdout
& 0x80));
147 udelay(plat
->spi_delay_us
);
149 soft_spi_scl(dev
, 0);
151 soft_spi_scl(dev
, 1);
153 if ((plat
->flags
& SPI_MASTER_NO_RX
) == 0)
154 tmpdin
|= dm_gpio_get_value(&plat
->miso
);
156 udelay(plat
->spi_delay_us
);
158 soft_spi_scl(dev
, 1);
161 * If the number of bits isn't a multiple of 8, shift the last
162 * bits over to left-justify them. Then store the last byte
166 if ((bitlen
% 8) != 0)
167 tmpdin
<<= 8 - (bitlen
% 8);
171 if (flags
& SPI_XFER_END
)
172 soft_spi_cs_deactivate(dev
);
177 static int soft_spi_set_speed(struct udevice
*dev
, unsigned int speed
)
179 /* Accept any speed */
183 static int soft_spi_set_mode(struct udevice
*dev
, unsigned int mode
)
185 struct soft_spi_priv
*priv
= dev_get_priv(dev
);
192 static const struct dm_spi_ops soft_spi_ops
= {
193 .claim_bus
= soft_spi_claim_bus
,
194 .release_bus
= soft_spi_release_bus
,
195 .xfer
= soft_spi_xfer
,
196 .set_speed
= soft_spi_set_speed
,
197 .set_mode
= soft_spi_set_mode
,
200 static int soft_spi_ofdata_to_platdata(struct udevice
*dev
)
202 struct soft_spi_platdata
*plat
= dev
->platdata
;
203 const void *blob
= gd
->fdt_blob
;
204 int node
= dev_of_offset(dev
);
206 plat
->spi_delay_us
= fdtdec_get_int(blob
, node
, "spi-delay-us", 0);
211 static int soft_spi_probe(struct udevice
*dev
)
213 struct spi_slave
*slave
= dev_get_parent_priv(dev
);
214 struct soft_spi_platdata
*plat
= dev
->platdata
;
215 int cs_flags
, clk_flags
;
218 cs_flags
= (slave
->mode
& SPI_CS_HIGH
) ? 0 : GPIOD_ACTIVE_LOW
;
219 clk_flags
= (slave
->mode
& SPI_CPOL
) ? GPIOD_ACTIVE_LOW
: 0;
221 if (gpio_request_by_name(dev
, "cs-gpios", 0, &plat
->cs
,
222 GPIOD_IS_OUT
| cs_flags
) ||
223 gpio_request_by_name(dev
, "gpio-sck", 0, &plat
->sclk
,
224 GPIOD_IS_OUT
| clk_flags
))
227 ret
= gpio_request_by_name(dev
, "gpio-mosi", 0, &plat
->mosi
,
228 GPIOD_IS_OUT
| GPIOD_IS_OUT_ACTIVE
);
230 plat
->flags
|= SPI_MASTER_NO_TX
;
232 ret
= gpio_request_by_name(dev
, "gpio-miso", 0, &plat
->miso
,
235 plat
->flags
|= SPI_MASTER_NO_RX
;
237 if ((plat
->flags
& (SPI_MASTER_NO_RX
| SPI_MASTER_NO_TX
)) ==
238 (SPI_MASTER_NO_RX
| SPI_MASTER_NO_TX
))
244 static const struct udevice_id soft_spi_ids
[] = {
245 { .compatible
= "spi-gpio" },
249 U_BOOT_DRIVER(soft_spi
) = {
252 .of_match
= soft_spi_ids
,
253 .ops
= &soft_spi_ops
,
254 .ofdata_to_platdata
= soft_spi_ofdata_to_platdata
,
255 .platdata_auto_alloc_size
= sizeof(struct soft_spi_platdata
),
256 .priv_auto_alloc_size
= sizeof(struct soft_spi_priv
),
257 .probe
= soft_spi_probe
,