i2cmt_lark.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. /*
  2. * Copyright (c) 2017 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief I2CMT master driver for Actions SoC
  9. */
  10. //#define DT_DRV_COMPAT actions_acts_i2cmt
  11. #include <errno.h>
  12. #include <sys/__assert.h>
  13. #include <stdbool.h>
  14. #include <kernel.h>
  15. #include <device.h>
  16. #include <init.h>
  17. #include <drivers/ipmsg.h>
  18. #include <drivers/i2cmt.h>
  19. #include <rbuf/rbuf_msg_sc.h>
  20. #include <soc.h>
  21. #include <board_cfg.h>
  22. #include <linker/linker-defs.h>
  23. #define I2CMT_MAX_TASK_LEN (256)
  24. #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
  25. #include <logging/log.h>
  26. LOG_MODULE_REGISTER(i2cmt_acts);
  27. #define I2CMT_CLOCK (4000000)
  28. /**
  29. * @brief I2C Module (I2CMT)
  30. */
  31. typedef struct {
  32. volatile uint32_t CTL; /*!< (@ 0x00000000) TASK Control Register */
  33. volatile uint32_t DMA_CTL; /*!< (@ 0x00000004) TASK DMA Control Register */
  34. volatile uint32_t DMA_ADD; /*!< (@ 0x00000008) TASK DMA Address Register */
  35. volatile uint32_t DMA_CNT; /*!< (@ 0x0000000C) TASK DMA CNT Register */
  36. volatile uint32_t DMA_RC; /*!< (@ 0x00000010) TASK DMA remain counter Register */
  37. volatile uint32_t RESERVED[11];
  38. } I2CMT_AUTO_TASK_Type; /*!< Size = 64 (0x40) */
  39. typedef struct { /*!< (@ 0x40088000) I2CMT Structure */
  40. volatile uint32_t CTL; /*!< (@ 0x00000000) I2C Control Register */
  41. volatile uint32_t NML_STA; /*!< (@ 0x00000004) I2C Status Register */
  42. volatile uint32_t NML_DAT; /*!< (@ 0x00000008) I2C TX/RX DATA Register */
  43. volatile uint32_t AUTO_TASK_STAT; /*!< (@ 0x0000000C) Auto task status Register */
  44. volatile uint32_t AUTO_TASK_IE; /*!< (@ 0x00000010) Auto task IRQ enable Register */
  45. volatile uint32_t AUTO_TASK_IP; /*!< (@ 0x00000014) Auto task IRQ pending Register */
  46. volatile uint32_t RESERVED1[2];
  47. volatile uint32_t AUTO_TASK_CFG; /*!< (@ 0x00000020) Auto task CFG Register */
  48. volatile uint32_t RESERVED2[55];
  49. volatile I2CMT_AUTO_TASK_Type AUTO_TASK[4]; /*!< (@ 0x00000100) TASK[0..3] Group */
  50. volatile uint32_t RESERVED3[3968];
  51. } I2CMT_Type; /*!< Size = 512 (0x200) */
  52. typedef I2CMT_Type I2CMT_ARRAYType[1]; /*!< max. 2 instances available */
  53. #define I2CMT ((I2CMT_ARRAYType*) I2CMT0_REG_BASE)
  54. /* ========================================================== CTL ========================================================== */
  55. #define I2CMT_CTL_CLKDIV_Msk (0xf80UL) /*!< CLKDIV (Bitfield-Mask: 0x1f) */
  56. #define I2CMT_CTL_MODSEL_Msk (0x40UL) /*!< MODSEL (Bitfield-Mask: 0x01) */
  57. #define I2CMT_CTL_EN_Msk (0x20UL) /*!< EN (Bitfield-Mask: 0x01) */
  58. #define I2CMT_CTL_IRQE_Msk (0x10UL) /*!< IRQE (Bitfield-Mask: 0x01) */
  59. #define I2CMT_CTL_GBCC_Msk (0xcUL) /*!< GBCC (Bitfield-Mask: 0x03) */
  60. #define I2CMT_CTL_RB_Msk (0x2UL) /*!< RB (Bitfield-Mask: 0x01) */
  61. #define I2CMT_CTL_GACK_Msk (0x1UL) /*!< GACK (Bitfield-Mask: 0x01) */
  62. #define I2CMT_CTL_CLKDIV_Pos (7UL) /*!< CLKDIV (Bit 7) */
  63. #define I2CMT_CTL_MODSEL_Pos (6UL) /*!< MODSEL (Bit 6) */
  64. #define I2CMT_CTL_EN_Pos (5UL) /*!< EN (Bit 5) */
  65. #define I2CMT_CTL_IRQE_Pos (4UL) /*!< IRQE (Bit 4) */
  66. #define I2CMT_CTL_GBCC_Pos (2UL) /*!< GBCC (Bit 2) */
  67. #define I2CMT_CTL_RB_Pos (1UL) /*!< RB (Bit 1) */
  68. #define I2CMT_CTL_GACK_Pos (0UL) /*!< GACK (Bit 0) */
  69. /* ======================================================== NML_STA ======================================================== */
  70. #define I2CMT_NML_STA_TCB_Msk (0x100UL) /*!< TCB (Bitfield-Mask: 0x01) */
  71. #define I2CMT_NML_STA_STPD_Msk (0x80UL) /*!< STPD (Bitfield-Mask: 0x01) */
  72. #define I2CMT_NML_STA_STAD_Msk (0x40UL) /*!< STAD (Bitfield-Mask: 0x01) */
  73. #define I2CMT_NML_STA_RWST_Msk (0x20UL) /*!< RWST (Bitfield-Mask: 0x01) */
  74. #define I2CMT_NML_STA_LBST_Msk (0x10UL) /*!< LBST (Bitfield-Mask: 0x01) */
  75. #define I2CMT_NML_STA_IRQP_Msk (0x8UL) /*!< IRQP (Bitfield-Mask: 0x01) */
  76. #define I2CMT_NML_STA_BBB_Msk (0x4UL) /*!< BBB (Bitfield-Mask: 0x01) */
  77. #define I2CMT_NML_STA_BEB_Msk (0x2UL) /*!< BEB (Bitfield-Mask: 0x01) */
  78. #define I2CMT_NML_STA_RACK_Msk (0x1UL) /*!< RACK (Bitfield-Mask: 0x01) */
  79. /* ===================================================== AUTO_TASK_IE ====================================================== */
  80. #define I2CMT_AUTO_TASK_IE_TSK0BERIE_Pos (12UL) /*!< TSK0BERIE (Bit 12) */
  81. #define I2CMT_AUTO_TASK_IE_TSK0NAKIE_Pos (8UL) /*!< TSK0NAKIE (Bit 8) */
  82. #define I2CMT_AUTO_TASK_IE_TSK0HFIE_Pos (4UL) /*!< TSK0HFIE (Bit 4) */
  83. #define I2CMT_AUTO_TASK_IE_TSK0TCIE_Pos (0UL) /*!< TSK0TCIE (Bit 0) */
  84. /* ===================================================== AUTO_TASK_IP ====================================================== */
  85. #define I2CMT_AUTO_TASK_IP_TSK0BERIP_Pos (12UL) /*!< TSK0BERIP (Bit 12) */
  86. #define I2CMT_AUTO_TASK_IP_TSK0NAKIP_Pos (8UL) /*!< TSK0NAKIP (Bit 8) */
  87. #define I2CMT_AUTO_TASK_IP_TSK0HFIP_Pos (4UL) /*!< TSK0HFIP (Bit 4) */
  88. #define I2CMT_AUTO_TASK_IP_TSK0TCIP_Pos (0UL) /*!< TSK0TCIP (Bit 0) */
  89. /* ========================================================== CTL ========================================================== */
  90. #define I2CMT_AUTO_TASK_CTL_SOFT_ST_Msk (0x80000000UL) /*!< SOFT_ST (Bitfield-Mask: 0x01) */
  91. /* ======================================================== DMA_CTL ======================================================== */
  92. #define I2CMT_AUTO_TASK_DMA_CTL_DMARELD_Pos (1UL) /*!< DMARELD (Bit 1) */
  93. #define I2CMT_AUTO_TASK_DMA_CTL_DMASTART_Msk (0x1UL) /*!< DMASTART (Bitfield-Mask: 0x01) */
  94. // I2C BUS STAT
  95. #define MASK (I2CMT_CTL_GBCC_Msk | I2CMT_CTL_RB_Msk | I2CMT_CTL_GACK_Msk)
  96. #define START (1 << I2CMT_CTL_GBCC_Pos)
  97. #define STOP (2 << I2CMT_CTL_GBCC_Pos)
  98. #define RESTA (3 << I2CMT_CTL_GBCC_Pos)
  99. #define REBUS I2CMT_CTL_RB_Msk
  100. #define ACK 0
  101. #define NACK I2CMT_CTL_GACK_Msk
  102. enum i2cmt_state {
  103. STATE_OK = 0,
  104. STATE_ERR,
  105. };
  106. struct acts_i2cmt_config {
  107. uint32_t ctl_reg;
  108. uint32_t clk_freq;
  109. uint8_t bus_id;
  110. uint8_t clock_id;
  111. uint8_t reset_id;
  112. void (*irq_config_func)(void);
  113. };
  114. /* Device run time data */
  115. struct acts_i2cmt_data {
  116. struct k_mutex mutex;
  117. struct k_sem complete_sem;
  118. enum i2cmt_state state;
  119. uint8_t suspended;
  120. uint8_t soft_started;
  121. /* task data */
  122. i2c_task_callback_t task_cb[I2C_TASK_NUM];
  123. void *task_cb_ctx[I2C_TASK_NUM];
  124. i2c_task_t *task_attr[I2C_TASK_NUM];
  125. uint8_t *task_buf[I2C_TASK_NUM];
  126. uint32_t task_len[I2C_TASK_NUM];
  127. };
  128. #define DEV_NAME(dev) ((dev)->name)
  129. #define DEV_CFG(dev) \
  130. ((const struct acts_i2cmt_config *const)(dev)->config)
  131. #define DEV_DATA(dev) \
  132. ((struct acts_i2cmt_data *const)(dev)->data)
  133. static void i2cmt_set_rate(int i2c_dev, int rate)
  134. {
  135. unsigned int val, div;
  136. /* RC4M clock src and div=1 */
  137. val = (0 << 8) | (0 << 0);
  138. sys_write32(val, CMU_I2CMT0CLK + i2c_dev * 4);
  139. div = (I2CMT_CLOCK + rate * 2 - 1) / (rate * 2);
  140. I2CMT[i2c_dev]->CTL &= ~I2CMT_CTL_CLKDIV_Msk;
  141. I2CMT[i2c_dev]->CTL |= div << I2CMT_CTL_CLKDIV_Pos;
  142. }
  143. // switch to auto mode
  144. static void i2cmt_auto_mode_set(int i2c_dev)
  145. {
  146. /* clear task IRQ pending */
  147. I2CMT[i2c_dev]->AUTO_TASK_IP = I2CMT[i2c_dev]->AUTO_TASK_IP;
  148. /* set auto mode */
  149. I2CMT[i2c_dev]->CTL |= I2CMT_CTL_MODSEL_Msk;
  150. }
  151. // configure i2c task
  152. static void i2cmt_auto_task_config(int i2c_dev, int task_id, i2c_task_t *task_attr, uint32_t addr)
  153. {
  154. uint8_t *pdata = (uint8_t *)&task_attr->ctl;
  155. volatile uint32_t ctl = *(volatile unsigned int*)pdata;
  156. /* config task dma first */
  157. I2CMT[i2c_dev]->AUTO_TASK[task_id].DMA_ADD = addr;//task_attr->dma.addr;
  158. I2CMT[i2c_dev]->AUTO_TASK[task_id].DMA_CNT = task_attr->dma.len;
  159. if (task_attr->dma.len > 0) {
  160. I2CMT[i2c_dev]->AUTO_TASK[task_id].DMA_CTL = I2CMT_AUTO_TASK_DMA_CTL_DMASTART_Msk
  161. | (task_attr->dma.reload << I2CMT_AUTO_TASK_DMA_CTL_DMARELD_Pos);
  162. }
  163. if(task_attr->irq_type & I2C_TASK_IRQ_CMPLT) {
  164. /* enable task DMA transmission complete IRQ */
  165. I2CMT[i2c_dev]->AUTO_TASK_IE |= 1 << (I2CMT_AUTO_TASK_IE_TSK0TCIE_Pos + task_id);
  166. } else {
  167. /* disable task DMA transmission complete IRQ */
  168. I2CMT[i2c_dev]->AUTO_TASK_IE &= ~(1 << (I2CMT_AUTO_TASK_IE_TSK0TCIE_Pos + task_id));
  169. }
  170. if(task_attr->irq_type & I2C_TASK_IRQ_HALF_CMPLT) {
  171. /* enable task DMA Half transmission complete IRQ */
  172. I2CMT[i2c_dev]->AUTO_TASK_IE |= 1 << (I2CMT_AUTO_TASK_IE_TSK0HFIE_Pos + task_id);
  173. } else {
  174. /* disable task DMA Half transmission complete IRQ */
  175. I2CMT[i2c_dev]->AUTO_TASK_IE &= ~(1 << (I2CMT_AUTO_TASK_IE_TSK0HFIE_Pos + task_id));
  176. }
  177. if(task_attr->irq_type & I2C_TASK_IRQ_NACK) {
  178. /* enable task DMA receive NACK IRQ */
  179. I2CMT[i2c_dev]->AUTO_TASK_IE |= 1 << (I2CMT_AUTO_TASK_IE_TSK0NAKIE_Pos + task_id);
  180. } else {
  181. /* disable task DMA receive NACK IRQ */
  182. I2CMT[i2c_dev]->AUTO_TASK_IE &= ~(1 << (I2CMT_AUTO_TASK_IE_TSK0NAKIE_Pos + task_id));
  183. }
  184. if(task_attr->irq_type & I2C_TASK_IRQ_BUS_ERROR) {
  185. /* enable task DMA bus error IRQ */
  186. I2CMT[i2c_dev]->AUTO_TASK_IE |= 1 << (I2CMT_AUTO_TASK_IE_TSK0BERIE_Pos + task_id);
  187. } else {
  188. /* disable task DMA bus error IRQ */
  189. I2CMT[i2c_dev]->AUTO_TASK_IE &= ~(1 << (I2CMT_AUTO_TASK_IE_TSK0BERIE_Pos + task_id));
  190. }
  191. /* config task ctl*/
  192. I2CMT[i2c_dev]->AUTO_TASK[task_id].CTL = (ctl & ~I2CMT_AUTO_TASK_CTL_SOFT_ST_Msk);
  193. }
  194. // configure i2c stop
  195. static void i2cmt_auto_task_stop_en(int i2c_dev, int task_id, int en)
  196. {
  197. if (en) {
  198. I2CMT[i2c_dev]->AUTO_TASK_CFG &= ~(1 << task_id);
  199. } else {
  200. I2CMT[i2c_dev]->AUTO_TASK_CFG |= (1 << task_id);
  201. }
  202. }
  203. // force trigger i2c task by software if don't use externtal trigger sources
  204. static void i2cmt_auto_task_soft_start(int i2c_dev, int task_id)
  205. {
  206. /* trigger task by software */
  207. I2CMT[i2c_dev]->AUTO_TASK[task_id].CTL &= ~I2CMT_AUTO_TASK_CTL_SOFT_ST_Msk;
  208. I2CMT[i2c_dev]->AUTO_TASK[task_id].CTL |= I2CMT_AUTO_TASK_CTL_SOFT_ST_Msk;
  209. }
  210. // force trigger i2c task by software if don't use externtal trigger sources
  211. static void i2cmt_auto_task_soft_stop(int i2c_dev, int task_id)
  212. {
  213. /* stop dma */
  214. I2CMT[i2c_dev]->AUTO_TASK[task_id].DMA_CTL = 0;
  215. /* trigger task by software */
  216. I2CMT[i2c_dev]->AUTO_TASK[task_id].CTL &= ~I2CMT_AUTO_TASK_CTL_SOFT_ST_Msk;
  217. }
  218. //get the irq pending
  219. static __sleepfunc int i2cmt_auto_task_irq_get_pending(int i2c_dev)
  220. {
  221. return I2CMT[i2c_dev]->AUTO_TASK_IP & I2CMT[i2c_dev]->AUTO_TASK_IE;
  222. }
  223. static __sleepfunc int i2cmt_auto_task_irq_mask(int task_id, int task_irq_type)
  224. {
  225. int irq_pending_mask = 0;
  226. switch (task_irq_type) {
  227. case I2C_TASK_IRQ_CMPLT:
  228. irq_pending_mask = 1 << (I2CMT_AUTO_TASK_IP_TSK0TCIP_Pos + task_id);
  229. break;
  230. case I2C_TASK_IRQ_HALF_CMPLT:
  231. irq_pending_mask = 1 << (I2CMT_AUTO_TASK_IP_TSK0HFIP_Pos + task_id);
  232. break;
  233. case I2C_TASK_IRQ_NACK:
  234. irq_pending_mask = 1 << (I2CMT_AUTO_TASK_IP_TSK0NAKIP_Pos + task_id);
  235. break;
  236. case I2C_TASK_IRQ_BUS_ERROR:
  237. irq_pending_mask = 1 << (I2CMT_AUTO_TASK_IP_TSK0BERIP_Pos + task_id);
  238. break;
  239. default:
  240. break;
  241. }
  242. return irq_pending_mask;
  243. }
  244. //check if the irq is pending
  245. //static __sleepfunc int i2cmt_auto_task_irq_is_pending(int i2c_dev, int task_id, int task_irq_type)
  246. //{
  247. // return I2CMT[i2c_dev]->AUTO_TASK_IP & i2cmt_auto_task_irq_mask(task_id, task_irq_type);
  248. //}
  249. //clear task irq pending
  250. static __sleepfunc void i2cmt_auto_task_irq_clr_pending(int i2c_dev, int task_id, int task_irq_type)
  251. {
  252. I2CMT[i2c_dev]->AUTO_TASK_IP = i2cmt_auto_task_irq_mask(task_id, task_irq_type);
  253. }
  254. static void i2cmt_acts_register_callback(struct device *dev, int task_id,
  255. i2c_task_callback_t cb, void *context)
  256. {
  257. struct acts_i2cmt_data *data = DEV_DATA(dev);
  258. data->task_cb[task_id] = cb;
  259. data->task_cb_ctx[task_id] = context;
  260. }
  261. static uint8_t* i2cmt_task_buf_start(struct acts_i2cmt_data *data,
  262. int task_id, uint32_t addr, uint16_t len, uint8_t rd)
  263. {
  264. rbuf_t *rbuf;
  265. uint8_t *sbuf;
  266. uint16_t slen;
  267. /* check task len */
  268. if ((len == 0) || (len > I2CMT_MAX_TASK_LEN)) {
  269. LOG_ERR("task[%d] length %d error!", task_id, len);
  270. return NULL;
  271. }
  272. /* get task buf */
  273. sbuf = data->task_buf[task_id];
  274. /* check task buf len */
  275. if ((sbuf != NULL) && (len > data->task_len[task_id])) {
  276. /* free task buf */
  277. rbuf = RBUF_FR_BUF(sbuf);
  278. RB_MSG_FREE(rbuf);
  279. sbuf = NULL;
  280. data->task_buf[task_id] = NULL;
  281. data->task_len[task_id] = 0;
  282. }
  283. /* alloc task buf */
  284. if (sbuf == NULL) {
  285. if (task_id == I2C_TASK_NUM - 1) {
  286. slen = I2CMT_MAX_TASK_LEN;
  287. } else {
  288. slen = (len < 16) ? 16 : len;
  289. }
  290. rbuf = RB_MSG_ALLOC(slen);
  291. if (rbuf != NULL) {
  292. sbuf = (uint8_t*)RBUF_TO_BUF(rbuf);
  293. data->task_buf[task_id] = sbuf;
  294. data->task_len[task_id] = slen;
  295. } else {
  296. LOG_ERR("task[%d] malloc(%d) error!", task_id, len);
  297. }
  298. }
  299. /* copy buf before writing */
  300. if (!rd && (addr != 0) && sbuf) {
  301. memcpy(sbuf, (void*)addr, len);
  302. }
  303. return sbuf;
  304. }
  305. static uint8_t* i2cmt_task_buf_stop(struct acts_i2cmt_data *data,
  306. int task_id, uint32_t addr, uint32_t len, uint8_t rd)
  307. {
  308. uint8_t *sbuf;
  309. sbuf = data->task_buf[task_id];
  310. /* copy buf after reading */
  311. if (rd && (addr != 0) && sbuf) {
  312. memcpy((void*)addr, sbuf, len);
  313. }
  314. return sbuf;
  315. }
  316. static int i2cmt_acts_task_start(struct device *dev, int task_id,
  317. const i2c_task_t *attr)
  318. {
  319. const struct acts_i2cmt_config *cfg =DEV_CFG(dev);
  320. struct acts_i2cmt_data *data = DEV_DATA(dev);
  321. uint8_t *buf;
  322. /* start dma buffer */
  323. buf = i2cmt_task_buf_start(data, task_id, attr->dma.addr, attr->dma.len, attr->ctl.rwsel);
  324. if (buf == NULL) {
  325. return -1;
  326. }
  327. /* save attr */
  328. data->task_attr[task_id] = (i2c_task_t*)attr;
  329. /* select i2c auto mode */
  330. i2cmt_auto_mode_set(cfg->bus_id);
  331. /* config i2c task */
  332. i2cmt_auto_task_config(cfg->bus_id, task_id, (i2c_task_t*)attr, (uint32_t)buf);
  333. /* config ppi */
  334. if (!attr->ctl.soft) {
  335. /* disable ppi trigger */
  336. ppi_trig_src_en(attr->trig.trig, 0);
  337. /* clear ppi pending */
  338. ppi_trig_src_clr_pending(attr->trig.trig);
  339. /* config ppi trigger */
  340. ppi_task_trig_config(attr->trig.chan, attr->trig.task, attr->trig.trig);
  341. /* enable ppi trigger */
  342. ppi_trig_src_en(attr->trig.trig, attr->trig.en);
  343. } else {
  344. /* soft trigger */
  345. data->soft_started = 1;
  346. i2cmt_auto_task_soft_start(cfg->bus_id, task_id);
  347. }
  348. return 0;
  349. }
  350. static int i2cmt_acts_task_stop(struct device *dev, int task_id)
  351. {
  352. const struct acts_i2cmt_config *cfg =DEV_CFG(dev);
  353. struct acts_i2cmt_data *data = DEV_DATA(dev);
  354. const i2c_task_t *attr = data->task_attr[task_id];
  355. /* check attr */
  356. if (attr == NULL) {
  357. return 0;
  358. }
  359. /* disable ppi trigger */
  360. if ((attr != NULL) && (!attr->ctl.soft)) {
  361. ppi_trig_src_en(attr->trig.trig, 0);
  362. } else {
  363. i2cmt_auto_task_soft_stop(cfg->bus_id, task_id);
  364. data->soft_started = 0;
  365. }
  366. /* stop dma buffer */
  367. i2cmt_task_buf_stop(data, task_id, attr->dma.addr, attr->dma.len, attr->ctl.rwsel);
  368. /* clear attr */
  369. data->task_attr[task_id] = NULL;
  370. return 0;
  371. }
  372. static int i2cmt_acts_ctl_reset(const struct device *dev)
  373. {
  374. const struct acts_i2cmt_config *cfg = DEV_CFG(dev);
  375. // reset i2cmt
  376. acts_reset_peripheral(cfg->reset_id);
  377. /* enable i2c */
  378. I2CMT[cfg->bus_id]->CTL |= I2CMT_CTL_EN_Msk;
  379. return 0;
  380. }
  381. #if IS_ENABLED(CONFIG_I2CMT_0) || IS_ENABLED(CONFIG_I2CMT_1)
  382. static const unsigned short i2c_irq_list[4] = {
  383. I2C_TASK_IRQ_CMPLT,
  384. I2C_TASK_IRQ_HALF_CMPLT,
  385. I2C_TASK_IRQ_NACK,
  386. I2C_TASK_IRQ_BUS_ERROR,
  387. };
  388. static void i2cmt_acts_isr(struct device *dev)
  389. {
  390. const struct acts_i2cmt_config *cfg = DEV_CFG(dev);;
  391. struct acts_i2cmt_data *data = DEV_DATA(dev);
  392. int task_id, irq_type, len;
  393. int pending = i2cmt_auto_task_irq_get_pending(cfg->bus_id);
  394. int pos = find_msb_set(pending) - 1;
  395. i2c_task_callback_t cb;
  396. const i2c_task_t *attr;
  397. uint8_t *buf;
  398. void *ctx;
  399. while (pos >= 0) {
  400. task_id = (pos % 4);
  401. irq_type = i2c_irq_list[pos / 4];
  402. attr = data->task_attr[task_id];
  403. /* clear task pending */
  404. i2cmt_auto_task_irq_clr_pending(cfg->bus_id, task_id, irq_type);
  405. /* clear ppi pending */
  406. ppi_trig_src_clr_pending(SPIMT0_TASK0_CIP + attr->trig.task);
  407. if (!attr->ctl.soft) {
  408. ppi_trig_src_clr_pending(attr->trig.trig);
  409. if (attr->trig.trig <= TIMER4) {
  410. //timer_clear_pd(attr->trig.trig);
  411. }
  412. }
  413. /* call handler */
  414. cb = data->task_cb[task_id];
  415. if (cb != NULL) {
  416. /* get buffer */
  417. ctx = data->task_cb_ctx[task_id];
  418. buf = data->task_buf[task_id];
  419. len = attr->dma.len / 2;
  420. switch(irq_type) {
  421. case I2C_TASK_IRQ_CMPLT:
  422. buf += len;
  423. break;
  424. case I2C_TASK_IRQ_HALF_CMPLT:
  425. break;
  426. case I2C_TASK_IRQ_NACK:
  427. case I2C_TASK_IRQ_BUS_ERROR:
  428. buf = NULL;
  429. break;
  430. }
  431. cb(buf, len, ctx);
  432. }
  433. /* find msb */
  434. pending = i2cmt_auto_task_irq_get_pending(cfg->bus_id);
  435. pos = find_msb_set(pending) - 1;
  436. }
  437. }
  438. #endif
  439. __sleepfunc uint8_t* i2c_task_get_data(int bus_id, int task_id, int trig, int *plen)
  440. {
  441. int len = 0;
  442. uint8_t *buf = NULL;
  443. int pending = i2cmt_auto_task_irq_get_pending(bus_id);
  444. /* clear task pending */
  445. if (pending & i2cmt_auto_task_irq_mask(task_id, I2C_TASK_IRQ_HALF_CMPLT)) {
  446. i2cmt_auto_task_irq_clr_pending(bus_id, task_id, I2C_TASK_IRQ_HALF_CMPLT);
  447. len = I2CMT[bus_id]->AUTO_TASK[task_id].DMA_CNT / 2;
  448. buf = (uint8_t *)I2CMT[bus_id]->AUTO_TASK[task_id].DMA_ADD;
  449. } else if (pending & i2cmt_auto_task_irq_mask(task_id, I2C_TASK_IRQ_CMPLT)) {
  450. i2cmt_auto_task_irq_clr_pending(bus_id, task_id, I2C_TASK_IRQ_CMPLT);
  451. len = I2CMT[bus_id]->AUTO_TASK[task_id].DMA_CNT / 2;
  452. buf = (uint8_t *)I2CMT[bus_id]->AUTO_TASK[task_id].DMA_ADD + len;
  453. }
  454. /* clear ppi pending */
  455. if (buf) {
  456. ppi_trig_src_clr_pending(I2CMT0_TASK0_CIP+task_id);
  457. if (trig >= 0) {
  458. ppi_trig_src_clr_pending(trig);
  459. }
  460. }
  461. if (plen) {
  462. *plen = len;
  463. }
  464. return buf;
  465. }
  466. static uint32_t i2cmt_get_timeout(const struct device *dev, int len)
  467. {
  468. const struct acts_i2cmt_config *cfg = DEV_CFG(dev);
  469. /* > 50ms */
  470. return ((len << 15) / cfg->clk_freq + 50);
  471. }
  472. static void i2cmt_xfer_callback(unsigned char *buf, int len, void *ctx)
  473. {
  474. struct acts_i2cmt_data *data = DEV_DATA((const struct device *)ctx);
  475. // save status
  476. data->state = (buf != NULL) ? STATE_OK : STATE_ERR;
  477. // complete xfer
  478. k_sem_give(&data->complete_sem);
  479. }
  480. static int i2cmt_xfer_task(struct device *dev, uint32_t task_id, i2c_task_t *task)
  481. {
  482. int ret;
  483. uint32_t pre_time, cur_time;
  484. uint32_t timeout_ms = i2cmt_get_timeout(dev, task->dma.len + 3);
  485. const struct acts_i2cmt_config *cfg = DEV_CFG(dev);
  486. struct acts_i2cmt_data *data = DEV_DATA(dev);
  487. /* reset sem */
  488. if (!data->suspended) {
  489. k_sem_reset(&data->complete_sem);
  490. }
  491. /* start task */
  492. i2cmt_acts_register_callback(dev, task_id, i2cmt_xfer_callback, (void*)dev);
  493. ret = i2cmt_acts_task_start(dev, task_id, task);
  494. if(ret) {
  495. return -1;
  496. }
  497. /* wait task */
  498. if (data->suspended) {
  499. pre_time = (uint32_t)soc_sys_uptime_get();
  500. while(!i2c_task_get_data(cfg->bus_id, task_id, -1, NULL)) {
  501. cur_time = (uint32_t)soc_sys_uptime_get();
  502. // timeout
  503. if ((cur_time - pre_time) > timeout_ms) {
  504. data->state = STATE_ERR;
  505. break;
  506. }
  507. }
  508. } else {
  509. ret = k_sem_take(&data->complete_sem, K_MSEC(timeout_ms));
  510. if (ret) {
  511. data->state = STATE_ERR;
  512. LOG_ERR("i2cmt[%d] timeout(%d ms)", cfg->bus_id, timeout_ms);
  513. }
  514. }
  515. /* stop task */
  516. i2cmt_acts_task_stop(dev, task_id);
  517. i2cmt_acts_register_callback(dev, task_id, NULL, NULL);
  518. return data->state;
  519. }
  520. static int i2cmt_acts_configure(const struct device *dev, uint32_t config)
  521. {
  522. LOG_ERR("Change I2CMT clock is not supported");
  523. return 0;
  524. }
  525. static int i2cmt_acts_transfer(const struct device *dev, struct i2c_msg *msgs,
  526. uint8_t num_msgs, uint16_t addr)
  527. {
  528. const struct acts_i2cmt_config *cfg = DEV_CFG(dev);
  529. struct acts_i2cmt_data *data = DEV_DATA(dev);
  530. int ret = 0, i;
  531. i2c_task_t i2c_task = {0};
  532. if (!data->suspended) {
  533. k_mutex_lock(&data->mutex, K_FOREVER);
  534. }
  535. for (i = 0; i < num_msgs; i ++) {
  536. /* config task */
  537. i2c_task.irq_type = I2C_TASK_IRQ_CMPLT | I2C_TASK_IRQ_NACK;
  538. i2c_task.ctl.rwsel = ((msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_READ);
  539. i2c_task.ctl.sdevaddr = addr;
  540. i2c_task.ctl.rdlen_wsdat = msgs[i].len;
  541. i2c_task.ctl.tdataddr = 1,
  542. i2c_task.ctl.soft = 1;
  543. i2c_task.dma.reload = 0;
  544. i2c_task.dma.addr = (uint32_t)msgs[i].buf;
  545. i2c_task.dma.len = msgs[i].len;
  546. /* config stop */
  547. i2cmt_auto_task_stop_en(cfg->bus_id, I2C_TASK_NUM - 1, (msgs[i].flags & I2C_MSG_STOP));
  548. /* xfer task */
  549. ret = i2cmt_xfer_task((struct device *)dev, I2C_TASK_NUM - 1, &i2c_task);
  550. if (ret != STATE_OK) {
  551. break;
  552. }
  553. }
  554. if (!data->suspended) {
  555. k_mutex_unlock(&data->mutex);
  556. }
  557. return (ret != STATE_OK);
  558. }
  559. #ifdef CONFIG_PM_DEVICE
  560. int i2cmt_pm_control(const struct device *dev, enum pm_device_action action)
  561. {
  562. struct acts_i2cmt_data *data = DEV_DATA(dev);
  563. switch (action) {
  564. case PM_DEVICE_ACTION_RESUME:
  565. data->suspended = 0;
  566. break;
  567. case PM_DEVICE_ACTION_SUSPEND:
  568. if((data->mutex.lock_count != 0U) || data->soft_started) {
  569. LOG_ERR("i2cmt busy, cannot suspend");
  570. return -1;
  571. }
  572. data->suspended = 1;
  573. break;
  574. default:
  575. return 0;
  576. }
  577. return 0;
  578. }
  579. #else
  580. #define i2cmt_pm_control NULL
  581. #endif
  582. int i2cmt_acts_init(const struct device *dev)
  583. {
  584. const struct acts_i2cmt_config *cfg = DEV_CFG(dev);;
  585. struct acts_i2cmt_data *data = DEV_DATA(dev);
  586. // enable clock
  587. acts_clock_peripheral_enable(cfg->clock_id);
  588. // reset i2cmt
  589. i2cmt_acts_ctl_reset(dev);
  590. // set clock
  591. i2cmt_set_rate(cfg->bus_id, cfg->clk_freq);
  592. /* irq init */
  593. cfg->irq_config_func();
  594. /* data init */
  595. k_mutex_init(&data->mutex);
  596. k_sem_init(&data->complete_sem, 0, UINT_MAX);
  597. data->state = STATE_OK;
  598. data->suspended = 0;
  599. data->soft_started = 0;
  600. return 0;
  601. }
  602. const struct i2cmt_driver_api i2cmt_acts_driver_api = {
  603. .i2c_api = {
  604. .configure = i2cmt_acts_configure,
  605. .transfer = i2cmt_acts_transfer,
  606. },
  607. .register_callback = i2cmt_acts_register_callback,
  608. .task_start = i2cmt_acts_task_start,
  609. .task_stop = i2cmt_acts_task_stop,
  610. .ctl_reset = i2cmt_acts_ctl_reset,
  611. };
  612. #define I2CMT_ACTS_DEFINE_CONFIG(n) \
  613. static const struct device DEVICE_NAME_GET(i2cmt##n##_acts); \
  614. \
  615. static void i2cmt##n##_acts_irq_config(void) \
  616. { \
  617. IRQ_CONNECT(IRQ_ID_IIC##n##MT, CONFIG_I2CMT_##n##_IRQ_PRI, \
  618. i2cmt_acts_isr, \
  619. DEVICE_GET(i2cmt##n##_acts), 0); \
  620. irq_enable(IRQ_ID_IIC##n##MT); \
  621. } \
  622. static const struct acts_i2cmt_config i2cmt##n##_acts_config = { \
  623. .ctl_reg = I2CMT##n##_REG_BASE,\
  624. .clk_freq = CONFIG_I2CMT_##n##_CLK_FREQ, \
  625. .bus_id = n,\
  626. .clock_id = CLOCK_ID_I2CMT##n,\
  627. .reset_id = RESET_ID_I2CMT##n,\
  628. .irq_config_func = i2cmt##n##_acts_irq_config, \
  629. }
  630. #define I2CMT_ACTS_DEFINE_DATA(n) \
  631. static __act_s2_sleep_data struct acts_i2cmt_data i2cmt##n##_acts_dev_data;
  632. #define I2CMT_ACTS_DEVICE_INIT(n) \
  633. I2CMT_ACTS_DEFINE_CONFIG(n); \
  634. I2CMT_ACTS_DEFINE_DATA(n); \
  635. DEVICE_DEFINE(i2cmt##n##_acts, \
  636. CONFIG_I2CMT_##n##_NAME, \
  637. i2cmt_acts_init, i2cmt_pm_control, &i2cmt##n##_acts_dev_data, \
  638. &i2cmt##n##_acts_config, POST_KERNEL, \
  639. CONFIG_I2C_INIT_PRIORITY, &i2cmt_acts_driver_api);
  640. #if IS_ENABLED(CONFIG_I2CMT_0)
  641. I2CMT_ACTS_DEVICE_INIT(0)
  642. #endif
  643. #if IS_ENABLED(CONFIG_I2CMT_1)
  644. I2CMT_ACTS_DEVICE_INIT(1)
  645. #endif