ihs_i2c.c 11 KB

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