i2c.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include <string.h>
  2. #include "FreeRTOS.h"
  3. #include "chip.h"
  4. #include "errno.h"
  5. #define MAX_I2C_DEVICE_NUM 4
  6. static struct i2c_adapter *i2c_devs[MAX_I2C_DEVICE_NUM] = {NULL};
  7. static int i2c_devices_count = 0;
  8. int i2c_add_adapter(struct i2c_adapter *adap)
  9. {
  10. if (i2c_devices_count >= MAX_I2C_DEVICE_NUM)
  11. return -1;
  12. /* Set default timeout to 1 second if not already set */
  13. if (adap->timeout == 0)
  14. adap->timeout = configTICK_RATE_HZ;
  15. i2c_devs[i2c_devices_count++] = adap;
  16. return 0;
  17. }
  18. struct i2c_adapter *i2c_open(const char *i2cdev)
  19. {
  20. struct i2c_adapter *adap;
  21. int i;
  22. for (i = 0; i < i2c_devices_count; i++) {
  23. adap = i2c_devs[i];
  24. if (!strcmp(adap->name, i2cdev)) {
  25. adap->open_count++;
  26. if (adap->open_count == 1)
  27. adap->xMutex = xSemaphoreCreateMutex();
  28. return adap;
  29. }
  30. }
  31. return NULL;
  32. }
  33. void i2c_close(struct i2c_adapter *adap)
  34. {
  35. if (adap && --adap->open_count == 0)
  36. vSemaphoreDelete(adap->xMutex);
  37. }
  38. int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
  39. {
  40. unsigned long orig_jiffies;
  41. int ret, try;
  42. configASSERT(adap && msgs);
  43. xSemaphoreTake(adap->xMutex, portMAX_DELAY);
  44. /* Retry automatically on arbitration loss */
  45. orig_jiffies = xTaskGetTickCount();
  46. for (ret = 0, try = 0; try <= adap->retries; try++) {
  47. ret = adap->algo->master_xfer(adap, msgs, num);
  48. if (ret != -EAGAIN)
  49. break;
  50. if (xTaskGetTickCount() > orig_jiffies + adap->timeout)
  51. break;
  52. }
  53. xSemaphoreGive(adap->xMutex);
  54. return ret;
  55. }
  56. int i2c_slave_register(struct i2c_adapter *adap, u8 addr, i2c_slave_cb_t slave_cb)
  57. {
  58. int ret;
  59. if (!adap || !slave_cb)
  60. return -EINVAL;
  61. if (!(adap->flags & I2C_CLIENT_SLAVE))
  62. TRACE_WARNING("%s: client slave flag not set.\n", __func__);
  63. if (!adap->algo->reg_slave) {
  64. printf("%s: not supported by adapter\n", __func__);
  65. return -ENOTSUP;
  66. }
  67. adap->slave_cb = slave_cb;
  68. adap->addr = addr;
  69. ret = adap->algo->reg_slave(adap);
  70. if (ret) {
  71. adap->slave_cb = NULL;
  72. printf("%s: adapter returned error %d\n", __func__, ret);
  73. }
  74. return ret;
  75. }
  76. int i2c_slave_unregister(struct i2c_adapter *adap)
  77. {
  78. int ret;
  79. if (!adap)
  80. return -EINVAL;
  81. if (!adap->algo->unreg_slave) {
  82. printf("%s: not supported by adapter\n", __func__);
  83. return -ENOTSUP;
  84. }
  85. ret = adap->algo->unreg_slave(adap);
  86. if (ret == 0)
  87. adap->slave_cb = NULL;
  88. else
  89. printf("%s: adapter returned error %d\n", __func__, ret);
  90. return ret;
  91. }
  92. void i2c_init(void)
  93. {
  94. #ifdef DW_I2C0_SUPPORT
  95. i2c_dw_init(0);
  96. #endif
  97. #ifdef DW_I2C1_SUPPORT
  98. i2c_dw_init(1);
  99. #endif
  100. #ifdef ANALOG_I2C_SUPPORT
  101. i2c_gpio_init();
  102. #endif
  103. }