dev_spi_dm.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-12-06 GuEe-GUI first version
  9. */
  10. #include "dev_spi_dm.h"
  11. #define DBG_TAG "spi.dm"
  12. #define DBG_LVL DBG_INFO
  13. #include <rtdbg.h>
  14. #ifdef RT_USING_OFW
  15. static void ofw_parse_delay(struct rt_ofw_node *np, struct rt_spi_delay *delay,
  16. const char *prop)
  17. {
  18. rt_uint32_t value;
  19. if (!rt_ofw_prop_read_u32(np, prop, &value))
  20. {
  21. if (value > RT_UINT16_MAX)
  22. {
  23. delay->value = RT_DIV_ROUND_UP(value, 1000);
  24. delay->unit = RT_SPI_DELAY_UNIT_USECS;
  25. }
  26. else
  27. {
  28. delay->value = value;
  29. delay->unit = RT_SPI_DELAY_UNIT_NSECS;
  30. }
  31. }
  32. }
  33. rt_err_t spi_device_ofw_parse(struct rt_spi_device *spi_dev)
  34. {
  35. rt_err_t err;
  36. rt_uint32_t value, cs[RT_SPI_CS_CNT_MAX];
  37. struct rt_spi_bus *spi_bus = spi_dev->bus;
  38. struct rt_ofw_node *np = spi_dev->parent.ofw_node;
  39. struct rt_spi_configuration *conf = &spi_dev->config;
  40. if (rt_ofw_prop_read_bool(np, "spi-cpha"))
  41. {
  42. conf->mode |= RT_SPI_CPHA;
  43. }
  44. if (rt_ofw_prop_read_bool(np, "spi-cpol"))
  45. {
  46. conf->mode |= RT_SPI_CPOL;
  47. }
  48. if (rt_ofw_prop_read_bool(np, "spi-3wire"))
  49. {
  50. conf->mode |= RT_SPI_3WIRE;
  51. }
  52. if (rt_ofw_prop_read_bool(np, "spi-lsb-first"))
  53. {
  54. conf->mode |= RT_SPI_LSB;
  55. }
  56. if (rt_ofw_prop_read_bool(np, "spi-cs-high"))
  57. {
  58. conf->mode |= RT_SPI_CS_HIGH;
  59. }
  60. value = 1;
  61. rt_ofw_prop_read_u32(np, "spi-tx-bus-width", &value);
  62. conf->data_width_tx = value;
  63. value = 1;
  64. rt_ofw_prop_read_u32(np, "spi-rx-bus-width", &value);
  65. conf->data_width_rx = value;
  66. if (spi_bus->slave)
  67. {
  68. if (!rt_ofw_node_tag_equ(np, "slave"))
  69. {
  70. LOG_E("Invalid SPI device = %s", rt_ofw_node_full_name(np));
  71. return -RT_EINVAL;
  72. }
  73. return RT_EOK;
  74. }
  75. value = rt_ofw_prop_read_u32_array_index(np, "reg", 0, RT_SPI_CS_CNT_MAX, cs);
  76. if ((rt_int32_t)value < 0)
  77. {
  78. err = (rt_err_t)value;
  79. LOG_E("Find 'reg' failed");
  80. return err;
  81. }
  82. for (int i = 0; i < value; ++i)
  83. {
  84. spi_dev->chip_select[i] = cs[i];
  85. }
  86. if (!rt_ofw_prop_read_u32(np, "spi-max-frequency", &value))
  87. {
  88. conf->max_hz = value;
  89. }
  90. ofw_parse_delay(np, &spi_dev->cs_setup, "spi-cs-setup-delay-ns");
  91. ofw_parse_delay(np, &spi_dev->cs_hold, "spi-cs-hold-delay-ns");
  92. ofw_parse_delay(np, &spi_dev->cs_inactive, "spi-cs-inactive-delay-ns");
  93. return RT_EOK;
  94. }
  95. #endif /* RT_USING_OFW */