drv_i2c.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Email: opensource_embedded@phytium.com.cn
  7. *
  8. * Change Logs:
  9. * Date Author Notes
  10. * 2023-10-23 zhangyan first version
  11. *
  12. */
  13. #include "rtconfig.h"
  14. #if defined BSP_USING_I2C
  15. #define LOG_TAG "i2c_drv"
  16. #include "drv_log.h"
  17. #include "drv_i2c.h"
  18. #include "fi2c.h"
  19. #include "fi2c_hw.h"
  20. #include "fio_mux.h"
  21. #include "fmio_hw.h"
  22. #include "fmio.h"
  23. #include "drivers/i2c.h"
  24. #include "fparameters.h"
  25. #ifdef RT_USING_SMART
  26. #include <ioremap.h>
  27. #endif
  28. #define FI2C_DEFAULT_ID 0
  29. #define I2C_USE_MIO
  30. #if defined(I2C_USE_MIO)
  31. static FMioCtrl mio_handle;
  32. #endif
  33. struct phytium_i2c_bus
  34. {
  35. struct rt_i2c_bus_device device;
  36. FI2c i2c_handle;
  37. struct rt_i2c_msg *msg;
  38. const char *name;
  39. };
  40. #if defined(I2C_USE_CONTROLLER)
  41. static struct phytium_i2c_bus i2c_bus[FI2C_NUM] =
  42. {
  43. {
  44. .name = "I2C0",
  45. .i2c_handle.config.instance_id = 0,
  46. },
  47. {
  48. .name = "I2C1",
  49. .i2c_handle.config.instance_id = 1,
  50. },
  51. {
  52. .name = "I2C2",
  53. .i2c_handle.config.instance_id = 2,
  54. },
  55. };
  56. #endif
  57. #if defined(I2C_USE_MIO)
  58. static struct phytium_i2c_bus i2c_mio_bus[FMIO_NUM] =
  59. {
  60. #if defined(TARGET_E2000D) ||defined(TARGET_E2000Q)
  61. {
  62. .name = "MIO0",
  63. .i2c_handle.config.instance_id = 0,
  64. },
  65. {
  66. .name = "MIO1",
  67. .i2c_handle.config.instance_id = 1,
  68. },
  69. {
  70. .name = "MIO2",
  71. .i2c_handle.config.instance_id = 2,
  72. },
  73. {
  74. .name = "MIO3",
  75. .i2c_handle.config.instance_id = 3,
  76. },
  77. {
  78. .name = "MIO4",
  79. .i2c_handle.config.instance_id = 4,
  80. },
  81. {
  82. .name = "MIO5",
  83. .i2c_handle.config.instance_id = 5,
  84. },
  85. {
  86. .name = "MIO6",
  87. .i2c_handle.config.instance_id = 6,
  88. },
  89. {
  90. .name = "MIO7",
  91. .i2c_handle.config.instance_id = 7,
  92. },
  93. {
  94. .name = "MIO8",
  95. .i2c_handle.config.instance_id = 8,
  96. },
  97. {
  98. .name = "MIO9",
  99. .i2c_handle.config.instance_id = 9,
  100. },
  101. {
  102. .name = "MIO10",
  103. .i2c_handle.config.instance_id = 10,
  104. },
  105. {
  106. .name = "MIO11",
  107. .i2c_handle.config.instance_id = 11,
  108. },
  109. {
  110. .name = "MIO12",
  111. .i2c_handle.config.instance_id = 12,
  112. },
  113. {
  114. .name = "MIO13",
  115. .i2c_handle.config.instance_id = 13,
  116. },
  117. {
  118. .name = "MIO14",
  119. .i2c_handle.config.instance_id = 14,
  120. },
  121. {
  122. .name = "MIO15",
  123. .i2c_handle.config.instance_id = 15,
  124. },
  125. #elif defined(TARGET_PHYTIUMPI)
  126. {
  127. .name = "MIO0",
  128. .i2c_handle.config.instance_id = 0,
  129. },
  130. {
  131. .name = "MIO1",
  132. .i2c_handle.config.instance_id = 1,
  133. },
  134. {
  135. .name = "MIO2",
  136. .i2c_handle.config.instance_id = 2,
  137. },
  138. {
  139. .name = "MIO10",
  140. .i2c_handle.config.instance_id = 10,
  141. },
  142. #endif
  143. };
  144. #endif
  145. #if defined(I2C_USE_CONTROLLER)
  146. static rt_err_t i2c_config(struct phytium_i2c_bus *i2c_bus)
  147. {
  148. RT_ASSERT(i2c_bus);
  149. FI2cConfig input_cfg;
  150. const FI2cConfig *config_p = NULL;
  151. FI2c *instance_p = &i2c_bus->i2c_handle;
  152. FError ret = FI2C_SUCCESS;
  153. /* Lookup default configs by instance id */
  154. config_p = FI2cLookupConfig(instance_p->config.instance_id);
  155. input_cfg = *config_p;
  156. #ifdef RT_USING_SMART
  157. input_cfg.base_addr = (uintptr)rt_ioremap((void *)input_cfg.base_addr, 0x1000);
  158. #endif
  159. input_cfg.speed_rate = FI2C_SPEED_STANDARD_RATE;
  160. input_cfg.work_mode = FI2C_MASTER;
  161. FI2cDeInitialize(&i2c_bus->i2c_handle);
  162. /* Initialization */
  163. ret = FI2cCfgInitialize(instance_p, &input_cfg);
  164. if (ret != FI2C_SUCCESS)
  165. {
  166. LOG_E("Init master I2c failed, ret: 0x%x", ret);
  167. return RT_ERROR;
  168. }
  169. return RT_EOK;
  170. }
  171. #endif
  172. #if defined(I2C_USE_MIO)
  173. static rt_err_t i2c_mio_config(struct phytium_i2c_bus *i2c_bus)
  174. {
  175. RT_ASSERT(i2c_bus);
  176. FI2cConfig input_cfg;
  177. const FI2cConfig *config_p = NULL;
  178. FI2c *instance_p = &i2c_bus->i2c_handle;
  179. FError ret = FI2C_SUCCESS;
  180. mio_handle.config = *FMioLookupConfig(instance_p->config.instance_id);
  181. #ifdef RT_USING_SMART
  182. mio_handle.config.func_base_addr = (uintptr)rt_ioremap((void *)mio_handle.config.func_base_addr, 0x1200);
  183. mio_handle.config.mio_base_addr = (uintptr)rt_ioremap((void *)mio_handle.config.mio_base_addr, 0x200);
  184. #endif
  185. ret = FMioFuncInit(&mio_handle, FMIO_FUNC_SET_I2C);
  186. if (ret != FT_SUCCESS)
  187. {
  188. LOG_E("MIO initialize error.");
  189. return RT_ERROR;
  190. }
  191. FIOPadSetMioMux(instance_p->config.instance_id);
  192. config_p = FI2cLookupConfig(FI2C_DEFAULT_ID);
  193. if (NULL == config_p)
  194. {
  195. LOG_E("Config of mio instance %d non found.", instance_p->config.instance_id);
  196. return RT_ERROR;
  197. }
  198. input_cfg = *config_p;
  199. input_cfg.instance_id = instance_p->config.instance_id;
  200. input_cfg.base_addr = FMioFuncGetAddress(&mio_handle, FMIO_FUNC_SET_I2C);
  201. input_cfg.irq_num = FMioFuncGetIrqNum(&mio_handle, FMIO_FUNC_SET_I2C);
  202. input_cfg.ref_clk_hz = FMIO_CLK_FREQ_HZ;
  203. input_cfg.speed_rate = FI2C_SPEED_STANDARD_RATE;
  204. ret = FI2cCfgInitialize(&i2c_bus->i2c_handle, &input_cfg);
  205. if (FI2C_SUCCESS != ret)
  206. {
  207. LOG_E("Init mio master failed, ret: 0x%x", ret);
  208. return RT_ERROR;
  209. }
  210. return RT_EOK;
  211. }
  212. #endif
  213. static rt_err_t phytium_i2c_set_speed(struct phytium_i2c_bus *i2c_bus, rt_uint32_t speed)
  214. {
  215. RT_ASSERT(i2c_bus);
  216. u32 ret;
  217. uintptr base_addr = i2c_bus->i2c_handle.config.base_addr;
  218. ret = FI2cSetSpeed(base_addr, speed);
  219. if (ret != FI2C_SUCCESS)
  220. {
  221. LOG_E("Set i2c speed failed!\n");
  222. return RT_ERROR;
  223. }
  224. return RT_EOK;
  225. }
  226. static rt_err_t i2c_bus_control(struct rt_i2c_bus_device *device, int cmd, void *args)
  227. {
  228. RT_ASSERT(device);
  229. struct phytium_i2c_bus *i2c_bus;
  230. i2c_bus = (struct phytium_i2c_bus *)(device);
  231. switch (cmd)
  232. {
  233. case RT_I2C_DEV_CTRL_CLK:
  234. phytium_i2c_set_speed(i2c_bus, *(rt_uint32_t *)args);
  235. break;
  236. case RT_I2C_DEV_CTRL_10BIT:
  237. FI2cConfig *config_p = &i2c_bus->i2c_handle.config;
  238. config_p->use_7bit_addr = FALSE;
  239. FI2cCfgInitialize(&i2c_bus->i2c_handle, config_p);
  240. break;
  241. default:
  242. return -RT_EIO;
  243. }
  244. return RT_EOK;
  245. }
  246. static rt_ssize_t i2c_master_xfer(struct rt_i2c_bus_device *device, struct rt_i2c_msg msgs[], rt_uint32_t num)
  247. {
  248. RT_ASSERT(device);
  249. u32 ret;
  250. struct rt_i2c_msg *pmsg;
  251. struct phytium_i2c_bus *i2c_bus;
  252. i2c_bus = (struct phytium_i2c_bus *)(device);
  253. u8 mem_addr = msgs->buf[0];
  254. for (int i = 0; i < num; i++)
  255. {
  256. pmsg = i2c_bus->msg = &msgs[i];
  257. i2c_bus->i2c_handle.config.slave_addr = pmsg->addr;
  258. if (pmsg->flags & RT_I2C_RD)
  259. {
  260. ret = FI2cMasterReadPoll(&i2c_bus->i2c_handle, mem_addr, 1, &pmsg->buf[0], sizeof(pmsg->buf));
  261. if (ret != FI2C_SUCCESS)
  262. {
  263. LOG_E("I2C master read failed!\n");
  264. return RT_ERROR;
  265. }
  266. }
  267. else
  268. {
  269. ret = FI2cMasterWritePoll(&i2c_bus->i2c_handle, mem_addr, 1, &pmsg->buf[1], sizeof(pmsg->buf) - 1);
  270. if (ret != FI2C_SUCCESS)
  271. {
  272. LOG_E("I2C master write failed!\n");
  273. return RT_ERROR;
  274. }
  275. }
  276. }
  277. return RT_EOK;
  278. }
  279. static const struct rt_i2c_bus_device_ops _i2c_ops =
  280. {
  281. .master_xfer = i2c_master_xfer,
  282. .slave_xfer = NULL,
  283. .i2c_bus_control = i2c_bus_control
  284. };
  285. #if defined(I2C_USE_CONTROLLER)
  286. static int i2c_controller_init(u32 i2c_id)
  287. {
  288. u32 ret = RT_EOK;
  289. ret = i2c_config(&i2c_bus[i2c_id]);
  290. if (ret != FI2C_SUCCESS)
  291. {
  292. LOG_E("I2C config failed.\n");
  293. return RT_ERROR;
  294. }
  295. i2c_bus[i2c_id].device.ops = &_i2c_ops;
  296. ret = rt_i2c_bus_device_register(&i2c_bus[i2c_id].device, i2c_bus[i2c_id].name);
  297. LOG_D("I2C bus reg success.\n");
  298. RT_ASSERT(RT_EOK == ret);
  299. return ret;
  300. }
  301. #endif
  302. #if defined(I2C_USE_MIO)
  303. static int i2c_mio_init(u32 i2c_mio_id)
  304. {
  305. u32 ret = RT_EOK;
  306. ret = i2c_mio_config(&i2c_mio_bus[i2c_mio_id]);
  307. if (ret != FI2C_SUCCESS)
  308. {
  309. LOG_E("I2C mio config failed.\n");
  310. return RT_ERROR;
  311. }
  312. i2c_mio_bus[i2c_mio_id].device.ops = &_i2c_ops;
  313. ret = rt_i2c_bus_device_register(&i2c_mio_bus[i2c_mio_id].device, i2c_mio_bus[i2c_mio_id].name);
  314. LOG_D("I2C mio bus reg success.\n");
  315. RT_ASSERT(RT_EOK == ret);
  316. return ret;
  317. }
  318. #endif
  319. int rt_hw_i2c_init(void)
  320. {
  321. rt_err_t ret = RT_EOK;
  322. #if defined(I2C_USE_CONTROLLER)
  323. #if defined(RT_USING_I2C0)
  324. i2c_controller_init(FI2C0_ID);
  325. #endif
  326. #if defined(RT_USING_I2C1)
  327. i2c_controller_init(FI2C1_ID);
  328. #endif
  329. #if defined(RT_USING_I2C2)
  330. i2c_controller_init(FI2C2_ID);
  331. #endif
  332. #endif
  333. #if defined(I2C_USE_MIO)
  334. #if defined(RT_USING_MIO0)
  335. i2c_mio_init(FMIO0_ID);
  336. #endif
  337. #if defined(RT_USING_MIO1)
  338. i2c_mio_init(FMIO1_ID);
  339. #endif
  340. #if defined(RT_USING_MIO2)
  341. i2c_mio_init(FMIO2_ID);
  342. #endif
  343. #if defined(RT_USING_MIO3)
  344. i2c_mio_init(FMIO3_ID);
  345. #endif
  346. #if defined(RT_USING_MIO4)
  347. i2c_mio_init(FMIO4_ID);
  348. #endif
  349. #if defined(RT_USING_MIO5)
  350. i2c_mio_init(FMIO5_ID);
  351. #endif
  352. #if defined(RT_USING_MIO6)
  353. i2c_mio_init(FMIO6_ID);
  354. #endif
  355. #if defined(RT_USING_MIO7)
  356. i2c_mio_init(FMIO7_ID);
  357. #endif
  358. #if defined(RT_USING_MIO8)
  359. i2c_mio_init(FMIO8_ID);
  360. #endif
  361. #if defined(RT_USING_MIO9)
  362. i2c_mio_init(FMIO9_ID);
  363. #endif
  364. #if defined(RT_USING_MIO10)
  365. i2c_mio_init(FMIO10_ID);
  366. #endif
  367. #if defined(RT_USING_MIO11)
  368. i2c_mio_init(FMIO11_ID);
  369. #endif
  370. #if defined(RT_USING_MIO12)
  371. i2c_mio_init(FMIO12_ID);
  372. #endif
  373. #if defined(RT_USING_MIO13)
  374. i2c_mio_init(FMIO13_ID);
  375. #endif
  376. #if defined(RT_USING_MIO14)
  377. i2c_mio_init(FMIO14_ID);
  378. #endif
  379. #if defined(RT_USING_MIO15)
  380. i2c_mio_init(FMIO15_ID);
  381. #endif
  382. #endif
  383. return 0;
  384. }
  385. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  386. static struct rt_i2c_bus_device *i2c_test_bus = RT_NULL; /* I2C总线设备句柄 */
  387. int i2c_sample(int argc, char *argv[])
  388. {
  389. char name[RT_NAME_MAX];
  390. rt_strncpy(name, "MIO15", RT_NAME_MAX);
  391. i2c_test_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
  392. rt_uint8_t read_buf[2] = {0x02, 0x0};
  393. rt_uint8_t write_buf[2] = {0x02, 0x01};
  394. if (i2c_test_bus == RT_NULL)
  395. {
  396. rt_kprintf("can't find %s device!\n", name);
  397. }
  398. else
  399. {
  400. rt_kprintf("find %s device!!!!\n", name);
  401. }
  402. struct rt_i2c_msg read_msgs;
  403. read_msgs.addr = 0x6B;
  404. read_msgs.flags = RT_I2C_RD;
  405. read_msgs.buf = read_buf;
  406. read_msgs.len = 1;
  407. rt_i2c_transfer(i2c_test_bus, &read_msgs, 1);
  408. rt_kprintf("read_buf = %x\n", *read_msgs.buf);
  409. struct rt_i2c_msg write_msgs;
  410. write_msgs.addr = 0x6B;
  411. write_msgs.flags = RT_I2C_WR;
  412. write_msgs.buf = write_buf;
  413. write_msgs.len = 1;
  414. rt_i2c_transfer(i2c_test_bus, &write_msgs, 1);
  415. read_buf[0] = 0x02;
  416. rt_i2c_transfer(i2c_test_bus, &read_msgs, 1);
  417. rt_kprintf("read_buf = %x\n", *read_msgs.buf);
  418. return RT_EOK;
  419. }
  420. MSH_CMD_EXPORT(i2c_sample, i2c device sample);
  421. #endif