drv_i2c.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. /* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
  2. *
  3. * Redistribution and use in source and binary forms, with or without
  4. * modification, are permitted provided that the following conditions are met:
  5. * 1. Redistributions of source code must retain the above copyright
  6. * notice, this list of conditions and the following disclaimer.
  7. * 2. Redistributions in binary form must reproduce the above copyright
  8. * notice, this list of conditions and the following disclaimer in the
  9. * documentation and/or other materials provided with the distribution.
  10. *
  11. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  12. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  13. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  15. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  16. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  17. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  18. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  21. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  22. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. /*
  26. * Copyright (c) 2006-2025 RT-Thread Development Team
  27. *
  28. * SPDX-License-Identifier: Apache-2.0
  29. */
  30. #include <rtthread.h>
  31. #include <rthw.h>
  32. #include <rtdevice.h>
  33. #include <riscv_io.h>
  34. #include <ioremap.h>
  35. #include "board.h"
  36. #include "drv_i2c.h"
  37. #include "sysctl_clk.h"
  38. #undef DBG_TAG
  39. #undef DBG_LVL
  40. #define DBG_TAG "drv_i2c"
  41. #define DBG_LVL DBG_INFO
  42. #include <rtdbg.h>
  43. struct _i2c_speed_cfg
  44. {
  45. rt_uint16_t hcnt;
  46. rt_uint16_t lcnt;
  47. rt_uint16_t spklen;
  48. };
  49. struct k230_i2c_dev
  50. {
  51. struct rt_i2c_bus_device dev;
  52. const char *name;
  53. rt_ubase_t base;
  54. size_t size;
  55. int vector;
  56. rt_uint32_t clock;
  57. struct rt_i2c_msg *msg;
  58. struct _i2c_speed_cfg speed_cfg;
  59. };
  60. static rt_size_t k230_i2c_get_timer(rt_size_t base)
  61. {
  62. return rt_tick_get() - base ;
  63. }
  64. static void k230_i2c_enable(struct k230_i2c_dev *dev, rt_bool_t enable)
  65. {
  66. volatile i2c_t *i2c = (i2c_t *)dev->base;
  67. rt_uint32_t en_value = enable ? 1 : 0;
  68. int timeout = 100;
  69. do
  70. {
  71. i2c->enable.enable = en_value;
  72. if(i2c->enable_status.en == en_value)
  73. {
  74. return;
  75. }
  76. /*
  77. * Wait 10 times the signaling period of the highest I2C
  78. * transfer supported by the driver (for 400KHz this is
  79. * 25us) as described in the DesignWare I2C databook.
  80. */
  81. rt_hw_us_delay(25);
  82. }while(timeout--);
  83. LOG_E("timeout in %s i2c\n", enable ? "enable" : "disable");
  84. }
  85. static void k230_i2c_set_bus_timeout(struct k230_i2c_dev *dev, rt_uint32_t timeout)
  86. {
  87. float tick = 0;
  88. tick = RT_TICK_PER_SECOND / 1000.0f; /* ms to tick */
  89. dev->dev.timeout = (rt_uint32_t)(timeout * tick);
  90. }
  91. static int k230_i2c_set_bus_speed(struct k230_i2c_dev *dev, rt_uint32_t speed)
  92. {
  93. volatile i2c_t *i2c = (i2c_t *)dev->base;
  94. rt_uint32_t i2c_spd, period, spklen, ft;
  95. /*
  96. * Calculate clock counts for I2C speed
  97. * hcnt + lcnt + spklen + 7 + 1 + fall_time * clk = clk / speed
  98. * fall_time = 10ns
  99. * spklen = 0~50ns
  100. */
  101. spklen = dev->clock * 10 / 1e9;
  102. ft = dev->clock * 10 / 1e9;
  103. period = dev->clock / speed;
  104. period = period - spklen - 7 - 1 - ft;
  105. dev->speed_cfg.lcnt = period / 2;
  106. dev->speed_cfg.hcnt = period - dev->speed_cfg.lcnt;
  107. dev->speed_cfg.spklen = spklen;
  108. if(speed <= I2C_STANDARD_SPEED_UP)
  109. {
  110. i2c_spd = I2C_SPEED_MODE_STANDARD;
  111. }
  112. else if(speed <= I2C_FAST_SPEED_UP)
  113. {
  114. i2c_spd = I2C_SPEED_MODE_FAST;
  115. }
  116. else if(speed <= I2C_MAX_SPEED_UP)
  117. {
  118. i2c_spd = I2C_SPEED_MODE_MAX;
  119. }
  120. else
  121. {
  122. return -RT_EINVAL;
  123. }
  124. /* to set speed cltr must be disabled */
  125. k230_i2c_enable(dev, RT_FALSE);
  126. switch(i2c_spd)
  127. {
  128. case I2C_SPEED_MODE_STANDARD:
  129. i2c->ss_ufm_scl_hcnt.cnt = dev->speed_cfg.hcnt;
  130. i2c->ss_ufm_scl_lcnt.cnt = dev->speed_cfg.lcnt;
  131. i2c->fs_ufm_spklen.spklen = dev->speed_cfg.spklen;
  132. break;
  133. case I2C_SPEED_MODE_FAST:
  134. i2c->fs_scl_hcnt_ufm_tbuf_cnt.cnt = dev->speed_cfg.hcnt;
  135. i2c->fs_scl_lcnt.cnt = dev->speed_cfg.lcnt;
  136. i2c->fs_ufm_spklen.spklen = dev->speed_cfg.spklen;
  137. break;
  138. case I2C_SPEED_MODE_MAX:
  139. i2c->hs_scl_hcnt.cnt = dev->speed_cfg.hcnt;
  140. i2c->hs_scl_lcnt.cnt = dev->speed_cfg.lcnt;
  141. i2c->hs_spklen.spklen = dev->speed_cfg.spklen;
  142. break;
  143. default: break;
  144. }
  145. i2c->con.speed = i2c_spd;
  146. /* Enable back i2c now speed set */
  147. k230_i2c_enable(dev, RT_TRUE);
  148. return RT_EOK;
  149. }
  150. static void k230_i2c_set_addr(struct k230_i2c_dev *dev)
  151. {
  152. volatile i2c_t *i2c = (i2c_t *)dev->base;
  153. rt_uint16_t i2c_addr = dev->msg->addr;
  154. /* Disable i2c */
  155. k230_i2c_enable(dev, RT_FALSE);
  156. if(dev->msg->flags & RT_I2C_ADDR_10BIT || dev->dev.flags & RT_I2C_ADDR_10BIT)
  157. {
  158. i2c->tar.master_10bit_addr = 1;
  159. i2c_addr &= 0x3FF;
  160. }
  161. else
  162. {
  163. i2c->tar.master_10bit_addr = 0;
  164. i2c_addr &= 0x7F;
  165. }
  166. i2c->tar.tar = i2c_addr;
  167. /* Enable i2c */
  168. k230_i2c_enable(dev, RT_TRUE);
  169. }
  170. static void k230_i2c_flush_rxfifo(struct k230_i2c_dev *dev)
  171. {
  172. volatile i2c_t *i2c = (i2c_t *)dev->base;
  173. while(i2c->status.rfne)
  174. {
  175. readl(&i2c->data_cmd);
  176. }
  177. }
  178. static int k230_i2c_wait_for_bus_busy(struct k230_i2c_dev *dev)
  179. {
  180. rt_size_t start_time = k230_i2c_get_timer(0);
  181. volatile i2c_t *i2c = (i2c_t *)dev->base;
  182. while((i2c->status.mst_activity) || !(i2c->status.tfe))
  183. {
  184. /* Evaluate timeout */
  185. if(k230_i2c_get_timer(start_time) > (rt_size_t)dev->dev.timeout * I2C_TX_FIFO_SIZE)
  186. {
  187. return -RT_ETIMEOUT;
  188. }
  189. }
  190. return RT_EOK;
  191. }
  192. static int k230_i2c_xfer_init(struct k230_i2c_dev *dev)
  193. {
  194. volatile i2c_t *i2c = (i2c_t *)dev->base;
  195. rt_uint8_t addr = 0;
  196. if(k230_i2c_wait_for_bus_busy(dev) != RT_EOK)
  197. {
  198. return -RT_EBUSY;
  199. }
  200. k230_i2c_set_addr(dev);
  201. return RT_EOK;
  202. }
  203. static int k230_i2c_xfer_finish(struct k230_i2c_dev *dev)
  204. {
  205. volatile i2c_t *i2c = (i2c_t *)dev->base;
  206. rt_uint32_t start_stop_det = k230_i2c_get_timer(0);
  207. while (1)
  208. {
  209. if(i2c->raw_intr_stat.stop_det)
  210. {
  211. readl(&i2c->clr_stop_det);
  212. break;
  213. }
  214. else if (k230_i2c_get_timer(start_stop_det) > dev->dev.timeout)
  215. {
  216. break;
  217. }
  218. }
  219. if (k230_i2c_wait_for_bus_busy(dev) != RT_EOK)
  220. {
  221. return -RT_EBUSY;
  222. }
  223. k230_i2c_flush_rxfifo(dev);
  224. return RT_EOK;
  225. }
  226. static int _k230_i2c_read(struct k230_i2c_dev *dev)
  227. {
  228. volatile i2c_t *i2c = (i2c_t *)dev->base;
  229. rt_size_t start_time_rx = 0;
  230. rt_uint32_t recv_len = dev->msg->len;
  231. rt_uint32_t tran_len = dev->msg->len;
  232. rt_uint8_t *buffer = dev->msg->buf;
  233. rt_uint32_t cmd = 0;
  234. /* If no start condition is sent before reading, then send a repeated start. */
  235. if(dev->msg->flags & RT_I2C_NO_START)
  236. {
  237. cmd |= I2C_DATA_CMD_RESTART;
  238. }
  239. else
  240. {
  241. if(k230_i2c_xfer_init(dev) != RT_EOK)
  242. {
  243. return -RT_EBUSY;
  244. }
  245. }
  246. start_time_rx = k230_i2c_get_timer(0);
  247. while(recv_len || tran_len)
  248. {
  249. if (tran_len)
  250. {
  251. while(i2c->status.tfnf == 0);
  252. /* Write stop when the last byte */
  253. cmd = tran_len == 1 ? cmd | I2C_DATA_CMD_STOP : cmd;
  254. /* Write to data cmd register to trigger i2c */
  255. writel(cmd | I2C_DATA_CMD_READ, &i2c->data_cmd);
  256. cmd = 0;
  257. tran_len--;
  258. }
  259. if(i2c->status.rfne)
  260. {
  261. *buffer++ = i2c->data_cmd.dat;
  262. recv_len--;
  263. start_time_rx = k230_i2c_get_timer(0);
  264. }
  265. else if(k230_i2c_get_timer(start_time_rx) > dev->dev.timeout)
  266. {
  267. return -RT_ETIMEOUT;
  268. }
  269. }
  270. return k230_i2c_xfer_finish(dev);
  271. }
  272. static int _k230_i2c_write(struct k230_i2c_dev *dev)
  273. {
  274. volatile i2c_t *i2c = (i2c_t *)dev->base;
  275. rt_size_t start_time_tx = 0;
  276. rt_uint32_t tran_len = dev->msg->len;
  277. rt_uint8_t *buffer = dev->msg->buf;
  278. rt_uint32_t cmd = 0;
  279. rt_uint32_t cut = 0;
  280. if (k230_i2c_xfer_init(dev) != RT_EOK)
  281. {
  282. return -RT_EBUSY;
  283. }
  284. start_time_tx = k230_i2c_get_timer(0);
  285. while(tran_len)
  286. {
  287. if(i2c->status.tfnf)
  288. {
  289. /* If there is no stop flag, the stop condition will not be sent at the last byte. */
  290. if(tran_len == 1 && !(dev->msg->flags & RT_I2C_NO_STOP))
  291. {
  292. cmd |= I2C_DATA_CMD_STOP;
  293. }
  294. else
  295. {
  296. cmd &= ~I2C_DATA_CMD_STOP;
  297. }
  298. cmd |= *buffer++;
  299. writel(cmd, &i2c->data_cmd);
  300. cmd = 0;
  301. tran_len--;
  302. start_time_tx = k230_i2c_get_timer(0);
  303. }
  304. else if(k230_i2c_get_timer(start_time_tx) > dev->dev.timeout)
  305. {
  306. return -RT_ETIMEOUT;
  307. }
  308. }
  309. if (dev->msg->flags & RT_I2C_NO_STOP)
  310. {
  311. return RT_EOK;
  312. }
  313. if (k230_i2c_wait_for_bus_busy(dev) != RT_EOK)
  314. {
  315. return -RT_EBUSY;
  316. }
  317. return RT_EOK;
  318. }
  319. static rt_ssize_t k230_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
  320. {
  321. struct k230_i2c_dev *i2c_dev = rt_container_of(bus, struct k230_i2c_dev, dev);
  322. volatile i2c_t *i2c = (i2c_t *)i2c_dev->base;
  323. int ret;
  324. rt_ssize_t send_mesgs = num;
  325. for (; num > 0; num--, msgs++)
  326. {
  327. i2c_dev->msg = msgs;
  328. if(msgs->flags & RT_I2C_RD)
  329. {
  330. ret = _k230_i2c_read(i2c_dev);
  331. }
  332. else
  333. {
  334. ret = _k230_i2c_write(i2c_dev);
  335. }
  336. if (ret != RT_EOK)
  337. {
  338. return -RT_EIO;
  339. }
  340. }
  341. return send_mesgs;
  342. }
  343. static rt_err_t k230_i2c_control(struct rt_i2c_bus_device *bus, int cmd, void *args)
  344. {
  345. struct k230_i2c_dev *i2c_dev = rt_container_of(bus, struct k230_i2c_dev, dev);
  346. rt_uint32_t arg = *(rt_uint32_t *)args;
  347. rt_err_t ret;
  348. RT_ASSERT(bus != RT_NULL);
  349. switch (cmd)
  350. {
  351. /* set 10-bit addr mode */
  352. case RT_I2C_DEV_CTRL_10BIT:
  353. if(arg & RT_I2C_ADDR_10BIT)
  354. {
  355. i2c_dev->dev.flags |= RT_I2C_ADDR_10BIT;
  356. }
  357. else
  358. {
  359. i2c_dev->dev.flags &= ~RT_I2C_ADDR_10BIT;
  360. }
  361. break;
  362. case RT_I2C_DEV_CTRL_TIMEOUT:
  363. k230_i2c_set_bus_timeout(i2c_dev, arg);
  364. break;
  365. case RT_I2C_DEV_CTRL_CLK:
  366. ret = k230_i2c_set_bus_speed(i2c_dev, arg);
  367. if (ret != RT_EOK)
  368. {
  369. return -RT_EIO;
  370. }
  371. break;
  372. default: break;
  373. }
  374. return RT_EOK;
  375. }
  376. static void k230_i2c_master_init(struct k230_i2c_dev *dev)
  377. {
  378. volatile i2c_t *i2c = (i2c_t *)dev->base;
  379. /* Disable i2c */
  380. k230_i2c_enable(dev, RT_FALSE);
  381. i2c->con.slave_disable = 1;
  382. i2c->con.restart_en = 1;
  383. i2c->con.master_mode = 1;
  384. i2c->tx_tl.tl = I2C_TX_TL;
  385. i2c->rx_tl.tl = I2C_RX_TL;
  386. i2c->intr_mask.m_stop_det = 1;
  387. /* Enable i2c */
  388. k230_i2c_enable(dev, RT_TRUE);
  389. }
  390. static const struct rt_i2c_bus_device_ops k230_i2c_ops =
  391. {
  392. .master_xfer = k230_i2c_xfer,
  393. .i2c_bus_control = k230_i2c_control,
  394. };
  395. static struct k230_i2c_dev k230_i2c_devs[] =
  396. {
  397. #ifdef BSP_USING_I2C0
  398. {
  399. .name = "i2c0",
  400. .base = I2C0_BASE_ADDR,
  401. .size = I2C0_IO_SIZE,
  402. .vector = K230_IRQ_I2C0,
  403. },
  404. #endif
  405. #ifdef BSP_USING_I2C1
  406. {
  407. .name = "i2c1",
  408. .base = I2C1_BASE_ADDR,
  409. .size = I2C1_IO_SIZE,
  410. .vector = K230_IRQ_I2C1,
  411. },
  412. #endif
  413. #ifdef BSP_USING_I2C2
  414. {
  415. .name = "i2c2",
  416. .base = I2C2_BASE_ADDR,
  417. .size = I2C2_IO_SIZE,
  418. .vector = K230_IRQ_I2C2,
  419. },
  420. #endif
  421. #ifdef BSP_USING_I2C3
  422. {
  423. .name = "i2c3",
  424. .base = I2C3_BASE_ADDR,
  425. .size = I2C3_IO_SIZE,
  426. .vector = K230_IRQ_I2C3,
  427. },
  428. #endif
  429. #ifdef BSP_USING_I2C4
  430. {
  431. .name = "i2c4",
  432. .base = I2C4_BASE_ADDR,
  433. .size = I2C4_IO_SIZE,
  434. .vector = K230_IRQ_I2C4,
  435. },
  436. #endif
  437. };
  438. int rt_hw_i2c_init(void)
  439. {
  440. int i;
  441. for (i = 0; i < sizeof(k230_i2c_devs) / sizeof(k230_i2c_devs[0]); i++)
  442. {
  443. k230_i2c_devs[i].base = (rt_ubase_t)rt_ioremap((void *)k230_i2c_devs[i].base, k230_i2c_devs[i].size);
  444. k230_i2c_devs[i].dev.ops = &k230_i2c_ops;
  445. k230_i2c_devs[i].clock = sysctl_clk_get_leaf_freq(SYSCTL_CLK_I2C0_CORE + i);
  446. k230_i2c_master_init(&k230_i2c_devs[i]);
  447. k230_i2c_set_bus_timeout(&k230_i2c_devs[i], I2C_DEFAULT_TIMEOUT);
  448. k230_i2c_set_bus_speed(&k230_i2c_devs[i], I2C_DEFAULT_SPEED);
  449. rt_i2c_bus_device_register(&k230_i2c_devs[i].dev, k230_i2c_devs[i].name);
  450. LOG_I("i2c%d master mode, i2c%d clock=%dHz\n", i, i, k230_i2c_devs[i].clock);
  451. }
  452. return RT_EOK;
  453. }
  454. INIT_DEVICE_EXPORT(rt_hw_i2c_init);