soft_spi.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2014 Google, Inc
  4. *
  5. * (C) Copyright 2002
  6. * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
  7. *
  8. * Influenced by code from:
  9. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  10. */
  11. #include <common.h>
  12. #include <dm.h>
  13. #include <errno.h>
  14. #include <fdtdec.h>
  15. #include <log.h>
  16. #include <malloc.h>
  17. #include <spi.h>
  18. #include <asm/gpio.h>
  19. #include <linux/bitops.h>
  20. #include <linux/delay.h>
  21. DECLARE_GLOBAL_DATA_PTR;
  22. struct soft_spi_platdata {
  23. struct gpio_desc cs;
  24. struct gpio_desc sclk;
  25. struct gpio_desc mosi;
  26. struct gpio_desc miso;
  27. int spi_delay_us;
  28. int flags;
  29. };
  30. #define SPI_MASTER_NO_RX BIT(0)
  31. #define SPI_MASTER_NO_TX BIT(1)
  32. struct soft_spi_priv {
  33. unsigned int mode;
  34. };
  35. static int soft_spi_scl(struct udevice *dev, int bit)
  36. {
  37. struct udevice *bus = dev_get_parent(dev);
  38. struct soft_spi_platdata *plat = dev_get_platdata(bus);
  39. dm_gpio_set_value(&plat->sclk, bit);
  40. return 0;
  41. }
  42. static int soft_spi_sda(struct udevice *dev, int bit)
  43. {
  44. struct udevice *bus = dev_get_parent(dev);
  45. struct soft_spi_platdata *plat = dev_get_platdata(bus);
  46. dm_gpio_set_value(&plat->mosi, bit);
  47. return 0;
  48. }
  49. static int soft_spi_cs_activate(struct udevice *dev)
  50. {
  51. struct udevice *bus = dev_get_parent(dev);
  52. struct soft_spi_priv *priv = dev_get_priv(bus);
  53. struct soft_spi_platdata *plat = dev_get_platdata(bus);
  54. int cidle = !!(priv->mode & SPI_CPOL);
  55. dm_gpio_set_value(&plat->cs, 0);
  56. dm_gpio_set_value(&plat->sclk, cidle); /* to idle */
  57. dm_gpio_set_value(&plat->cs, 1);
  58. return 0;
  59. }
  60. static int soft_spi_cs_deactivate(struct udevice *dev)
  61. {
  62. struct udevice *bus = dev_get_parent(dev);
  63. struct soft_spi_platdata *plat = dev_get_platdata(bus);
  64. dm_gpio_set_value(&plat->cs, 0);
  65. return 0;
  66. }
  67. static int soft_spi_claim_bus(struct udevice *dev)
  68. {
  69. struct udevice *bus = dev_get_parent(dev);
  70. struct soft_spi_priv *priv = dev_get_priv(bus);
  71. int cidle = !!(priv->mode & SPI_CPOL);
  72. /*
  73. * Make sure the SPI clock is in idle state as defined for
  74. * this slave.
  75. */
  76. return soft_spi_scl(dev, cidle);
  77. }
  78. static int soft_spi_release_bus(struct udevice *dev)
  79. {
  80. /* Nothing to do */
  81. return 0;
  82. }
  83. /*-----------------------------------------------------------------------
  84. * SPI transfer
  85. *
  86. * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
  87. * "bitlen" bits in the SPI MISO port. That's just the way SPI works.
  88. *
  89. * The source of the outgoing bits is the "dout" parameter and the
  90. * destination of the input bits is the "din" parameter. Note that "dout"
  91. * and "din" can point to the same memory location, in which case the
  92. * input data overwrites the output data (since both are buffered by
  93. * temporary variables, this is OK).
  94. */
  95. static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
  96. const void *dout, void *din, unsigned long flags)
  97. {
  98. struct udevice *bus = dev_get_parent(dev);
  99. struct soft_spi_priv *priv = dev_get_priv(bus);
  100. struct soft_spi_platdata *plat = dev_get_platdata(bus);
  101. uchar tmpdin = 0;
  102. uchar tmpdout = 0;
  103. const u8 *txd = dout;
  104. u8 *rxd = din;
  105. int cpha = !!(priv->mode & SPI_CPHA);
  106. int cidle = !!(priv->mode & SPI_CPOL);
  107. unsigned int j;
  108. debug("spi_xfer: slave %s:%s dout %08X din %08X bitlen %u\n",
  109. dev->parent->name, dev->name, *(uint *)txd, *(uint *)rxd,
  110. bitlen);
  111. if (flags & SPI_XFER_BEGIN)
  112. soft_spi_cs_activate(dev);
  113. for (j = 0; j < bitlen; j++) {
  114. /*
  115. * Check if it is time to work on a new byte.
  116. */
  117. if ((j % 8) == 0) {
  118. if (txd)
  119. tmpdout = *txd++;
  120. else
  121. tmpdout = 0;
  122. if (j != 0) {
  123. if (rxd)
  124. *rxd++ = tmpdin;
  125. }
  126. tmpdin = 0;
  127. }
  128. /*
  129. * CPOL 0: idle is low (0), active is high (1)
  130. * CPOL 1: idle is high (1), active is low (0)
  131. */
  132. /*
  133. * drive bit
  134. * CPHA 1: CLK from idle to active
  135. */
  136. if (cpha)
  137. soft_spi_scl(dev, !cidle);
  138. if ((plat->flags & SPI_MASTER_NO_TX) == 0)
  139. soft_spi_sda(dev, !!(tmpdout & 0x80));
  140. udelay(plat->spi_delay_us);
  141. /*
  142. * sample bit
  143. * CPHA 0: CLK from idle to active
  144. * CPHA 1: CLK from active to idle
  145. */
  146. if (!cpha)
  147. soft_spi_scl(dev, !cidle);
  148. else
  149. soft_spi_scl(dev, cidle);
  150. tmpdin <<= 1;
  151. if ((plat->flags & SPI_MASTER_NO_RX) == 0)
  152. tmpdin |= dm_gpio_get_value(&plat->miso);
  153. tmpdout <<= 1;
  154. udelay(plat->spi_delay_us);
  155. /*
  156. * drive bit
  157. * CPHA 0: CLK from active to idle
  158. */
  159. if (!cpha)
  160. soft_spi_scl(dev, cidle);
  161. }
  162. /*
  163. * If the number of bits isn't a multiple of 8, shift the last
  164. * bits over to left-justify them. Then store the last byte
  165. * read in.
  166. */
  167. if (rxd) {
  168. if ((bitlen % 8) != 0)
  169. tmpdin <<= 8 - (bitlen % 8);
  170. *rxd++ = tmpdin;
  171. }
  172. if (flags & SPI_XFER_END)
  173. soft_spi_cs_deactivate(dev);
  174. return 0;
  175. }
  176. static int soft_spi_set_speed(struct udevice *dev, unsigned int speed)
  177. {
  178. /* Ignore any speed settings. Speed is implemented via "spi-delay-us" */
  179. return 0;
  180. }
  181. static int soft_spi_set_mode(struct udevice *dev, unsigned int mode)
  182. {
  183. struct soft_spi_priv *priv = dev_get_priv(dev);
  184. priv->mode = mode;
  185. return 0;
  186. }
  187. static const struct dm_spi_ops soft_spi_ops = {
  188. .claim_bus = soft_spi_claim_bus,
  189. .release_bus = soft_spi_release_bus,
  190. .xfer = soft_spi_xfer,
  191. .set_speed = soft_spi_set_speed,
  192. .set_mode = soft_spi_set_mode,
  193. };
  194. static int soft_spi_ofdata_to_platdata(struct udevice *dev)
  195. {
  196. struct soft_spi_platdata *plat = dev->platdata;
  197. const void *blob = gd->fdt_blob;
  198. int node = dev_of_offset(dev);
  199. plat->spi_delay_us = fdtdec_get_int(blob, node, "spi-delay-us", 0);
  200. return 0;
  201. }
  202. static int soft_spi_probe(struct udevice *dev)
  203. {
  204. struct spi_slave *slave = dev_get_parent_priv(dev);
  205. struct soft_spi_platdata *plat = dev->platdata;
  206. int cs_flags, clk_flags;
  207. int ret;
  208. cs_flags = (slave && slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
  209. clk_flags = (slave && slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;
  210. if (gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs,
  211. GPIOD_IS_OUT | cs_flags) ||
  212. gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,
  213. GPIOD_IS_OUT | clk_flags))
  214. return -EINVAL;
  215. ret = gpio_request_by_name(dev, "gpio-mosi", 0, &plat->mosi,
  216. GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
  217. if (ret)
  218. plat->flags |= SPI_MASTER_NO_TX;
  219. ret = gpio_request_by_name(dev, "gpio-miso", 0, &plat->miso,
  220. GPIOD_IS_IN);
  221. if (ret)
  222. plat->flags |= SPI_MASTER_NO_RX;
  223. if ((plat->flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX)) ==
  224. (SPI_MASTER_NO_RX | SPI_MASTER_NO_TX))
  225. return -EINVAL;
  226. return 0;
  227. }
  228. static const struct udevice_id soft_spi_ids[] = {
  229. { .compatible = "spi-gpio" },
  230. { }
  231. };
  232. U_BOOT_DRIVER(soft_spi) = {
  233. .name = "soft_spi",
  234. .id = UCLASS_SPI,
  235. .of_match = soft_spi_ids,
  236. .ops = &soft_spi_ops,
  237. .ofdata_to_platdata = soft_spi_ofdata_to_platdata,
  238. .platdata_auto_alloc_size = sizeof(struct soft_spi_platdata),
  239. .priv_auto_alloc_size = sizeof(struct soft_spi_priv),
  240. .probe = soft_spi_probe,
  241. };