dw_iic_ll.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (C) 2017-2020 Alibaba Group Holding Limited
  3. */
  4. #include <common.h>
  5. #include <asm/io.h>
  6. #include <asm/types.h>
  7. #include <linux/bitops.h>
  8. #include "dw_iic_ll.h"
  9. #include <linux/delay.h>
  10. int dw_iic_wait_bus_idle(dw_iic_regs_t *iic_base, uint32_t timeout)
  11. {
  12. /*wait prev iic op is completed*/
  13. int ret = -3;
  14. uint32_t time_out = 0;
  15. while(time_out < timeout) {
  16. if (!(DW_IIC_STATUS_ACTIVITY_STATE & dw_iic_get_iic_state(iic_base))) {
  17. ret = 0;
  18. break;
  19. }
  20. mdelay(1);
  21. time_out++;
  22. }
  23. return ret;
  24. }
  25. void dw_iic_set_target_address(dw_iic_regs_t *iic_base, uint32_t address)
  26. {
  27. uint32_t iic_status;
  28. iic_status = dw_iic_get_iic_status(iic_base);
  29. dw_iic_disable(iic_base);
  30. uint32_t target_address = iic_base->IC_TAR;
  31. target_address &= (DW_IIC_TAR_MASTER_ADDR_MODE | DW_IIC_TAR_SPECIAL | DW_IIC_TAR_GC_OR_START);
  32. target_address |= address;
  33. iic_base->IC_TAR = target_address; /* this register can be written only when the I2C is disabled*/
  34. if (iic_status == DW_IIC_EN) {
  35. dw_iic_enable(iic_base);
  36. }
  37. }
  38. void dw_iic_set_transfer_speed_high(dw_iic_regs_t *iic_base)
  39. {
  40. uint32_t speed_config = iic_base->IC_CON;
  41. speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN);
  42. speed_config |= DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN;
  43. iic_base->IC_CON = speed_config;
  44. }
  45. void dw_iic_set_transfer_speed_fast(dw_iic_regs_t *iic_base)
  46. {
  47. uint32_t speed_config = iic_base->IC_CON;
  48. speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN);
  49. speed_config |= DW_IIC_CON_SPEEDH_EN;
  50. iic_base->IC_CON = speed_config;
  51. }
  52. void dw_iic_set_transfer_speed_standard(dw_iic_regs_t *iic_base)
  53. {
  54. uint32_t speed_config = iic_base->IC_CON;
  55. speed_config &= ~(DW_IIC_CON_SPEEDL_EN | DW_IIC_CON_SPEEDH_EN);
  56. speed_config |= DW_IIC_CON_SPEEDL_EN;
  57. iic_base->IC_CON = speed_config;
  58. }
  59. void dw_iic_set_slave_mode(dw_iic_regs_t *iic_base)
  60. {
  61. uint32_t iic_status;
  62. iic_status = dw_iic_get_iic_status(iic_base);
  63. dw_iic_disable(iic_base);
  64. uint32_t val = DW_IIC_CON_MASTER_EN | DW_IIC_CON_SLAVE_EN;
  65. iic_base->IC_CON &= ~val; ///< set 0 to disabled master mode; set 0 to enabled slave mode
  66. if (iic_status == DW_IIC_EN) {
  67. dw_iic_enable(iic_base);
  68. }
  69. }
  70. void dw_iic_set_master_mode(dw_iic_regs_t *iic_base)
  71. {
  72. uint32_t iic_status;
  73. iic_status = dw_iic_get_iic_status(iic_base);
  74. dw_iic_disable(iic_base);
  75. uint32_t val = DW_IIC_CON_MASTER_EN | DW_IIC_CON_SLAVE_EN; ///< set 1 to enabled master mode; set 1 to disabled slave mode
  76. iic_base->IC_CON |= val;
  77. if (iic_status == DW_IIC_EN) {
  78. dw_iic_enable(iic_base);
  79. }
  80. }
  81. uint32_t dw_iic_find_max_prime_num(uint32_t num)
  82. {
  83. uint32_t i = 0U;
  84. for (i = 8U; i > 0U; i --) {
  85. if (!num) {
  86. i = 1U;
  87. break;
  88. }
  89. if (!(num % i)) {
  90. break;
  91. }
  92. }
  93. return i;
  94. }