rk8xx-i2c.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-11-26 GuEe-GUI first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #define DBG_TAG "mfd.rk8xx-i2c"
  13. #define DBG_LVL DBG_INFO
  14. #include <rtdbg.h>
  15. #include "rk8xx.h"
  16. struct rk8xx_i2c_soc_data
  17. {
  18. int variant;
  19. };
  20. static rt_uint32_t rk8xx_i2c_read(struct rk8xx *rk8xx, rt_uint16_t reg)
  21. {
  22. rt_uint8_t data = 0;
  23. rt_uint8_t send_buf[2];
  24. struct rt_i2c_msg msg[2];
  25. struct rt_i2c_client *client = rk8xx_to_i2c_client(rk8xx);
  26. send_buf[0] = (reg & 0xff);
  27. msg[0].addr = client->client_addr;
  28. msg[0].flags = RT_I2C_WR;
  29. msg[0].len = 1;
  30. msg[0].buf = send_buf;
  31. msg[1].addr = client->client_addr;
  32. msg[1].flags = RT_I2C_RD;
  33. msg[1].len = 1;
  34. msg[1].buf = &data;
  35. if (rt_i2c_transfer(client->bus, msg, 2) == 2)
  36. {
  37. return data;
  38. }
  39. else
  40. {
  41. return (rt_uint32_t)-RT_ERROR;
  42. }
  43. }
  44. static rt_err_t rk8xx_i2c_write(struct rk8xx *rk8xx, rt_uint16_t reg,
  45. rt_uint8_t data)
  46. {
  47. rt_uint8_t send_buf[2];
  48. struct rt_i2c_msg msg;
  49. struct rt_i2c_client *client = rk8xx_to_i2c_client(rk8xx);
  50. send_buf[0] = reg & 0xff;
  51. send_buf[1] = data;
  52. msg.addr = client->client_addr;
  53. msg.flags = RT_I2C_WR;
  54. msg.len = 2;
  55. msg.buf = send_buf;
  56. if (rt_i2c_transfer(client->bus, &msg, 1) == 1)
  57. {
  58. return RT_EOK;
  59. }
  60. else
  61. {
  62. return -RT_ERROR;
  63. }
  64. }
  65. static rt_err_t rk8xx_i2c_update_bits(struct rk8xx *rk8xx, rt_uint16_t reg,
  66. rt_uint8_t mask, rt_uint8_t data)
  67. {
  68. rt_uint32_t old, tmp;
  69. old = rk8xx_i2c_read(rk8xx, reg);
  70. if (old < 0)
  71. {
  72. return old;
  73. }
  74. tmp = old & ~mask;
  75. tmp |= (data & mask);
  76. return rk8xx_i2c_write(rk8xx, reg, tmp);
  77. }
  78. static rt_err_t rk8xx_i2c_probe(struct rt_i2c_client *client)
  79. {
  80. rt_err_t err;
  81. const struct rk8xx_i2c_soc_data *soc_data;
  82. struct rk8xx *rk8xx = rt_calloc(1, sizeof(*rk8xx));
  83. if (!rk8xx)
  84. {
  85. return -RT_ENOMEM;
  86. }
  87. rk8xx->irq = rt_dm_dev_get_irq(&client->parent, 0);
  88. if (rk8xx->irq < 0)
  89. {
  90. err = rk8xx->irq;
  91. goto _fail;
  92. }
  93. soc_data = client->ofw_id->data;
  94. client->parent.user_data = rk8xx;
  95. rk8xx->variant = soc_data->variant;
  96. rk8xx->dev = &client->parent;
  97. rk8xx->read = rk8xx_i2c_read;
  98. rk8xx->write = rk8xx_i2c_write;
  99. rk8xx->update_bits = rk8xx_i2c_update_bits;
  100. if ((err = rk8xx_probe(rk8xx)))
  101. {
  102. goto _fail;
  103. }
  104. return RT_EOK;
  105. _fail:
  106. rt_free(rk8xx);
  107. return err;
  108. }
  109. static rt_err_t rk8xx_i2c_shutdown(struct rt_i2c_client *client)
  110. {
  111. struct rk8xx *rk8xx = client->parent.user_data;
  112. return rk8xx_shutdown(rk8xx);
  113. }
  114. static const struct rk8xx_i2c_soc_data rk805_data =
  115. {
  116. .variant = RK805_ID,
  117. };
  118. static const struct rk8xx_i2c_soc_data rk808_data =
  119. {
  120. .variant = RK808_ID,
  121. };
  122. static const struct rk8xx_i2c_soc_data rk809_data =
  123. {
  124. .variant = RK809_ID,
  125. };
  126. static const struct rk8xx_i2c_soc_data rk817_data =
  127. {
  128. .variant = RK817_ID,
  129. };
  130. static const struct rk8xx_i2c_soc_data rk818_data =
  131. {
  132. .variant = RK818_ID,
  133. };
  134. static const struct rt_ofw_node_id rk8xx_i2c_ofw_ids[] =
  135. {
  136. { .compatible = "rockchip,rk805", .data = &rk805_data },
  137. { .compatible = "rockchip,rk808", .data = &rk808_data },
  138. { .compatible = "rockchip,rk809", .data = &rk809_data },
  139. { .compatible = "rockchip,rk817", .data = &rk817_data },
  140. { .compatible = "rockchip,rk818", .data = &rk818_data },
  141. { /* sentinel */ },
  142. };
  143. static struct rt_i2c_driver rk8xx_i2c_driver =
  144. {
  145. .ofw_ids = rk8xx_i2c_ofw_ids,
  146. .probe = rk8xx_i2c_probe,
  147. .shutdown = rk8xx_i2c_shutdown,
  148. };
  149. RT_I2C_DRIVER_EXPORT(rk8xx_i2c_driver);