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 }