1 #include "bflb_adc.h"
2 #include "bflb_efuse.h"
3 #include "hardware/adc_reg.h"
4 
5 #if defined(BL702) || defined(BL602) || defined(BL702L)
6 #define ADC_GPIP_BASE ((uint32_t)0x40002000)
7 #elif defined(BL616) || defined(BL606P) || defined(BL808) || defined(BL628)
8 #define ADC_GPIP_BASE ((uint32_t)0x20002000)
9 #endif
10 
11 volatile float coe = 1.0;
12 volatile uint32_t tsen_offset;
13 
bflb_adc_init(struct bflb_device_s * dev,const struct bflb_adc_config_s * config)14 void bflb_adc_init(struct bflb_device_s *dev, const struct bflb_adc_config_s *config)
15 {
16     uint32_t regval;
17     uint32_t reg_base;
18 
19     reg_base = dev->reg_base;
20 
21     /* adc disable */
22     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
23     regval &= ~AON_GPADC_GLOBAL_EN;
24     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
25 
26     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
27     regval |= AON_GPADC_GLOBAL_EN;
28     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
29 
30     /* adc reset */
31     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
32     regval |= AON_GPADC_SOFT_RST;
33     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
34 
35     __asm volatile("nop");
36     __asm volatile("nop");
37     __asm volatile("nop");
38     __asm volatile("nop");
39     __asm volatile("nop");
40     __asm volatile("nop");
41     __asm volatile("nop");
42     __asm volatile("nop");
43 
44     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
45     regval &= ~AON_GPADC_SOFT_RST;
46     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
47 
48     /* disable int and clear status */
49     regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
50     regval |= (GPIP_GPADC_FIFO_UNDERRUN_MASK | GPIP_GPADC_FIFO_OVERRUN_MASK | GPIP_GPADC_RDY_MASK |
51                GPIP_GPADC_FIFO_UNDERRUN_CLR | GPIP_GPADC_FIFO_OVERRUN_CLR | GPIP_GPADC_RDY_CLR);
52 
53 #if defined(BL702) || defined(BL702L)
54     regval |= (GPIP_GPADC_FIFO_RDY_MASK | GPIP_GPADC_FIFO_RDY);
55 #endif
56     regval |= GPIP_GPADC_FIFO_CLR;
57     regval &= ~GPIP_GPADC_FIFO_THL_MASK;
58     regval &= ~GPIP_GPADC_DMA_EN;
59     putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
60 
61     bflb_adc_start_conversion(dev);
62     bflb_mtimer_delay_ms(1);
63     bflb_adc_stop_conversion(dev);
64 
65     regval = 0;
66     regval |= (2 << AON_GPADC_V18_SEL_SHIFT);                     /* V18 select 1.82V */
67     regval |= (1 << AON_GPADC_V11_SEL_SHIFT);                     /* V11 select 1.1V */
68     regval |= (config->clk_div << AON_GPADC_CLK_DIV_RATIO_SHIFT); /* clock div */
69     regval |= (config->resolution << AON_GPADC_RES_SEL_SHIFT);    /* resolution */
70     if (config->scan_conv_mode) {
71         regval |= AON_GPADC_SCAN_EN;
72         regval |= AON_GPADC_CLK_ANA_INV;
73     }
74     if (config->continuous_conv_mode) {
75         regval |= AON_GPADC_CONT_CONV_EN;
76     }
77 
78     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG1_OFFSET);
79 
80     __asm volatile("nop");
81     __asm volatile("nop");
82     __asm volatile("nop");
83     __asm volatile("nop");
84     __asm volatile("nop");
85     __asm volatile("nop");
86     __asm volatile("nop");
87     __asm volatile("nop");
88 
89     regval = 0;
90     regval |= (2 << AON_GPADC_DLY_SEL_SHIFT);
91     regval |= (2 << AON_GPADC_CHOP_MODE_SHIFT); /* Vref AZ and PGA chop on */
92     regval |= (1 << AON_GPADC_PGA1_GAIN_SHIFT); /* gain 1 */
93     regval |= (1 << AON_GPADC_PGA2_GAIN_SHIFT); /* gain 1 */
94     regval |= AON_GPADC_PGA_EN;
95     regval |= (8 << AON_GPADC_PGA_OS_CAL_SHIFT);
96     regval |= (1 << AON_GPADC_PGA_VCM_SHIFT); /* PGA output common mode control 1.4V */
97 
98     if (config->vref == ADC_VREF_2P0V) {
99         regval |= AON_GPADC_VREF_SEL;
100     }
101 
102     if (config->differential_mode) {
103         regval |= AON_GPADC_DIFF_MODE;
104     }
105 
106     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
107 
108     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
109     regval |= AON_GPADC_MIC2_DIFF; /* mic2 diff enable */
110     if (config->differential_mode) {
111         regval &= ~AON_GPADC_NEG_GND;
112     } else {
113         regval |= AON_GPADC_NEG_GND;
114     }
115     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
116 
117     /* calibration offset */
118     regval = getreg32(reg_base + AON_GPADC_REG_DEFINE_OFFSET);
119     regval &= ~AON_GPADC_OS_CAL_DATA_MASK;
120     putreg32(regval, reg_base + AON_GPADC_REG_DEFINE_OFFSET);
121 
122     /* disable int and clear status */
123     regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
124     regval |= (GPIP_GPADC_FIFO_UNDERRUN_MASK | GPIP_GPADC_FIFO_OVERRUN_MASK | GPIP_GPADC_RDY_MASK |
125                GPIP_GPADC_FIFO_UNDERRUN_CLR | GPIP_GPADC_FIFO_OVERRUN_CLR | GPIP_GPADC_RDY_CLR);
126 
127 #if defined(BL702) || defined(BL702L)
128     regval |= (GPIP_GPADC_FIFO_RDY_MASK | GPIP_GPADC_FIFO_RDY);
129 #endif
130     regval |= GPIP_GPADC_FIFO_CLR;
131     regval &= ~GPIP_GPADC_FIFO_THL_MASK;
132     regval &= ~GPIP_GPADC_DMA_EN;
133     putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
134 
135     regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
136     regval &= ~(GPIP_GPADC_FIFO_UNDERRUN_CLR |
137                 GPIP_GPADC_FIFO_OVERRUN_CLR |
138                 GPIP_GPADC_RDY_CLR |
139                 GPIP_GPADC_FIFO_CLR);
140     putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
141 
142     regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
143     regval |= AON_GPADC_NEG_SATUR_MASK;
144     regval |= AON_GPADC_POS_SATUR_MASK;
145     putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
146 
147     coe = bflb_efuse_get_adc_trim();              /* read from efuse */
148     tsen_offset = bflb_efuse_get_adc_tsen_trim(); /* read from efuse */
149 }
150 
bflb_adc_deinit(struct bflb_device_s * dev)151 void bflb_adc_deinit(struct bflb_device_s *dev)
152 {
153     uint32_t regval;
154     uint32_t reg_base;
155 
156     reg_base = dev->reg_base;
157 
158     /* adc disable */
159     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
160     regval &= ~AON_GPADC_GLOBAL_EN;
161     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
162 
163     /* adc reset */
164     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
165     regval |= AON_GPADC_SOFT_RST;
166     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
167 
168     __asm volatile("nop");
169     __asm volatile("nop");
170     __asm volatile("nop");
171     __asm volatile("nop");
172     __asm volatile("nop");
173     __asm volatile("nop");
174     __asm volatile("nop");
175     __asm volatile("nop");
176 
177     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
178     regval &= ~AON_GPADC_SOFT_RST;
179     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
180 
181     putreg32(0, reg_base + AON_GPADC_REG_CONFIG1_OFFSET);
182     putreg32(0, reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
183 }
184 
bflb_adc_link_rxdma(struct bflb_device_s * dev,bool enable)185 void bflb_adc_link_rxdma(struct bflb_device_s *dev, bool enable)
186 {
187     uint32_t regval;
188 
189     regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
190     if (enable) {
191         regval |= GPIP_GPADC_DMA_EN;
192     } else {
193         regval &= ~GPIP_GPADC_DMA_EN;
194     }
195     putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
196 }
197 
bflb_adc_channel_config(struct bflb_device_s * dev,struct bflb_adc_channel_s * chan,uint8_t channels)198 int bflb_adc_channel_config(struct bflb_device_s *dev, struct bflb_adc_channel_s *chan, uint8_t channels)
199 {
200     uint32_t regval;
201     uint32_t regval2;
202     uint32_t reg_base;
203 
204     reg_base = dev->reg_base;
205 
206     if (!(getreg32(reg_base + AON_GPADC_REG_CONFIG1_OFFSET) & AON_GPADC_SCAN_EN)) {
207         if (channels > 1) {
208             return -EINVAL;
209         }
210 
211         regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
212         regval &= ~AON_GPADC_POS_SEL_MASK;
213         regval &= ~AON_GPADC_NEG_SEL_MASK;
214         regval |= (chan->pos_chan << AON_GPADC_POS_SEL_SHIFT);
215         regval |= (chan->neg_chan << AON_GPADC_NEG_SEL_SHIFT);
216         putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
217     } else {
218         if (channels < 6) {
219             regval = 0;
220             regval2 = 0;
221             for (uint8_t i = 0; i < channels; i++) {
222                 regval |= (chan[i].pos_chan << (i * 5));
223                 regval2 |= (chan[i].neg_chan << (i * 5));
224             }
225             putreg32(regval, reg_base + AON_GPADC_REG_SCN_POS1_OFFSET);
226             putreg32(regval2, reg_base + AON_GPADC_REG_SCN_NEG1_OFFSET);
227         } else {
228             regval = 0;
229             regval2 = 0;
230             for (uint8_t i = 0; i < 6; i++) {
231                 regval |= (chan[i].pos_chan << (i * 5));
232                 regval2 |= (chan[i].neg_chan << (i * 5));
233             }
234             putreg32(regval, reg_base + AON_GPADC_REG_SCN_POS1_OFFSET);
235             putreg32(regval2, reg_base + AON_GPADC_REG_SCN_NEG1_OFFSET);
236 
237             regval = 0;
238             regval2 = 0;
239             for (uint8_t i = 0; i < (channels - 6); i++) {
240                 regval |= (chan[i + 6].pos_chan << (i * 5));
241                 regval2 |= (chan[i + 6].neg_chan << (i * 5));
242             }
243             putreg32(regval, reg_base + AON_GPADC_REG_SCN_POS2_OFFSET);
244             putreg32(regval2, reg_base + AON_GPADC_REG_SCN_NEG2_OFFSET);
245         }
246 
247         regval = getreg32(reg_base + AON_GPADC_REG_CONFIG1_OFFSET);
248         regval &= ~AON_GPADC_SCAN_LENGTH_MASK;
249         regval |= ((channels - 1) << AON_GPADC_SCAN_LENGTH_SHIFT);
250         putreg32(regval, reg_base + AON_GPADC_REG_CONFIG1_OFFSET);
251     }
252     return 0;
253 }
254 
bflb_adc_start_conversion(struct bflb_device_s * dev)255 void bflb_adc_start_conversion(struct bflb_device_s *dev)
256 {
257     uint32_t regval;
258     uint32_t reg_base;
259 
260     reg_base = dev->reg_base;
261 
262     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
263     regval &= ~AON_GPADC_CONV_START;
264     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
265 
266     bflb_mtimer_delay_us(100);
267 
268     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
269     regval |= AON_GPADC_CONV_START;
270     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
271 }
272 
bflb_adc_stop_conversion(struct bflb_device_s * dev)273 void bflb_adc_stop_conversion(struct bflb_device_s *dev)
274 {
275     uint32_t regval;
276     uint32_t reg_base;
277 
278     reg_base = dev->reg_base;
279     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
280     regval &= ~AON_GPADC_CONV_START;
281     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
282 }
283 
bflb_adc_get_count(struct bflb_device_s * dev)284 uint8_t bflb_adc_get_count(struct bflb_device_s *dev)
285 {
286     return ((getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET) & GPIP_GPADC_FIFO_DATA_COUNT_MASK) >> GPIP_GPADC_FIFO_DATA_COUNT_SHIFT);
287 }
288 
bflb_adc_read_raw(struct bflb_device_s * dev)289 uint32_t bflb_adc_read_raw(struct bflb_device_s *dev)
290 {
291     return getreg32(ADC_GPIP_BASE + GPIP_GPADC_DMA_RDATA_OFFSET) & GPIP_GPADC_DMA_RDATA_MASK;
292 }
293 
bflb_adc_rxint_mask(struct bflb_device_s * dev,bool mask)294 void bflb_adc_rxint_mask(struct bflb_device_s *dev, bool mask)
295 {
296     uint32_t regval;
297 
298     regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
299     if (mask) {
300         regval |= GPIP_GPADC_RDY_MASK;
301     } else {
302         regval &= ~GPIP_GPADC_RDY_MASK;
303     }
304     putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
305 }
306 
bflb_adc_errint_mask(struct bflb_device_s * dev,bool mask)307 void bflb_adc_errint_mask(struct bflb_device_s *dev, bool mask)
308 {
309     uint32_t regval;
310     uint32_t regval2;
311     uint32_t reg_base;
312 
313     reg_base = dev->reg_base;
314 
315     regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
316     regval2 = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
317 
318     if (mask) {
319         regval |= AON_GPADC_POS_SATUR_MASK;
320         regval |= AON_GPADC_NEG_SATUR_MASK;
321         regval2 |= GPIP_GPADC_FIFO_UNDERRUN_MASK;
322         regval2 |= GPIP_GPADC_FIFO_OVERRUN_MASK;
323     } else {
324         regval &= ~AON_GPADC_POS_SATUR_MASK;
325         regval &= ~AON_GPADC_NEG_SATUR_MASK;
326         regval2 &= ~GPIP_GPADC_FIFO_UNDERRUN_MASK;
327         regval2 &= ~GPIP_GPADC_FIFO_OVERRUN_MASK;
328     }
329     putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
330     putreg32(regval2, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
331 }
332 
bflb_adc_get_intstatus(struct bflb_device_s * dev)333 uint32_t bflb_adc_get_intstatus(struct bflb_device_s *dev)
334 {
335     uint32_t reg_base;
336     uint32_t regval = 0;
337 
338     reg_base = dev->reg_base;
339 
340     if (getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET) & AON_GPADC_NEG_SATUR) {
341         regval |= ADC_INTSTS_NEG_SATURATION;
342     }
343     if (getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET) & AON_GPADC_POS_SATUR) {
344         regval |= ADC_INTSTS_POS_SATURATION;
345     }
346     if (getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET) & GPIP_GPADC_FIFO_UNDERRUN) {
347         regval |= ADC_INTSTS_FIFO_UNDERRUN;
348     }
349     if (getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET) & GPIP_GPADC_FIFO_OVERRUN) {
350         regval |= ADC_INTSTS_FIFO_OVERRUN;
351     }
352     if (getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET) & GPIP_GPADC_RDY) {
353         regval |= ADC_INTSTS_ADC_READY;
354     }
355     return regval;
356 }
357 
bflb_adc_int_clear(struct bflb_device_s * dev,uint32_t int_clear)358 void bflb_adc_int_clear(struct bflb_device_s *dev, uint32_t int_clear)
359 {
360     uint32_t regval;
361     uint32_t reg_base;
362 
363     reg_base = dev->reg_base;
364 
365     if (int_clear & ADC_INTCLR_NEG_SATURATION) {
366         regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
367         regval &= ~AON_GPADC_NEG_SATUR_CLR;
368         putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
369 
370         regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
371         regval |= AON_GPADC_NEG_SATUR_CLR;
372         putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
373 
374         regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
375         regval &= ~AON_GPADC_NEG_SATUR_CLR;
376         putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
377     }
378     if (int_clear & ADC_INTCLR_POS_SATURATION) {
379         regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
380         regval &= ~AON_GPADC_POS_SATUR_CLR;
381         putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
382 
383         regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
384         regval |= AON_GPADC_POS_SATUR_CLR;
385         putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
386 
387         regval = getreg32(reg_base + AON_GPADC_REG_ISR_OFFSET);
388         regval &= ~AON_GPADC_POS_SATUR_CLR;
389         putreg32(regval, reg_base + AON_GPADC_REG_ISR_OFFSET);
390     }
391     if (int_clear & ADC_INTCLR_FIFO_UNDERRUN) {
392         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
393         regval &= ~GPIP_GPADC_FIFO_UNDERRUN_CLR;
394         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
395 
396         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
397         regval |= GPIP_GPADC_FIFO_UNDERRUN_CLR;
398         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
399 
400         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
401         regval &= ~GPIP_GPADC_FIFO_UNDERRUN_CLR;
402         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
403     }
404     if (int_clear & ADC_INTCLR_FIFO_OVERRUN) {
405         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
406         regval &= ~GPIP_GPADC_FIFO_OVERRUN_CLR;
407         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
408 
409         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
410         regval |= GPIP_GPADC_FIFO_OVERRUN_CLR;
411         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
412 
413         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
414         regval &= ~GPIP_GPADC_FIFO_OVERRUN_CLR;
415         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
416     }
417     if (int_clear & ADC_INTCLR_ADC_READY) {
418         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
419         regval &= ~GPIP_GPADC_RDY_CLR;
420         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
421 
422         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
423         regval |= GPIP_GPADC_RDY_CLR;
424         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
425 
426         regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
427         regval &= ~GPIP_GPADC_RDY_CLR;
428         putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
429     }
430 }
431 
bflb_adc_parse_result(struct bflb_device_s * dev,uint32_t * buffer,struct bflb_adc_result_s * result,uint16_t count)432 void bflb_adc_parse_result(struct bflb_device_s *dev, uint32_t *buffer, struct bflb_adc_result_s *result, uint16_t count)
433 {
434     uint32_t reg_base;
435     uint8_t resolution;
436     uint8_t diff_mode;
437     uint8_t vref;
438     uint32_t conv_result = 0;
439     uint16_t ref = 3200;
440     uint8_t neg = 0;
441     uint32_t tmp;
442 
443     reg_base = dev->reg_base;
444 
445     resolution = (getreg32(reg_base + AON_GPADC_REG_CONFIG1_OFFSET) & AON_GPADC_RES_SEL_MASK) >> AON_GPADC_RES_SEL_SHIFT;
446     diff_mode = (getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET) & AON_GPADC_DIFF_MODE) >> 2;
447     vref = (getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET) & AON_GPADC_VREF_SEL) >> 3;
448 
449     if (vref == ADC_VREF_2P0V) {
450         ref = 2000;
451     }
452 
453     /* single mode */
454     if (diff_mode == 0) {
455         for (uint16_t i = 0; i < count; i++) {
456             result[i].pos_chan = buffer[i] >> 21;
457             result[i].neg_chan = -1;
458 
459             if (resolution == ADC_RESOLUTION_12B) {
460                 conv_result = (uint32_t)(((buffer[i] & 0xffff) >> 4) / coe);
461                 if (conv_result > 4095) {
462                     conv_result = 4095;
463                 }
464                 result[i].value = conv_result;
465                 result[i].millivolt = (float)result[i].value / 4096 * ref;
466             } else if (resolution == ADC_RESOLUTION_14B) {
467                 conv_result = (uint32_t)(((buffer[i] & 0xffff) >> 2) / coe);
468                 if (conv_result > 16383) {
469                     conv_result = 16383;
470                 }
471                 result[i].value = conv_result;
472                 result[i].millivolt = (float)result[i].value / 16384 * ref;
473             } else if (resolution == ADC_RESOLUTION_16B) {
474                 conv_result = (uint32_t)((buffer[i] & 0xffff) / coe);
475                 if (conv_result > 65535) {
476                     conv_result = 65535;
477                 }
478                 result[i].value = conv_result;
479                 result[i].millivolt = (int32_t)result[i].value / 65536.0 * ref;
480             } else {
481             }
482         }
483     } else {
484         for (uint16_t i = 0; i < count; i++) {
485             result[i].pos_chan = buffer[i] >> 21;
486             result[i].neg_chan = (buffer[i] >> 16) & 0x1F;
487 
488             tmp = buffer[i];
489 
490             if (tmp & 0x8000) {
491                 tmp = ~tmp;
492                 tmp += 1;
493                 neg = 1;
494             }
495 
496             if (resolution == ADC_RESOLUTION_12B) {
497                 conv_result = (uint32_t)(((tmp & 0xffff) >> 4) / coe);
498                 if (conv_result > 2047) {
499                     conv_result = 2047;
500                 }
501                 result[i].value = conv_result;
502                 result[i].millivolt = (float)result[i].value / 2048 * ref;
503             } else if (resolution == ADC_RESOLUTION_14B) {
504                 conv_result = (uint32_t)(((tmp & 0xffff) >> 2) / coe);
505                 if (conv_result > 8191) {
506                     conv_result = 8191;
507                 }
508                 result[i].value = conv_result;
509                 result[i].millivolt = (float)result[i].value / 8192 * ref;
510             } else if (resolution == ADC_RESOLUTION_16B) {
511                 conv_result = (uint32_t)((tmp & 0xffff) / coe);
512                 if (conv_result > 32767) {
513                     conv_result = 32767;
514                 }
515                 result[i].value = conv_result;
516                 result[i].millivolt = (float)result[i].value / 32768 * ref;
517             } else {
518             }
519 
520             if (neg) {
521                 result[i].value = -result[i].value;
522                 result[i].millivolt = -result[i].millivolt;
523             }
524         }
525     }
526 }
527 
bflb_adc_tsen_init(struct bflb_device_s * dev,uint8_t tsen_mod)528 void bflb_adc_tsen_init(struct bflb_device_s *dev, uint8_t tsen_mod)
529 {
530     uint32_t regval;
531     uint32_t reg_base;
532     reg_base = dev->reg_base;
533 
534     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
535     regval &= ~AON_GPADC_SEN_TEST_EN;
536     regval |= (0 << AON_GPADC_SEN_SEL_SHIFT);
537     regval &= ~AON_GPADC_CHIP_SEN_PU;
538     regval |= AON_GPADC_DWA_EN;
539     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
540 
541     regval = getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
542     regval &= ~AON_GPADC_TSVBE_LOW;
543     regval |= (2 << AON_GPADC_DLY_SEL_SHIFT);
544     regval |= (0 << AON_GPADC_TEST_SEL_SHIFT);
545     regval &= ~AON_GPADC_TEST_EN;
546     regval |= AON_GPADC_TS_EN;
547     if (tsen_mod) {
548         regval |= AON_GPADC_TSEXT_SEL;
549     } else {
550         regval &= ~AON_GPADC_TSEXT_SEL;
551     }
552     regval |= (2 << AON_GPADC_PGA_VCM_SHIFT);
553     regval &= ~AON_GPADC_PGA_VCMI_EN;
554     regval |= (0 << AON_GPADC_PGA_OS_CAL_SHIFT);
555     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
556 
557     regval = getreg32(reg_base + AON_GPADC_REG_CONFIG1_OFFSET);
558     regval |= AON_GPADC_DITHER_EN;
559     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG1_OFFSET);
560 
561     regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET);
562     regval |= AON_GPADC_MIC2_DIFF;
563     putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET);
564 }
565 
bflb_adc_tsen_get_temp(struct bflb_device_s * dev)566 float bflb_adc_tsen_get_temp(struct bflb_device_s *dev)
567 {
568     uint32_t regval;
569     uint32_t reg_base;
570     struct bflb_adc_result_s result;
571     uint32_t v0 = 0, v1 = 0;
572     float temp = 0;
573     uint32_t raw_data;
574     uint64_t start_time;
575 
576     reg_base = dev->reg_base;
577 
578     regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
579     regval |= (0 << 22);
580     regval |= GPIP_GPADC_FIFO_CLR;
581     putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
582 
583     regval = getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
584     regval &= ~AON_GPADC_TSVBE_LOW;
585     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
586 
587     bflb_adc_start_conversion(dev);
588     start_time = bflb_mtimer_get_time_ms();
589     while (bflb_adc_get_count(dev) == 0) {
590         if ((bflb_mtimer_get_time_ms() - start_time) > 100) {
591             return -ETIMEDOUT;
592         }
593     }
594     raw_data = bflb_adc_read_raw(dev);
595     bflb_adc_parse_result(dev, &raw_data, &result, 1);
596     v0 = result.value;
597     regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
598     regval |= GPIP_GPADC_FIFO_CLR;
599     putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET);
600 
601     regval = getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
602     regval |= AON_GPADC_TSVBE_LOW;
603     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
604 
605     bflb_adc_start_conversion(dev);
606     start_time = bflb_mtimer_get_time_ms();
607     while (bflb_adc_get_count(dev) == 0) {
608         if ((bflb_mtimer_get_time_ms() - start_time) > 100) {
609             return -ETIMEDOUT;
610         }
611     }
612     raw_data = bflb_adc_read_raw(dev);
613     bflb_adc_parse_result(dev, &raw_data, &result, 1);
614     v1 = result.value;
615     if (v0 > v1) {
616         temp = (((float)v0 - (float)v1) - (float)tsen_offset) / 7.753;
617     } else {
618         temp = (((float)v1 - (float)v0) - (float)tsen_offset) / 7.753;
619     }
620 
621     return temp;
622 }
623 
bflb_adc_vbat_enable(struct bflb_device_s * dev)624 void bflb_adc_vbat_enable(struct bflb_device_s *dev)
625 {
626     uint32_t regval;
627     uint32_t reg_base;
628 
629     reg_base = dev->reg_base;
630 
631     regval = getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
632     regval |= AON_GPADC_VBAT_EN;
633     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
634 }
635 
bflb_adc_vbat_disable(struct bflb_device_s * dev)636 void bflb_adc_vbat_disable(struct bflb_device_s *dev)
637 {
638     uint32_t regval;
639     uint32_t reg_base;
640 
641     reg_base = dev->reg_base;
642 
643     regval = getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
644     regval &= ~AON_GPADC_VBAT_EN;
645     putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET);
646 }