ihs_i2c.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2013
  4. * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
  5. */
  6. #include <common.h>
  7. #include <i2c.h>
  8. #if CONFIG_IS_ENABLED(DM_I2C)
  9. #include <dm.h>
  10. #include <regmap.h>
  11. #else
  12. #include <gdsys_fpga.h>
  13. #endif
  14. #include <log.h>
  15. #include <asm/global_data.h>
  16. #include <asm/unaligned.h>
  17. #include <linux/bitops.h>
  18. #include <linux/delay.h>
  19. #if CONFIG_IS_ENABLED(DM_I2C)
  20. struct ihs_i2c_priv {
  21. uint speed;
  22. struct regmap *map;
  23. };
  24. struct ihs_i2c_regs {
  25. u16 interrupt_status;
  26. u16 interrupt_enable_control;
  27. u16 write_mailbox_ext;
  28. u16 write_mailbox;
  29. u16 read_mailbox_ext;
  30. u16 read_mailbox;
  31. };
  32. #define ihs_i2c_set(map, member, val) \
  33. regmap_set(map, struct ihs_i2c_regs, member, val)
  34. #define ihs_i2c_get(map, member, valp) \
  35. regmap_get(map, struct ihs_i2c_regs, member, valp)
  36. #else /* !CONFIG_DM_I2C */
  37. DECLARE_GLOBAL_DATA_PTR;
  38. #ifdef CONFIG_SYS_I2C_IHS_DUAL
  39. #define I2C_SET_REG(fld, val) \
  40. do { \
  41. if (I2C_ADAP_HWNR & 0x10) \
  42. FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
  43. else \
  44. FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
  45. } while (0)
  46. #else
  47. #define I2C_SET_REG(fld, val) \
  48. FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
  49. #endif
  50. #ifdef CONFIG_SYS_I2C_IHS_DUAL
  51. #define I2C_GET_REG(fld, val) \
  52. do { \
  53. if (I2C_ADAP_HWNR & 0x10) \
  54. FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
  55. else \
  56. FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
  57. } while (0)
  58. #else
  59. #define I2C_GET_REG(fld, val) \
  60. FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
  61. #endif
  62. #endif /* CONFIG_DM_I2C */
  63. enum {
  64. I2CINT_ERROR_EV = BIT(13),
  65. I2CINT_TRANSMIT_EV = BIT(14),
  66. I2CINT_RECEIVE_EV = BIT(15),
  67. };
  68. enum {
  69. I2CMB_READ = 0 << 10,
  70. I2CMB_WRITE = 1 << 10,
  71. I2CMB_1BYTE = 0 << 11,
  72. I2CMB_2BYTE = 1 << 11,
  73. I2CMB_DONT_HOLD_BUS = 0 << 13,
  74. I2CMB_HOLD_BUS = 1 << 13,
  75. I2CMB_NATIVE = 2 << 14,
  76. };
  77. enum {
  78. I2COP_WRITE = 0,
  79. I2COP_READ = 1,
  80. };
  81. #if CONFIG_IS_ENABLED(DM_I2C)
  82. static int wait_for_int(struct udevice *dev, int read)
  83. #else
  84. static int wait_for_int(bool read)
  85. #endif
  86. {
  87. u16 val;
  88. uint ctr = 0;
  89. #if CONFIG_IS_ENABLED(DM_I2C)
  90. struct ihs_i2c_priv *priv = dev_get_priv(dev);
  91. #endif
  92. #if CONFIG_IS_ENABLED(DM_I2C)
  93. ihs_i2c_get(priv->map, interrupt_status, &val);
  94. #else
  95. I2C_GET_REG(interrupt_status, &val);
  96. #endif
  97. /* Wait until error or receive/transmit interrupt was raised */
  98. while (!(val & (I2CINT_ERROR_EV
  99. | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) {
  100. udelay(10);
  101. if (ctr++ > 5000) {
  102. debug("%s: timed out\n", __func__);
  103. return -ETIMEDOUT;
  104. }
  105. #if CONFIG_IS_ENABLED(DM_I2C)
  106. ihs_i2c_get(priv->map, interrupt_status, &val);
  107. #else
  108. I2C_GET_REG(interrupt_status, &val);
  109. #endif
  110. }
  111. return (val & I2CINT_ERROR_EV) ? -EIO : 0;
  112. }
  113. #if CONFIG_IS_ENABLED(DM_I2C)
  114. static int ihs_i2c_transfer(struct udevice *dev, uchar chip,
  115. uchar *buffer, int len, int read, bool is_last)
  116. #else
  117. static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
  118. bool is_last)
  119. #endif
  120. {
  121. u16 val;
  122. u16 data;
  123. int res;
  124. #if CONFIG_IS_ENABLED(DM_I2C)
  125. struct ihs_i2c_priv *priv = dev_get_priv(dev);
  126. #endif
  127. /* Clear interrupt status */
  128. data = I2CINT_ERROR_EV | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV;
  129. #if CONFIG_IS_ENABLED(DM_I2C)
  130. ihs_i2c_set(priv->map, interrupt_status, data);
  131. ihs_i2c_get(priv->map, interrupt_status, &val);
  132. #else
  133. I2C_SET_REG(interrupt_status, data);
  134. I2C_GET_REG(interrupt_status, &val);
  135. #endif
  136. /* If we want to write and have data, write the bytes to the mailbox */
  137. if (!read && len) {
  138. val = buffer[0];
  139. if (len > 1)
  140. val |= buffer[1] << 8;
  141. #if CONFIG_IS_ENABLED(DM_I2C)
  142. ihs_i2c_set(priv->map, write_mailbox_ext, val);
  143. #else
  144. I2C_SET_REG(write_mailbox_ext, val);
  145. #endif
  146. }
  147. data = I2CMB_NATIVE
  148. | (read ? 0 : I2CMB_WRITE)
  149. | (chip << 1)
  150. | ((len > 1) ? I2CMB_2BYTE : 0)
  151. | (is_last ? 0 : I2CMB_HOLD_BUS);
  152. #if CONFIG_IS_ENABLED(DM_I2C)
  153. ihs_i2c_set(priv->map, write_mailbox, data);
  154. #else
  155. I2C_SET_REG(write_mailbox, data);
  156. #endif
  157. #if CONFIG_IS_ENABLED(DM_I2C)
  158. res = wait_for_int(dev, read);
  159. #else
  160. res = wait_for_int(read);
  161. #endif
  162. if (res) {
  163. if (res == -ETIMEDOUT)
  164. debug("%s: time out while waiting for event\n", __func__);
  165. return res;
  166. }
  167. /* If we want to read, get the bytes from the mailbox */
  168. if (read) {
  169. #if CONFIG_IS_ENABLED(DM_I2C)
  170. ihs_i2c_get(priv->map, read_mailbox_ext, &val);
  171. #else
  172. I2C_GET_REG(read_mailbox_ext, &val);
  173. #endif
  174. buffer[0] = val & 0xff;
  175. if (len > 1)
  176. buffer[1] = val >> 8;
  177. }
  178. return 0;
  179. }
  180. #if CONFIG_IS_ENABLED(DM_I2C)
  181. static int ihs_i2c_send_buffer(struct udevice *dev, uchar chip, u8 *data, int len, bool hold_bus, int read)
  182. #else
  183. static int ihs_i2c_send_buffer(uchar chip, u8 *data, int len, bool hold_bus,
  184. int read)
  185. #endif
  186. {
  187. int res;
  188. while (len) {
  189. int transfer = min(len, 2);
  190. bool is_last = len <= transfer;
  191. #if CONFIG_IS_ENABLED(DM_I2C)
  192. res = ihs_i2c_transfer(dev, chip, data, transfer, read,
  193. hold_bus ? false : is_last);
  194. #else
  195. res = ihs_i2c_transfer(chip, data, transfer, read,
  196. hold_bus ? false : is_last);
  197. #endif
  198. if (res)
  199. return res;
  200. data += transfer;
  201. len -= transfer;
  202. }
  203. return 0;
  204. }
  205. #if CONFIG_IS_ENABLED(DM_I2C)
  206. static int ihs_i2c_address(struct udevice *dev, uchar chip, u8 *addr, int alen,
  207. bool hold_bus)
  208. #else
  209. static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
  210. #endif
  211. {
  212. #if CONFIG_IS_ENABLED(DM_I2C)
  213. return ihs_i2c_send_buffer(dev, chip, addr, alen, hold_bus, I2COP_WRITE);
  214. #else
  215. return ihs_i2c_send_buffer(chip, addr, alen, hold_bus, I2COP_WRITE);
  216. #endif
  217. }
  218. #if CONFIG_IS_ENABLED(DM_I2C)
  219. static int ihs_i2c_access(struct udevice *dev, uchar chip, u8 *addr,
  220. int alen, uchar *buffer, int len, int read)
  221. #else
  222. static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, u8 *addr,
  223. int alen, uchar *buffer, int len, int read)
  224. #endif
  225. {
  226. int res;
  227. /* Don't hold the bus if length of data to send/receive is zero */
  228. if (len <= 0)
  229. return -EINVAL;
  230. #if CONFIG_IS_ENABLED(DM_I2C)
  231. res = ihs_i2c_address(dev, chip, addr, alen, len);
  232. #else
  233. res = ihs_i2c_address(chip, addr, alen, len);
  234. #endif
  235. if (res)
  236. return res;
  237. #if CONFIG_IS_ENABLED(DM_I2C)
  238. return ihs_i2c_send_buffer(dev, chip, buffer, len, false, read);
  239. #else
  240. return ihs_i2c_send_buffer(chip, buffer, len, false, read);
  241. #endif
  242. }
  243. #if CONFIG_IS_ENABLED(DM_I2C)
  244. int ihs_i2c_probe(struct udevice *bus)
  245. {
  246. struct ihs_i2c_priv *priv = dev_get_priv(bus);
  247. regmap_init_mem(dev_ofnode(bus), &priv->map);
  248. return 0;
  249. }
  250. static int ihs_i2c_set_bus_speed(struct udevice *bus, uint speed)
  251. {
  252. struct ihs_i2c_priv *priv = dev_get_priv(bus);
  253. if (speed != priv->speed && priv->speed != 0)
  254. return -EINVAL;
  255. priv->speed = speed;
  256. return 0;
  257. }
  258. static int ihs_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
  259. {
  260. struct i2c_msg *dmsg, *omsg, dummy;
  261. memset(&dummy, 0, sizeof(struct i2c_msg));
  262. /* We expect either two messages (one with an offset and one with the
  263. * actucal data) or one message (just data)
  264. */
  265. if (nmsgs > 2 || nmsgs == 0) {
  266. debug("%s: Only one or two messages are supported\n", __func__);
  267. return -ENOTSUPP;
  268. }
  269. omsg = nmsgs == 1 ? &dummy : msg;
  270. dmsg = nmsgs == 1 ? msg : msg + 1;
  271. if (dmsg->flags & I2C_M_RD)
  272. return ihs_i2c_access(bus, dmsg->addr, omsg->buf,
  273. omsg->len, dmsg->buf, dmsg->len,
  274. I2COP_READ);
  275. else
  276. return ihs_i2c_access(bus, dmsg->addr, omsg->buf,
  277. omsg->len, dmsg->buf, dmsg->len,
  278. I2COP_WRITE);
  279. }
  280. static int ihs_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
  281. u32 chip_flags)
  282. {
  283. uchar buffer[2];
  284. int res;
  285. res = ihs_i2c_transfer(bus, chip_addr, buffer, 0, I2COP_READ, true);
  286. if (res)
  287. return res;
  288. return 0;
  289. }
  290. static const struct dm_i2c_ops ihs_i2c_ops = {
  291. .xfer = ihs_i2c_xfer,
  292. .probe_chip = ihs_i2c_probe_chip,
  293. .set_bus_speed = ihs_i2c_set_bus_speed,
  294. };
  295. static const struct udevice_id ihs_i2c_ids[] = {
  296. { .compatible = "gdsys,ihs_i2cmaster", },
  297. { /* sentinel */ }
  298. };
  299. U_BOOT_DRIVER(i2c_ihs) = {
  300. .name = "i2c_ihs",
  301. .id = UCLASS_I2C,
  302. .of_match = ihs_i2c_ids,
  303. .probe = ihs_i2c_probe,
  304. .priv_auto = sizeof(struct ihs_i2c_priv),
  305. .ops = &ihs_i2c_ops,
  306. };
  307. #else /* CONFIG_DM_I2C */
  308. static void ihs_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
  309. {
  310. #ifdef CONFIG_SYS_I2C_INIT_BOARD
  311. /*
  312. * Call board specific i2c bus reset routine before accessing the
  313. * environment, which might be in a chip on that bus. For details
  314. * about this problem see doc/I2C_Edge_Conditions.
  315. */
  316. i2c_init_board();
  317. #endif
  318. }
  319. static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
  320. {
  321. uchar buffer[2];
  322. int res;
  323. res = ihs_i2c_transfer(chip, buffer, 0, I2COP_READ, true);
  324. if (res)
  325. return res;
  326. return 0;
  327. }
  328. static int ihs_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
  329. int alen, uchar *buffer, int len)
  330. {
  331. u8 addr_bytes[4];
  332. put_unaligned_le32(addr, addr_bytes);
  333. return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
  334. I2COP_READ);
  335. }
  336. static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
  337. int alen, uchar *buffer, int len)
  338. {
  339. u8 addr_bytes[4];
  340. put_unaligned_le32(addr, addr_bytes);
  341. return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
  342. I2COP_WRITE);
  343. }
  344. static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap,
  345. unsigned int speed)
  346. {
  347. if (speed != adap->speed)
  348. return -EINVAL;
  349. return speed;
  350. }
  351. /*
  352. * Register IHS i2c adapters
  353. */
  354. #ifdef CONFIG_SYS_I2C_IHS_CH0
  355. U_BOOT_I2C_ADAP_COMPLETE(ihs0, ihs_i2c_init, ihs_i2c_probe,
  356. ihs_i2c_read, ihs_i2c_write,
  357. ihs_i2c_set_bus_speed,
  358. CONFIG_SYS_I2C_IHS_SPEED_0,
  359. CONFIG_SYS_I2C_IHS_SLAVE_0, 0)
  360. #ifdef CONFIG_SYS_I2C_IHS_DUAL
  361. U_BOOT_I2C_ADAP_COMPLETE(ihs0_1, ihs_i2c_init, ihs_i2c_probe,
  362. ihs_i2c_read, ihs_i2c_write,
  363. ihs_i2c_set_bus_speed,
  364. CONFIG_SYS_I2C_IHS_SPEED_0_1,
  365. CONFIG_SYS_I2C_IHS_SLAVE_0_1, 16)
  366. #endif
  367. #endif
  368. #ifdef CONFIG_SYS_I2C_IHS_CH1
  369. U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe,
  370. ihs_i2c_read, ihs_i2c_write,
  371. ihs_i2c_set_bus_speed,
  372. CONFIG_SYS_I2C_IHS_SPEED_1,
  373. CONFIG_SYS_I2C_IHS_SLAVE_1, 1)
  374. #ifdef CONFIG_SYS_I2C_IHS_DUAL
  375. U_BOOT_I2C_ADAP_COMPLETE(ihs1_1, ihs_i2c_init, ihs_i2c_probe,
  376. ihs_i2c_read, ihs_i2c_write,
  377. ihs_i2c_set_bus_speed,
  378. CONFIG_SYS_I2C_IHS_SPEED_1_1,
  379. CONFIG_SYS_I2C_IHS_SLAVE_1_1, 17)
  380. #endif
  381. #endif
  382. #ifdef CONFIG_SYS_I2C_IHS_CH2
  383. U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe,
  384. ihs_i2c_read, ihs_i2c_write,
  385. ihs_i2c_set_bus_speed,
  386. CONFIG_SYS_I2C_IHS_SPEED_2,
  387. CONFIG_SYS_I2C_IHS_SLAVE_2, 2)
  388. #ifdef CONFIG_SYS_I2C_IHS_DUAL
  389. U_BOOT_I2C_ADAP_COMPLETE(ihs2_1, ihs_i2c_init, ihs_i2c_probe,
  390. ihs_i2c_read, ihs_i2c_write,
  391. ihs_i2c_set_bus_speed,
  392. CONFIG_SYS_I2C_IHS_SPEED_2_1,
  393. CONFIG_SYS_I2C_IHS_SLAVE_2_1, 18)
  394. #endif
  395. #endif
  396. #ifdef CONFIG_SYS_I2C_IHS_CH3
  397. U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe,
  398. ihs_i2c_read, ihs_i2c_write,
  399. ihs_i2c_set_bus_speed,
  400. CONFIG_SYS_I2C_IHS_SPEED_3,
  401. CONFIG_SYS_I2C_IHS_SLAVE_3, 3)
  402. #ifdef CONFIG_SYS_I2C_IHS_DUAL
  403. U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe,
  404. ihs_i2c_read, ihs_i2c_write,
  405. ihs_i2c_set_bus_speed,
  406. CONFIG_SYS_I2C_IHS_SPEED_3_1,
  407. CONFIG_SYS_I2C_IHS_SLAVE_3_1, 19)
  408. #endif
  409. #endif
  410. #endif /* CONFIG_DM_I2C */