• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }