dev_spi.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. #include <rtthread.h>
  10. #include "drivers/dev_spi.h"
  11. #define DBG_TAG "spi.dev"
  12. #define DBG_LVL DBG_INFO
  13. #include <rtdbg.h>
  14. #ifdef RT_USING_DM
  15. #include "dev_spi_dm.h"
  16. #endif
  17. /* SPI bus device interface, compatible with RT-Thread 0.3.x/1.0.x */
  18. static rt_ssize_t _spi_bus_device_read(rt_device_t dev,
  19. rt_off_t pos,
  20. void *buffer,
  21. rt_size_t size)
  22. {
  23. struct rt_spi_bus *bus;
  24. bus = (struct rt_spi_bus *)dev;
  25. RT_ASSERT(bus != RT_NULL);
  26. RT_ASSERT(bus->owner != RT_NULL);
  27. return rt_spi_transfer(bus->owner, RT_NULL, buffer, size);
  28. }
  29. static rt_ssize_t _spi_bus_device_write(rt_device_t dev,
  30. rt_off_t pos,
  31. const void *buffer,
  32. rt_size_t size)
  33. {
  34. struct rt_spi_bus *bus;
  35. bus = (struct rt_spi_bus *)dev;
  36. RT_ASSERT(bus != RT_NULL);
  37. RT_ASSERT(bus->owner != RT_NULL);
  38. return rt_spi_transfer(bus->owner, buffer, RT_NULL, size);
  39. }
  40. #ifdef RT_USING_DEVICE_OPS
  41. const static struct rt_device_ops spi_bus_ops =
  42. {
  43. RT_NULL,
  44. RT_NULL,
  45. RT_NULL,
  46. _spi_bus_device_read,
  47. _spi_bus_device_write,
  48. RT_NULL
  49. };
  50. #endif
  51. rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name)
  52. {
  53. struct rt_device *device;
  54. RT_ASSERT(bus != RT_NULL);
  55. device = &bus->parent;
  56. /* set device type */
  57. device->type = RT_Device_Class_SPIBUS;
  58. /* initialize device interface */
  59. #ifdef RT_USING_DEVICE_OPS
  60. device->ops = &spi_bus_ops;
  61. #else
  62. device->init = RT_NULL;
  63. device->open = RT_NULL;
  64. device->close = RT_NULL;
  65. device->read = _spi_bus_device_read;
  66. device->write = _spi_bus_device_write;
  67. device->control = RT_NULL;
  68. #endif
  69. /* register to device manager */
  70. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
  71. }
  72. /* SPI Dev device interface, compatible with RT-Thread 0.3.x/1.0.x */
  73. static rt_ssize_t _spidev_device_read(rt_device_t dev,
  74. rt_off_t pos,
  75. void *buffer,
  76. rt_size_t size)
  77. {
  78. struct rt_spi_device *device;
  79. device = (struct rt_spi_device *)dev;
  80. RT_ASSERT(device != RT_NULL);
  81. RT_ASSERT(device->bus != RT_NULL);
  82. return rt_spi_transfer(device, RT_NULL, buffer, size);
  83. }
  84. static rt_ssize_t _spidev_device_write(rt_device_t dev,
  85. rt_off_t pos,
  86. const void *buffer,
  87. rt_size_t size)
  88. {
  89. struct rt_spi_device *device;
  90. device = (struct rt_spi_device *)dev;
  91. RT_ASSERT(device != RT_NULL);
  92. RT_ASSERT(device->bus != RT_NULL);
  93. return rt_spi_transfer(device, buffer, RT_NULL, size);
  94. }
  95. static rt_err_t _spidev_device_control(rt_device_t dev,
  96. int cmd,
  97. void *args)
  98. {
  99. switch (cmd)
  100. {
  101. case 0: /* set device */
  102. break;
  103. case 1:
  104. break;
  105. }
  106. return RT_EOK;
  107. }
  108. #ifdef RT_USING_DEVICE_OPS
  109. const static struct rt_device_ops spi_device_ops =
  110. {
  111. RT_NULL,
  112. RT_NULL,
  113. RT_NULL,
  114. _spidev_device_read,
  115. _spidev_device_write,
  116. _spidev_device_control
  117. };
  118. #endif
  119. rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name)
  120. {
  121. struct rt_device *device;
  122. RT_ASSERT(dev != RT_NULL);
  123. device = &(dev->parent);
  124. /* set device type */
  125. device->type = RT_Device_Class_SPIDevice;
  126. #ifdef RT_USING_DEVICE_OPS
  127. device->ops = &spi_device_ops;
  128. #else
  129. device->init = RT_NULL;
  130. device->open = RT_NULL;
  131. device->close = RT_NULL;
  132. device->read = _spidev_device_read;
  133. device->write = _spidev_device_write;
  134. device->control = _spidev_device_control;
  135. #endif
  136. /* register to device manager */
  137. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
  138. }
  139. #ifdef RT_USING_DM
  140. static rt_err_t spidev_probe(struct rt_spi_device *spi_dev)
  141. {
  142. const char *bus_name;
  143. struct rt_device *dev = &spi_dev->parent;
  144. if (spi_dev->parent.ofw_node)
  145. {
  146. if (rt_dm_dev_prop_index_of_string(dev, "compatible", "spidev") >= 0)
  147. {
  148. LOG_E("spidev is not supported in OFW");
  149. return -RT_EINVAL;
  150. }
  151. }
  152. bus_name = rt_dm_dev_get_name(&spi_dev->bus->parent);
  153. rt_dm_dev_set_name(dev, "%s_%d", bus_name, spi_dev->chip_select[0]);
  154. return RT_EOK;
  155. }
  156. static const struct rt_spi_device_id spidev_ids[] =
  157. {
  158. { .name = "dh2228fv" },
  159. { .name = "ltc2488" },
  160. { .name = "sx1301" },
  161. { .name = "bk4" },
  162. { .name = "dhcom-board" },
  163. { .name = "m53cpld" },
  164. { .name = "spi-petra" },
  165. { .name = "spi-authenta" },
  166. { .name = "em3581" },
  167. { .name = "si3210" },
  168. { /* sentinel */ },
  169. };
  170. static const struct rt_ofw_node_id spidev_ofw_ids[] =
  171. {
  172. { .compatible = "cisco,spi-petra" },
  173. { .compatible = "dh,dhcom-board" },
  174. { .compatible = "lineartechnology,ltc2488" },
  175. { .compatible = "lwn,bk4" },
  176. { .compatible = "menlo,m53cpld" },
  177. { .compatible = "micron,spi-authenta" },
  178. { .compatible = "rohm,dh2228fv" },
  179. { .compatible = "semtech,sx1301" },
  180. { .compatible = "silabs,em3581" },
  181. { .compatible = "silabs,si3210" },
  182. { .compatible = "rockchip,spidev" },
  183. { /* sentinel */ },
  184. };
  185. static struct rt_spi_driver spidev_driver =
  186. {
  187. .ids = spidev_ids,
  188. .ofw_ids = spidev_ofw_ids,
  189. .probe = spidev_probe,
  190. };
  191. RT_SPI_DRIVER_EXPORT(spidev_driver);
  192. #endif /* RT_USING_DM */