1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "adc_drv.h"
17
18 #include <hi_boot_rom.h>
19
adc_fifo_is_empty(hi_void)20 hi_bool adc_fifo_is_empty(hi_void)
21 {
22 hi_u32 reg_val = hi_reg_read_val32(REG_ADC_SR);
23 if (reg_val & ADC_SR_RNE) {
24 return HI_FALSE;
25 }
26 return HI_TRUE;
27 }
28
adc_scan_stop(hi_void)29 hi_void adc_scan_stop(hi_void)
30 {
31 hi_reg_write(REG_ADC_STOP, ADC_SCAN_STOP);
32 hi_reg_write(REG_ADC_IMSC, ADC_ISR_DISABLE);
33 while (adc_fifo_is_empty() == HI_FALSE) {
34 (hi_void)hi_reg_read_val32(REG_ADC_DR);
35 }
36 }
37
38 #define hi_reg_getbits16(addr, pos, bits) ((hi_reg_read_val16(addr) >> (pos)) & (((unsigned short)1 << (bits)) - 1))
39 #define GLB_CTL_REFCLK_FEQ_START_BIT 0
40 #define GLB_CTL_REFCLK_FEQ_BITS 1
41
42
get_ref_voltage(hi_u16 * voltage)43 hi_u32 get_ref_voltage(hi_u16 *voltage)
44 {
45 hi_u16 data = 0;
46 hi_u16 reg_val;
47 hi_u16 timeout_cnt = 0;
48 /* set adc clk div */
49 hi_reg_read16(LS_ADC_CLK_DIV1_REG, reg_val);
50 reg_val &= ~(0xF << LS_ADC_CLK_DIV1_OFFSET);
51 if (hi_reg_getbits16(GLB_CTL_REFCLK_FEQ_STATUS_REG, GLB_CTL_REFCLK_FEQ_START_BIT, GLB_CTL_REFCLK_FEQ_BITS)) {
52 reg_val |= (0x7 << LS_ADC_CLK_DIV1_OFFSET);
53 } else {
54 reg_val |= (0xC << LS_ADC_CLK_DIV1_OFFSET);
55 }
56 hi_reg_write16(LS_ADC_CLK_DIV1_REG, reg_val);
57 /* adc power on */
58 hi_reg_write(REG_ADC_EN, ADC_POWER_OFF);
59 udelay(1);
60 hi_reg_write(REG_ADC_EN, ADC_POWER_ON);
61 /* set basic info */
62 /*
63 channel: 0x80 << 0
64 equ_model_sel: 0x2 << 8
65 rst_cnt: 0xF << 12
66 adc_cfg->cur_bais: 0 << 24
67 fifo_water_line: 0x6
68 */
69 hi_reg_write(REG_ADC_CFG, 0xf280); /* 0xf280 */
70 hi_reg_write(REG_ADC_FIFO_CFG, 0x6);
71 /* determine is busy */
72 if (hi_reg_read_val32(REG_ADC_SR) & ADC_SR_BSY) {
73 adc_scan_stop();
74 }
75 /* start scan */
76 hi_reg_write(REG_ADC_START, ADC_SCAN_START);
77 while (timeout_cnt < ADC_PER_DATA_TIMEOUT_CNT) {
78 if (!adc_fifo_is_empty()) {
79 data = (hi_u16)hi_reg_read_val32(REG_ADC_DR);
80 break;
81 }
82 timeout_cnt++;
83 udelay(ADC_LOOP_DELAY_US);
84 }
85 adc_scan_stop();
86 hi_reg_write(REG_ADC_EN, ADC_POWER_OFF); /* POWER DOWN */
87 if (timeout_cnt >= ADC_PER_DATA_TIMEOUT_CNT) {
88 return HI_ERR_TIMEOUT;
89 }
90 data = data & 0xFFF; /* 0xFFF Obtains the lower 12 bits */
91 *voltage = ((hi_u32)data * 180) >> 10; /* bypass:180, flashLDO: 171 = 180*0.95,coefficients:10 Units: 0.01V */
92 return HI_ERR_SUCCESS;
93 }
94
get_average_ref_vlt(hi_u16 * voltage)95 hi_u32 get_average_ref_vlt(hi_u16 *voltage)
96 {
97 hi_u32 ret;
98 hi_u16 vlt;
99 hi_u32 vlt_total = 0;
100 ret = get_ref_voltage(&vlt);
101 if (ret != HI_ERR_SUCCESS) {
102 return ret;
103 }
104 vlt_total += vlt;
105 ret = get_ref_voltage(&vlt);
106 if (ret != HI_ERR_SUCCESS) {
107 *voltage = (hi_u16) vlt_total;
108 return HI_ERR_SUCCESS;
109 }
110 vlt_total += vlt;
111 ret = get_ref_voltage(&vlt);
112 if (ret != HI_ERR_SUCCESS) {
113 *voltage = (hi_u16) (vlt_total>>1);
114 return HI_ERR_SUCCESS;
115 }
116 vlt_total += vlt;
117 *voltage = (hi_u16) ((vlt_total) / 3); /* 3 */
118 return HI_ERR_SUCCESS;
119 }