gpioi2c.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. #include "drv_types.h"
  2. #include "hdmi_time.h"
  3. #include "gpioi2c.h"
  4. #include <drv_gpio.h>
  5. #include <drv_i2c.h>
  6. #if 0
  7. static UINT32 mmioRead(
  8. UINT32 addr)
  9. {
  10. volatile UINT32 dw = *((UINT32*)addr);
  11. return dw;
  12. }
  13. static UINT32 mmioReadMask(
  14. UINT32 addr, UINT32 mask)
  15. {
  16. return mmioRead(addr) & mask;
  17. }
  18. static void mmioWrite(
  19. UINT32 addr, UINT32 data)
  20. {
  21. *(UINT32*)addr = data;
  22. }
  23. static void mmioWriteMask(
  24. UINT32 addr, UINT32 mask, UINT32 data)
  25. {
  26. UINT32 dw;
  27. dw = mmioReadMask(addr, ~mask);
  28. mmioWrite(addr, ((data & mask) | dw));
  29. }
  30. static void set(UINT8 index, UINT32 value)
  31. {
  32. UINT8 bits;
  33. // set GPIO output value
  34. bits = index ;
  35. mmioWriteMask(0xbe0f0610, (0x1 << bits), (0x0 << bits));
  36. // set GPIO input / output control register to "output mode"
  37. mmioWriteMask(0xbe0f0618, (0x1 << bits), (value << bits));
  38. // set "function selection" mux to "GPIO (set '01') "
  39. bits = (index % 16) * 2;
  40. mmioWriteMask(0xbe0f0604, (0x3 << bits), (0x1 << bits));
  41. }
  42. static UINT8 gpio_read(UINT8 idx)
  43. {
  44. return GPIOTryRead(idx);
  45. }
  46. #endif
  47. static UINT8 gGpioI2cStatus;
  48. //#define GPIO_I2C_CLK 24
  49. //#define GPIO_I2C_DATA 25
  50. #define LAG 8
  51. static void MxI2CStart(void)
  52. {
  53. gGpioI2cStatus = 0;
  54. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL);
  55. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL);
  56. HDMI_DelayUs(LAG);
  57. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL);
  58. HDMI_DelayUs(LAG);
  59. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL);
  60. HDMI_DelayUs(LAG);
  61. }
  62. static void MxI2CStop(void)
  63. {
  64. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL);
  65. HDMI_DelayUs(LAG);
  66. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL);
  67. HDMI_DelayUs(LAG);
  68. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL);
  69. HDMI_DelayUs(LAG);
  70. GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL);
  71. GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA);
  72. HDMI_DelayUs(LAG);
  73. }
  74. static void MxI2CRestart(void)
  75. {
  76. if (gGpioI2cStatus)
  77. {
  78. return;
  79. }
  80. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL);
  81. HDMI_DelayUs(LAG);
  82. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL);
  83. HDMI_DelayUs(LAG);
  84. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL);
  85. HDMI_DelayUs(LAG);
  86. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL);
  87. HDMI_DelayUs(LAG);
  88. }
  89. static void MxI2CWriteByte(UINT8 Value)
  90. {
  91. UINT8 i;
  92. if (gGpioI2cStatus)
  93. {
  94. return;
  95. }
  96. for (i = 0; i < 8; i++)
  97. {
  98. if (Value & 0x80)
  99. {
  100. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL);
  101. }
  102. else
  103. {
  104. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL);
  105. }
  106. HDMI_DelayUs(LAG);
  107. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL);
  108. HDMI_DelayUs(LAG);
  109. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL);
  110. HDMI_DelayUs(LAG);
  111. Value <<= 1;
  112. }
  113. GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA);
  114. HDMI_DelayUs(LAG);
  115. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL);
  116. HDMI_DelayUs(LAG);
  117. if (GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA))
  118. {
  119. gGpioI2cStatus = 1;
  120. }
  121. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL);
  122. HDMI_DelayUs(LAG);
  123. }
  124. static UINT8 MxI2CReadByte(UINT8 bMoreByte)
  125. {
  126. UINT8 i, Value;
  127. if (gGpioI2cStatus)
  128. {
  129. return 0;
  130. }
  131. GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA);
  132. HDMI_DelayUs(LAG);
  133. Value = 0;
  134. for (i = 0; i < 8; i++)
  135. {
  136. Value <<= 1;
  137. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL);
  138. HDMI_DelayUs(LAG);
  139. if (GPIOGetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA))
  140. {
  141. Value |= 1;
  142. }
  143. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL);
  144. HDMI_DelayUs(LAG);
  145. }
  146. if (bMoreByte)
  147. {
  148. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_OFFLEVEL);
  149. }
  150. else
  151. {
  152. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SDA, GPIO_FUNC_ONLEVEL);
  153. }
  154. HDMI_DelayUs(LAG);
  155. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_ONLEVEL);
  156. HDMI_DelayUs(LAG);
  157. GPIOSetValueByPinFunc(GPIO_PIN_HDMISWITCH_SCL, GPIO_FUNC_OFFLEVEL);
  158. HDMI_DelayUs(LAG);
  159. return Value;
  160. }
  161. static UINT8 gI2CMode = 0;
  162. static UINT8 gDeviceId = 0;
  163. static UINT8 gAddrLen = 1;
  164. void hdmi_i2c_setup(UINT8 i2c_mode, UINT8 device_id, UINT8 addr_len)
  165. {
  166. gI2CMode = i2c_mode;
  167. gDeviceId = device_id & 0xfe; // device id can't be odd.
  168. gAddrLen = (addr_len > 4) ? 4 : addr_len;
  169. }
  170. static UINT8 gpio_i2c_write(UINT32 addr, UINT8 *data_ptr, INT32 data_sz)
  171. {
  172. /* Start */
  173. MxI2CStart();
  174. MxI2CWriteByte(gDeviceId);
  175. /* Set Address */
  176. if (gAddrLen)
  177. {
  178. INT32 i;
  179. for (i = gAddrLen - 1 ; i >= 0 ; i--)
  180. {
  181. MxI2CWriteByte((UINT8)((addr >> (i * 8)) & 0xff));
  182. }
  183. }
  184. /* Write Data */
  185. if (data_ptr && data_sz > 0)
  186. {
  187. INT32 i;
  188. for (i = 0 ; i < data_sz ; i++)
  189. {
  190. MxI2CWriteByte(data_ptr[i]);
  191. }
  192. }
  193. /* Stop */
  194. MxI2CStop();
  195. return gGpioI2cStatus;
  196. }
  197. static UINT8 gpio_i2c_read(UINT32 addr, UINT8 *data_ptr, INT32 data_sz)
  198. {
  199. /* Start */
  200. MxI2CStart();
  201. MxI2CWriteByte(gDeviceId);
  202. /* Set Address */
  203. if (gAddrLen)
  204. {
  205. INT32 i;
  206. for (i = gAddrLen - 1 ; i >= 0 ; i--)
  207. {
  208. MxI2CWriteByte((UINT8)((addr >> (i * 8)) & 0xff));
  209. }
  210. }
  211. MxI2CRestart();
  212. MxI2CWriteByte(gDeviceId | 0x1);
  213. /* Write Data */
  214. if (data_ptr && data_sz > 0)
  215. {
  216. INT32 i;
  217. for (i = 0 ; i < data_sz ; i++)
  218. {
  219. data_ptr[i] = MxI2CReadByte((i + 1 == data_sz) ? 0 : 1);
  220. }
  221. }
  222. /* Stop */
  223. MxI2CStop();
  224. return gGpioI2cStatus;
  225. }
  226. static UINT32 toI2CAddr(UINT32 i2cAddr)
  227. {
  228. // I2C Addr foramt [addr_type,1][addr,3]
  229. // ex. one byte address 0x12, input addr 0x01000012, output addr 0x01000012
  230. // ex. two byte address 0x1234, input addr 0x02001234, output addr 0x02003412
  231. // ex. three byte address 0x123456, input addr 0x03123456, output addr 0x03563412
  232. UINT32 addr = i2cAddr & 0xff000000;
  233. UINT8 addrType = (i2cAddr >> 24) & 0xff;
  234. UINT8 *ptr = (UINT8 *)&i2cAddr;
  235. if (addrType == 1)
  236. {
  237. addr |= (*ptr);
  238. }
  239. else if (addrType == 2)
  240. {
  241. addr |= (((*ptr) << 8) | (*(ptr + 1)));
  242. }
  243. else if (addrType == 3)
  244. {
  245. addr |= (((*ptr) << 16) | ((*(ptr + 1)) << 8) | (*(ptr + 2)));
  246. }
  247. else
  248. {
  249. addr = 0;
  250. }
  251. return addr;
  252. }
  253. UINT8 hdmi_i2c_write(UINT32 addr, UINT8 *data_ptr, INT32 data_sz)
  254. {
  255. UINT8 status = 0;
  256. if (gDeviceId == 0)
  257. {
  258. return -1;
  259. }
  260. if (gI2CMode == USE_I2C_VIA_GPIO)
  261. {
  262. status = gpio_i2c_write(addr, data_ptr, data_sz);
  263. }
  264. else
  265. {
  266. DRV_I2C_WriteFun(
  267. gI2CMode, gDeviceId,
  268. ADDRESS_TYPE_MULTIPLE,
  269. toI2CAddr((gAddrLen << 24) | (addr & 0xffffff)),
  270. data_ptr, data_sz,
  271. I2C_SPEED_100K, &status);
  272. }
  273. return status;
  274. }
  275. UINT8 hdmi_i2c_read(UINT32 addr, UINT8 *data_ptr, INT32 data_sz)
  276. {
  277. UINT8 status = 0;
  278. if (gDeviceId == 0)
  279. {
  280. return -1;
  281. }
  282. if (gI2CMode == USE_I2C_VIA_GPIO)
  283. {
  284. status = gpio_i2c_read(addr, data_ptr, data_sz);
  285. }
  286. else
  287. {
  288. DRV_I2C_ReadFun(
  289. gI2CMode, gDeviceId,
  290. ADDRESS_TYPE_MULTIPLE,
  291. toI2CAddr((gAddrLen << 24) | (addr & 0xffffff)),
  292. data_ptr, data_sz,
  293. I2C_SPEED_100K, &status);
  294. }
  295. return status;
  296. }
  297. void hdmi_gpio_write(UINT8 idx, UINT8 val)
  298. {
  299. GPIOWriteFun(idx, val);
  300. }
  301. UINT8 hdmi_gpio_read(UINT8 idx)
  302. {
  303. return GPIOTryRead(idx);
  304. }