CirrusLogic5430I2c.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /** @file
  2. I2C Bus implementation upon CirrusLogic.
  3. Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "CirrusLogic5430.h"
  7. #include "CirrusLogic5430I2c.h"
  8. #define SEQ_ADDRESS_REGISTER 0x3c4
  9. #define SEQ_DATA_REGISTER 0x3c5
  10. #define I2C_CONTROL 0x08
  11. #define I2CDAT_IN 7
  12. #define I2CCLK_IN 2
  13. #define I2CDAT_OUT 1
  14. #define I2CCLK_OUT 0
  15. #define I2C_BUS_SPEED 100 //100kbps
  16. /**
  17. PCI I/O byte write function.
  18. @param PciIo The pointer to PCI_IO_PROTOCOL.
  19. @param Address The bit map of I2C Data or I2C Clock pins.
  20. @param Data The date to write.
  21. **/
  22. VOID
  23. I2cOutb (
  24. EFI_PCI_IO_PROTOCOL *PciIo,
  25. UINTN Address,
  26. UINT8 Data
  27. )
  28. {
  29. PciIo->Io.Write (
  30. PciIo,
  31. EfiPciIoWidthUint8,
  32. EFI_PCI_IO_PASS_THROUGH_BAR,
  33. Address,
  34. 1,
  35. &Data
  36. );
  37. }
  38. /**
  39. PCI I/O byte read function.
  40. @param PciIo The pointer to PCI_IO_PROTOCOL.
  41. @param Address The bit map of I2C Data or I2C Clock pins.
  42. return byte value read from PCI I/O space.
  43. **/
  44. UINT8
  45. I2cInb (
  46. EFI_PCI_IO_PROTOCOL *PciIo,
  47. UINTN Address
  48. )
  49. {
  50. UINT8 Data;
  51. PciIo->Io.Read (
  52. PciIo,
  53. EfiPciIoWidthUint8,
  54. EFI_PCI_IO_PASS_THROUGH_BAR,
  55. Address,
  56. 1,
  57. &Data
  58. );
  59. return Data;
  60. }
  61. /**
  62. Read status of I2C Data and I2C Clock Pins.
  63. @param PciIo The pointer to PCI_IO_PROTOCOL.
  64. @param Blt The bit map of I2C Data or I2C Clock pins.
  65. @retval 0 Low on I2C Data or I2C Clock Pin.
  66. @retval 1 High on I2C Data or I2C Clock Pin.
  67. **/
  68. UINT8
  69. I2cPinRead (
  70. EFI_PCI_IO_PROTOCOL *PciIo,
  71. UINT8 Bit
  72. )
  73. {
  74. I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
  75. return (UINT8) ((I2cInb (PciIo, SEQ_DATA_REGISTER) >> Bit ) & 0xfe);
  76. }
  77. /**
  78. Set/Clear I2C Data and I2C Clock Pins.
  79. @param PciIo The pointer to PCI_IO_PROTOCOL.
  80. @param Blt The bit map to controller I2C Data or I2C Clock pins.
  81. @param Value 1 or 0 stands for Set or Clear I2C Data and I2C Clock Pins.
  82. **/
  83. VOID
  84. I2cPinWrite (
  85. EFI_PCI_IO_PROTOCOL *PciIo,
  86. UINT8 Bit,
  87. UINT8 Value
  88. )
  89. {
  90. UINT8 Byte;
  91. I2cOutb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);
  92. Byte = (UINT8) (I2cInb (PciIo, SEQ_DATA_REGISTER) & (UINT8) ~(1 << Bit)) ;
  93. Byte = (UINT8) (Byte | ((Value & 0x01) << Bit));
  94. I2cOutb (PciIo, SEQ_DATA_REGISTER, (UINT8) (Byte | 0x40));
  95. return;
  96. }
  97. /**
  98. Read/write delay acoording to I2C Bus Speed.
  99. **/
  100. VOID
  101. I2cDelay (
  102. VOID
  103. )
  104. {
  105. MicroSecondDelay (1000 / I2C_BUS_SPEED);
  106. }
  107. /**
  108. Write a 8-bit data onto I2C Data Pin.
  109. @param PciIo The pointer to PCI_IO_PROTOCOL.
  110. @param Data The byte data to write.
  111. **/
  112. VOID
  113. I2cSendByte (
  114. EFI_PCI_IO_PROTOCOL *PciIo,
  115. UINT8 Data
  116. )
  117. {
  118. UINTN Index;
  119. //
  120. // Send byte data onto I2C Bus
  121. //
  122. for (Index = 0; Index < 8; Index --) {
  123. I2cPinWrite (PciIo, I2CDAT_OUT, (UINT8) (Data >> (7 - Index)));
  124. I2cPinWrite (PciIo, I2CCLK_OUT, 1);
  125. I2cDelay ();
  126. I2cPinWrite (PciIo, I2CCLK_OUT, 0);
  127. }
  128. }
  129. /**
  130. Read a 8-bit data from I2C Data Pin.
  131. @param PciIo The pointer to PCI_IO_PROTOCOL.
  132. Return the byte data read from I2C Data Pin.
  133. **/
  134. UINT8
  135. I2cReceiveByte (
  136. EFI_PCI_IO_PROTOCOL *PciIo
  137. )
  138. {
  139. UINT8 Data;
  140. UINTN Index;
  141. Data = 0;
  142. //
  143. // Read byte data from I2C Bus
  144. //
  145. for (Index = 0; Index < 8; Index --) {
  146. I2cPinWrite (PciIo, I2CCLK_OUT, 1);
  147. I2cDelay ();
  148. Data = (UINT8) (Data << 1);
  149. Data = (UINT8) (Data | I2cPinRead (PciIo, I2CDAT_IN));
  150. I2cPinWrite (PciIo, I2CCLK_OUT, 0);
  151. }
  152. return Data;
  153. }
  154. /**
  155. Receive an ACK signal from I2C Bus.
  156. @param PciIo The pointer to PCI_IO_PROTOCOL.
  157. **/
  158. BOOLEAN
  159. I2cWaitAck (
  160. EFI_PCI_IO_PROTOCOL *PciIo
  161. )
  162. {
  163. //
  164. // Wait for ACK signal
  165. //
  166. I2cPinWrite (PciIo, I2CDAT_OUT, 1);
  167. I2cPinWrite (PciIo, I2CCLK_OUT, 1);
  168. I2cDelay ();
  169. if (I2cPinRead (PciIo, I2CDAT_IN) == 0) {
  170. I2cPinWrite (PciIo, I2CDAT_OUT, 1);
  171. return TRUE;
  172. } else {
  173. return FALSE;
  174. }
  175. }
  176. /**
  177. Send an ACK signal onto I2C Bus.
  178. @param PciIo The pointer to PCI_IO_PROTOCOL.
  179. **/
  180. VOID
  181. I2cSendAck (
  182. EFI_PCI_IO_PROTOCOL *PciIo
  183. )
  184. {
  185. I2cPinWrite (PciIo, I2CCLK_OUT, 1);
  186. I2cPinWrite (PciIo, I2CDAT_OUT, 1);
  187. I2cPinWrite (PciIo, I2CDAT_OUT, 0);
  188. I2cPinWrite (PciIo, I2CCLK_OUT, 0);
  189. }
  190. /**
  191. Start a I2C transfer on I2C Bus.
  192. @param PciIo The pointer to PCI_IO_PROTOCOL.
  193. **/
  194. VOID
  195. I2cStart (
  196. EFI_PCI_IO_PROTOCOL *PciIo
  197. )
  198. {
  199. //
  200. // Init CLK and DAT pins
  201. //
  202. I2cPinWrite (PciIo, I2CCLK_OUT, 1);
  203. I2cPinWrite (PciIo, I2CDAT_OUT, 1);
  204. //
  205. // Start a I2C transfer, set SDA low from high, when SCL is high
  206. //
  207. I2cPinWrite (PciIo, I2CDAT_OUT, 0);
  208. I2cPinWrite (PciIo, I2CCLK_OUT, 0);
  209. }
  210. /**
  211. Stop a I2C transfer on I2C Bus.
  212. @param PciIo The pointer to PCI_IO_PROTOCOL.
  213. **/
  214. VOID
  215. I2cStop (
  216. EFI_PCI_IO_PROTOCOL *PciIo
  217. )
  218. {
  219. //
  220. // Stop a I2C transfer, set SDA high from low, when SCL is high
  221. //
  222. I2cPinWrite (PciIo, I2CDAT_OUT, 0);
  223. I2cPinWrite (PciIo, I2CCLK_OUT, 1);
  224. I2cPinWrite (PciIo, I2CDAT_OUT, 1);
  225. }
  226. /**
  227. Read one byte data on I2C Bus.
  228. Read one byte data from the slave device connectet to I2C Bus.
  229. If Data is NULL, then ASSERT().
  230. @param PciIo The pointer to PCI_IO_PROTOCOL.
  231. @param DeviceAddress Slave device's address.
  232. @param RegisterAddress The register address on slave device.
  233. @param Data The pointer to returned data if EFI_SUCCESS returned.
  234. @retval EFI_DEVICE_ERROR
  235. @retval EFI_SUCCESS
  236. **/
  237. EFI_STATUS
  238. EFIAPI
  239. I2cReadByte (
  240. EFI_PCI_IO_PROTOCOL *PciIo,
  241. UINT8 DeviceAddress,
  242. UINT8 RegisterAddress,
  243. UINT8 *Data
  244. )
  245. {
  246. ASSERT (Data != NULL);
  247. //
  248. // Start I2C transfer
  249. //
  250. I2cStart (PciIo);
  251. //
  252. // Send slave address with enabling write flag
  253. //
  254. I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
  255. //
  256. // Wait for ACK signal
  257. //
  258. if (I2cWaitAck (PciIo) == FALSE) {
  259. return EFI_DEVICE_ERROR;
  260. }
  261. //
  262. // Send register address
  263. //
  264. I2cSendByte (PciIo, RegisterAddress);
  265. //
  266. // Wait for ACK signal
  267. //
  268. if (I2cWaitAck (PciIo) == FALSE) {
  269. return EFI_DEVICE_ERROR;
  270. }
  271. //
  272. // Send slave address with enabling read flag
  273. //
  274. I2cSendByte (PciIo, (UINT8) (DeviceAddress | 0x01));
  275. //
  276. // Wait for ACK signal
  277. //
  278. if (I2cWaitAck (PciIo) == FALSE) {
  279. return EFI_DEVICE_ERROR;
  280. }
  281. //
  282. // Read byte data from I2C Bus
  283. //
  284. *Data = I2cReceiveByte (PciIo);
  285. //
  286. // Send ACK signal onto I2C Bus
  287. //
  288. I2cSendAck (PciIo);
  289. //
  290. // Stop a I2C transfer
  291. //
  292. I2cStop (PciIo);
  293. return EFI_SUCCESS;
  294. }
  295. /**
  296. Write one byte data onto I2C Bus.
  297. Write one byte data to the slave device connectet to I2C Bus.
  298. If Data is NULL, then ASSERT().
  299. @param PciIo The pointer to PCI_IO_PROTOCOL.
  300. @param DeviceAddress Slave device's address.
  301. @param RegisterAddress The register address on slave device.
  302. @param Data The pointer to write data.
  303. @retval EFI_DEVICE_ERROR
  304. @retval EFI_SUCCESS
  305. **/
  306. EFI_STATUS
  307. EFIAPI
  308. I2cWriteByte (
  309. EFI_PCI_IO_PROTOCOL *PciIo,
  310. UINT8 DeviceAddress,
  311. UINT8 RegisterAddress,
  312. UINT8 *Data
  313. )
  314. {
  315. ASSERT (Data != NULL);
  316. I2cStart (PciIo);
  317. //
  318. // Send slave address with enabling write flag
  319. //
  320. I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));
  321. //
  322. // Wait for ACK signal
  323. //
  324. if (I2cWaitAck (PciIo) == FALSE) {
  325. return EFI_DEVICE_ERROR;
  326. }
  327. //
  328. // Send register address
  329. //
  330. I2cSendByte (PciIo, RegisterAddress);
  331. //
  332. // Wait for ACK signal
  333. //
  334. if (I2cWaitAck (PciIo) == FALSE) {
  335. return EFI_DEVICE_ERROR;
  336. }
  337. //
  338. // Send byte data onto I2C Bus
  339. //
  340. I2cSendByte (PciIo, *Data);
  341. //
  342. // Wait for ACK signal
  343. //
  344. if (I2cWaitAck (PciIo) == FALSE) {
  345. return EFI_DEVICE_ERROR;
  346. }
  347. //
  348. // Stop a I2C transfer
  349. //
  350. I2cStop (PciIo);
  351. return EFI_SUCCESS;
  352. }