2 * Copyright (c) 2014 Google, Inc
5 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
7 * Influenced by code from:
8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
10 * SPDX-License-Identifier: GPL-2.0+
21 DECLARE_GLOBAL_DATA_PTR
;
23 struct soft_spi_platdata
{
24 struct fdt_gpio_state cs
;
25 struct fdt_gpio_state sclk
;
26 struct fdt_gpio_state mosi
;
27 struct fdt_gpio_state miso
;
31 struct soft_spi_priv
{
35 static int soft_spi_scl(struct udevice
*dev
, int bit
)
37 struct soft_spi_platdata
*plat
= dev
->platdata
;
38 struct soft_spi_priv
*priv
= dev_get_priv(dev
);
40 gpio_set_value(plat
->sclk
.gpio
, priv
->mode
& SPI_CPOL
? bit
: !bit
);
45 static int soft_spi_sda(struct udevice
*dev
, int bit
)
47 struct soft_spi_platdata
*plat
= dev
->platdata
;
49 gpio_set_value(plat
->mosi
.gpio
, bit
);
54 static int soft_spi_cs_activate(struct udevice
*dev
)
56 struct soft_spi_platdata
*plat
= dev
->platdata
;
57 struct soft_spi_priv
*priv
= dev_get_priv(dev
);
59 gpio_set_value(plat
->cs
.gpio
, !(priv
->mode
& SPI_CS_HIGH
));
60 gpio_set_value(plat
->sclk
.gpio
, priv
->mode
& SPI_CPOL
);
61 gpio_set_value(plat
->cs
.gpio
, priv
->mode
& SPI_CS_HIGH
);
66 static int soft_spi_cs_deactivate(struct udevice
*dev
)
68 struct soft_spi_platdata
*plat
= dev
->platdata
;
69 struct soft_spi_priv
*priv
= dev_get_priv(dev
);
71 gpio_set_value(plat
->cs
.gpio
, !(priv
->mode
& SPI_CS_HIGH
));
76 static int soft_spi_claim_bus(struct udevice
*dev
)
79 * Make sure the SPI clock is in idle state as defined for
82 return soft_spi_scl(dev
, 0);
85 static int soft_spi_release_bus(struct udevice
*dev
)
91 /*-----------------------------------------------------------------------
94 * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
95 * "bitlen" bits in the SPI MISO port. That's just the way SPI works.
97 * The source of the outgoing bits is the "dout" parameter and the
98 * destination of the input bits is the "din" parameter. Note that "dout"
99 * and "din" can point to the same memory location, in which case the
100 * input data overwrites the output data (since both are buffered by
101 * temporary variables, this is OK).
103 static int soft_spi_xfer(struct udevice
*dev
, unsigned int bitlen
,
104 const void *dout
, void *din
, unsigned long flags
)
106 struct soft_spi_priv
*priv
= dev_get_priv(dev
);
107 struct soft_spi_platdata
*plat
= dev
->platdata
;
110 const u8
*txd
= dout
;
112 int cpol
= priv
->mode
& SPI_CPOL
;
113 int cpha
= priv
->mode
& SPI_CPHA
;
116 debug("spi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
117 dev
->parent
->name
, dev
->name
, *(uint
*)txd
, *(uint
*)rxd
,
120 if (flags
& SPI_XFER_BEGIN
)
121 soft_spi_cs_activate(dev
);
123 for (j
= 0; j
< bitlen
; j
++) {
125 * Check if it is time to work on a new byte.
140 soft_spi_scl(dev
, !cpol
);
141 soft_spi_sda(dev
, tmpdout
& 0x80);
142 udelay(plat
->spi_delay_us
);
144 soft_spi_scl(dev
, !cpol
);
146 soft_spi_scl(dev
, cpol
);
148 tmpdin
|= gpio_get_value(plat
->miso
.gpio
);
150 udelay(plat
->spi_delay_us
);
152 soft_spi_scl(dev
, cpol
);
155 * If the number of bits isn't a multiple of 8, shift the last
156 * bits over to left-justify them. Then store the last byte
160 if ((bitlen
% 8) != 0)
161 tmpdin
<<= 8 - (bitlen
% 8);
165 if (flags
& SPI_XFER_END
)
166 soft_spi_cs_deactivate(dev
);
171 static int soft_spi_set_speed(struct udevice
*dev
, unsigned int speed
)
173 /* Accept any speed */
177 static int soft_spi_set_mode(struct udevice
*dev
, unsigned int mode
)
179 struct soft_spi_priv
*priv
= dev_get_priv(dev
);
186 static int soft_spi_child_pre_probe(struct udevice
*dev
)
188 struct spi_slave
*slave
= dev_get_parentdata(dev
);
191 return spi_ofdata_to_platdata(gd
->fdt_blob
, dev
->of_offset
, slave
);
194 static const struct dm_spi_ops soft_spi_ops
= {
195 .claim_bus
= soft_spi_claim_bus
,
196 .release_bus
= soft_spi_release_bus
,
197 .xfer
= soft_spi_xfer
,
198 .set_speed
= soft_spi_set_speed
,
199 .set_mode
= soft_spi_set_mode
,
202 static int soft_spi_ofdata_to_platdata(struct udevice
*dev
)
204 struct soft_spi_platdata
*plat
= dev
->platdata
;
205 const void *blob
= gd
->fdt_blob
;
206 int node
= dev
->of_offset
;
208 if (fdtdec_decode_gpio(blob
, node
, "cs-gpio", &plat
->cs
) ||
209 fdtdec_decode_gpio(blob
, node
, "sclk-gpio", &plat
->sclk
) ||
210 fdtdec_decode_gpio(blob
, node
, "mosi-gpio", &plat
->mosi
) ||
211 fdtdec_decode_gpio(blob
, node
, "miso-gpio", &plat
->miso
))
213 plat
->spi_delay_us
= fdtdec_get_int(blob
, node
, "spi-delay-us", 0);
218 static int soft_spi_probe(struct udevice
*dev
)
220 struct spi_slave
*slave
= dev_get_parentdata(dev
);
221 struct soft_spi_platdata
*plat
= dev
->platdata
;
223 gpio_request(plat
->cs
.gpio
, "soft_spi_cs");
224 gpio_request(plat
->sclk
.gpio
, "soft_spi_sclk");
225 gpio_request(plat
->mosi
.gpio
, "soft_spi_mosi");
226 gpio_request(plat
->miso
.gpio
, "soft_spi_miso");
228 gpio_direction_output(plat
->sclk
.gpio
, slave
->mode
& SPI_CPOL
);
229 gpio_direction_output(plat
->mosi
.gpio
, 1);
230 gpio_direction_input(plat
->miso
.gpio
);
231 gpio_direction_output(plat
->cs
.gpio
, !(slave
->mode
& SPI_CS_HIGH
));
236 static const struct udevice_id soft_spi_ids
[] = {
237 { .compatible
= "u-boot,soft-spi" },
241 U_BOOT_DRIVER(soft_spi
) = {
244 .of_match
= soft_spi_ids
,
245 .ops
= &soft_spi_ops
,
246 .ofdata_to_platdata
= soft_spi_ofdata_to_platdata
,
247 .platdata_auto_alloc_size
= sizeof(struct soft_spi_platdata
),
248 .priv_auto_alloc_size
= sizeof(struct soft_spi_priv
),
249 .per_child_auto_alloc_size
= sizeof(struct spi_slave
),
250 .probe
= soft_spi_probe
,
251 .child_pre_probe
= soft_spi_child_pre_probe
,