mtk_auxadc.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2019. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. /*****************************************************************************
  32. *
  33. * Filename:
  34. * ---------
  35. * mtk_auxadc.c
  36. *
  37. * Project:
  38. * --------
  39. * Android_Software
  40. *
  41. * Description:
  42. * ------------
  43. * This Module defines functions of mtk AUXADC
  44. *
  45. * Author:
  46. * -------
  47. * James Lo
  48. *
  49. ****************************************************************************/
  50. #include <stdio.h>
  51. #include <platform/mt_gpt.h>
  52. #include <platform/mtk_auxadc_sw.h>
  53. #include <platform/mtk_auxadc_hw.h>
  54. static s32 cali_oe;
  55. static s32 cali_ge;
  56. static void mt_auxadc_update_cali(void)
  57. {
  58. u32 cali_reg;
  59. u32 cali_ge_a;
  60. u32 cali_oe_a;
  61. cali_reg = (*(unsigned int *const)(ADC_CALI_EN_A_REG));
  62. if (((cali_reg & ADC_CALI_EN_A_MASK) >> ADC_CALI_EN_A_SHIFT) != 0) {
  63. cali_oe_a = (cali_reg & ADC_OE_A_MASK) >> ADC_OE_A_SHIFT;
  64. cali_ge_a = ((cali_reg & ADC_GE_A_MASK) >> ADC_GE_A_SHIFT);
  65. /* In sw implement guide, ge should div 4096. But we don't do that now due to it will multi 4096 later */
  66. cali_ge = cali_ge_a - 512;
  67. cali_oe = cali_oe_a - 512;
  68. dprintf(CRITICAL, "[adc_api]: cali_ge = 0x%x, cali_oe = 0x%x\n", cali_ge, cali_oe);
  69. } else {
  70. cali_oe = 0;
  71. cali_ge = 0;
  72. dprintf(CRITICAL, "[adc_api]: No efuse data");
  73. }
  74. }
  75. static int mt_auxadc_read_raw(int dwChannel, int *rawdata)
  76. {
  77. unsigned int channel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  78. int idle_count = 0;
  79. int data_ready_count = 0;
  80. /* step1 check con2 if auxadc is busy */
  81. while ((*(volatile unsigned short *)AUXADC_CON2) & 0x01) {
  82. dprintf(CRITICAL, "[adc_api]: wait for module idle\n");
  83. udelay(10000);
  84. idle_count++;
  85. if (idle_count > 30) {
  86. //wait for idle time out
  87. dprintf(CRITICAL, "[adc_api]: wait for aux/adc idle time out\n");
  88. return -1;
  89. }
  90. }
  91. /* step2 clear bit */
  92. *(volatile unsigned short *)AUXADC_CON1 = *(volatile unsigned short *)AUXADC_CON1 & (~(1 << dwChannel));
  93. /* step3 read channel and make sure old ready bit == 0 */
  94. while ((*(volatile unsigned short *)(AUXADC_DAT0 + dwChannel * 0x04)) & (1<<12)) {
  95. dprintf(CRITICAL, "[adc_api]: wait for channel[%d] ready bit clear\n", dwChannel);
  96. udelay(10000);
  97. data_ready_count++;
  98. if (data_ready_count > 30) {
  99. dprintf(CRITICAL, "[adc_api]: wait for channel[%d] ready bit clear time out\n", dwChannel);
  100. return -2;
  101. }
  102. }
  103. /* step4 set bit to trigger sample */
  104. *(volatile unsigned short *)AUXADC_CON1 = *(volatile unsigned short *)AUXADC_CON1 | (1 << dwChannel);
  105. /* step5 read channel and make sure ready bit == 1 */
  106. udelay(25); /* we must dealay here for hw sample cahnnel data */
  107. while (0==((*(volatile unsigned short *)(AUXADC_DAT0 + dwChannel * 0x04)) & (1<<12))) {
  108. dprintf(CRITICAL, "[adc_api]: wait for channel[%d] ready bit == 1\n", dwChannel);
  109. udelay(10000);
  110. data_ready_count++;
  111. if (data_ready_count > 30) {
  112. //wait for idle time out
  113. dprintf(CRITICAL, "[adc_api]: wait for channel[%d] data ready time out\n", dwChannel);
  114. return -3;
  115. }
  116. }
  117. /* step6 read data */
  118. channel[dwChannel] = (*(volatile unsigned short *)(AUXADC_DAT0 + dwChannel * 0x04)) & 0x0FFF;
  119. *rawdata = channel[dwChannel];
  120. return 0;
  121. }
  122. int iio_read_channel_processed(int channel, int *val)
  123. {
  124. static bool cali_read = false;
  125. int raw;
  126. int ret;
  127. if (cali_read == false) {
  128. mt_auxadc_update_cali();
  129. cali_read = true;
  130. }
  131. ret = mt_auxadc_read_raw(channel, &raw);
  132. if (ret) {
  133. dprintf(CRITICAL, "[adc_api]:%s get raw value error %d \n", __func__, ret);
  134. return -1;
  135. }
  136. *val = (4096 * (raw - cali_oe)) / (4096 + cali_ge);
  137. /* Convert adc raw data to voltage: 0 - 1500 mV */
  138. *val = *val * 1500 / 4096;
  139. return 0;
  140. }