dev_sdhci_host.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-08-16 zhujiale first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #define DBG_TAG "SDHCI"
  13. #ifdef RT_SDIO_DEBUG
  14. #define DBG_LVL DBG_LOG
  15. #else
  16. #define DBG_LVL DBG_INFO
  17. #endif /* RT_SDIO_DEBUG */
  18. #include <rtdbg.h>
  19. #include "dev_sdio_dm.h"
  20. #include "dev_sdhci_dm.h"
  21. static void rt_plat_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
  22. {
  23. rt_uint32_t flags = req->cmd->flags;
  24. struct rt_mmc_host *mmc = rt_container_of(host, struct rt_mmc_host, rthost);
  25. switch (flags & RESP_MASK)
  26. {
  27. case RESP_NONE:
  28. flags |= MMC_RSP_NONE;
  29. break;
  30. case RESP_R1:
  31. flags |= MMC_RSP_R1;
  32. break;
  33. case RESP_R1B:
  34. flags |= MMC_RSP_R1B;
  35. break;
  36. case RESP_R2:
  37. flags |= MMC_RSP_R2;
  38. break;
  39. case RESP_R3:
  40. flags |= MMC_RSP_R3;
  41. break;
  42. case RESP_R4:
  43. flags |= MMC_RSP_R4;
  44. break;
  45. case RESP_R5:
  46. flags |= MMC_RSP_R5;
  47. break;
  48. case RESP_R6:
  49. flags |= MMC_RSP_R6;
  50. break;
  51. case RESP_R7:
  52. flags |= MMC_RSP_R7;
  53. break;
  54. }
  55. if (req->data)
  56. {
  57. if ((rt_uint64_t)rt_kmem_v2p(req->data->buf) > 0xffffffff)
  58. {
  59. void *req_buf = RT_NULL;
  60. void *dma_buffer = rt_malloc(req->data->blks * req->data->blksize);
  61. if (req->data->flags & DATA_DIR_WRITE)
  62. {
  63. rt_memcpy(dma_buffer, req->data->buf, req->data->blks * req->data->blksize);
  64. req_buf = req->data->buf;
  65. req->data->buf = dma_buffer;
  66. }
  67. else if (req->data->flags & DATA_DIR_READ)
  68. {
  69. req_buf = req->data->buf;
  70. req->data->buf = dma_buffer;
  71. }
  72. req->cmd->flags |= flags;
  73. mmc->ops->request(mmc, req);
  74. rt_sem_take(&host->sem_ack, RT_WAITING_FOREVER);
  75. if (req->data->flags & DATA_DIR_READ)
  76. {
  77. rt_memcpy(req_buf, dma_buffer, req->data->blksize * req->data->blks);
  78. req->data->buf = req_buf;
  79. }
  80. else
  81. {
  82. req->data->buf = req_buf;
  83. }
  84. rt_free(dma_buffer);
  85. rt_sem_release(&host->sem_ack);
  86. }
  87. else
  88. {
  89. req->cmd->flags |= flags;
  90. mmc->ops->request(mmc, req);
  91. }
  92. }
  93. else
  94. {
  95. req->cmd->flags |= flags;
  96. mmc->ops->request(mmc, req);
  97. }
  98. }
  99. static void rt_plat_set_ioconfig(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *iocfg)
  100. {
  101. struct rt_mmc_host *mmc = rt_container_of(host, struct rt_mmc_host, rthost);
  102. LOG_D("clock: %u, width: %u, power: %u, vdd: %u, timing: %u",
  103. iocfg->clock, iocfg->bus_width,
  104. iocfg->power_mode, iocfg->vdd, iocfg->timing);
  105. mmc->ops->set_ios(mmc, iocfg);
  106. }
  107. static rt_int32_t rt_plat_get_card_status(struct rt_mmcsd_host *host)
  108. {
  109. struct rt_mmc_host *mmc = rt_container_of(host, struct rt_mmc_host, rthost);
  110. return mmc->ops->get_cd(mmc);
  111. }
  112. static rt_int32_t rt_plat_execute_tuning(struct rt_mmcsd_host *host, rt_int32_t opcode)
  113. {
  114. struct rt_mmc_host *mmc = rt_container_of(host, struct rt_mmc_host, rthost);
  115. return mmc->ops->execute_tuning(mmc, opcode);
  116. }
  117. static void rt_plat_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t en)
  118. {
  119. struct rt_mmc_host *mmc = rt_container_of(host, struct rt_mmc_host, rthost);
  120. return mmc->ops->enable_sdio_irq(mmc, en);
  121. }
  122. static rt_bool_t rt_plat_card_busy(struct rt_mmcsd_host *host)
  123. {
  124. struct rt_mmc_host *mmc = rt_container_of(host, struct rt_mmc_host, rthost);
  125. return mmc->ops->card_busy(mmc);
  126. }
  127. static rt_err_t rt_plat_signal_voltage_switch(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
  128. {
  129. struct rt_mmc_host *mmc = rt_container_of(host, struct rt_mmc_host, rthost);
  130. return mmc->ops->start_signal_voltage_switch(mmc, io_cfg);
  131. }
  132. static const struct rt_mmcsd_host_ops rt_mmcsd_ops =
  133. {
  134. .request = rt_plat_request,
  135. .set_iocfg = rt_plat_set_ioconfig,
  136. .get_card_status = rt_plat_get_card_status,
  137. .enable_sdio_irq = rt_plat_enable_sdio_irq,
  138. .execute_tuning = rt_plat_execute_tuning,
  139. .card_busy = rt_plat_card_busy,
  140. .signal_voltage_switch = rt_plat_signal_voltage_switch,
  141. };
  142. void rt_mmc_request_done(struct rt_mmc_host *host, struct rt_mmcsd_req *mrq)
  143. {
  144. mmcsd_req_complete(&host->rthost);
  145. }
  146. /* Add host in rtt while sdhci complete */
  147. rt_err_t rt_mmc_add_host(struct rt_mmc_host *mmc)
  148. {
  149. mmc->rthost.ops = &rt_mmcsd_ops;
  150. mmc->rthost.flags = mmc->caps;
  151. mmc->rthost.freq_max = mmc->f_max;
  152. mmc->rthost.freq_min = mmc->f_min;
  153. mmc->rthost.max_dma_segs = mmc->max_segs;
  154. mmc->rthost.max_seg_size = mmc->max_seg_size;
  155. mmc->rthost.max_blk_size = mmc->max_blk_size;
  156. mmc->rthost.max_blk_count = mmc->max_blk_count;
  157. mmc->rthost.valid_ocr = mmc->ocr_avail;
  158. mmcsd_change(&mmc->rthost);
  159. return RT_EOK;
  160. }
  161. struct rt_mmc_host *rt_mmc_alloc_host(int extra, struct rt_device *dev)
  162. {
  163. struct rt_mmc_host *mmc;
  164. mmc = rt_calloc(1, sizeof(*mmc) + extra);
  165. if (mmc)
  166. {
  167. mmc->parent = dev;
  168. mmcsd_host_init(&mmc->rthost);
  169. }
  170. return mmc;
  171. }
  172. void rt_mmc_remove_host(struct rt_mmc_host *host)
  173. {
  174. rt_free(host);
  175. }
  176. rt_err_t rt_mmc_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
  177. {
  178. return RT_EOK;
  179. }
  180. rt_err_t rt_mmc_gpio_get_cd(struct rt_mmc_host *host)
  181. {
  182. return -RT_ENOSYS;
  183. }
  184. void rt_mmc_detect_change(struct rt_mmc_host *host, rt_ubase_t delay)
  185. {
  186. }
  187. rt_bool_t rt_mmc_can_gpio_ro(struct rt_mmc_host *host)
  188. {
  189. return RT_FALSE;
  190. }
  191. rt_err_t rt_mmc_gpio_get_ro(struct rt_mmc_host *host)
  192. {
  193. return RT_EOK;
  194. }
  195. rt_err_t rt_mmc_send_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
  196. {
  197. return RT_EOK;
  198. }
  199. rt_err_t rt_mmc_of_parse(struct rt_mmc_host *host)
  200. {
  201. rt_err_t err;
  202. struct rt_device *dev = host->parent;
  203. if (!dev || !dev->ofw_node)
  204. {
  205. return RT_EOK;
  206. }
  207. err = sdio_ofw_parse(dev->ofw_node, &host->rthost);
  208. if (err)
  209. {
  210. return err;
  211. }
  212. host->caps |= host->rthost.flags;
  213. if (rt_dm_dev_prop_read_bool(dev, "no-sdio"))
  214. {
  215. host->caps2 |= MMC_CAP2_NO_SDIO;
  216. }
  217. if (rt_dm_dev_prop_read_bool(dev, "no-sd"))
  218. {
  219. host->caps2 |= MMC_CAP2_NO_SD;
  220. }
  221. return RT_EOK;
  222. }
  223. void rt_mmc_free_host(struct rt_mmc_host *host)
  224. {
  225. }
  226. rt_bool_t rt_mmc_can_gpio_cd(struct rt_mmc_host *host)
  227. {
  228. return RT_FALSE;
  229. }