blob: 6dbf12bbe9ed69364dcbe2179a896bf9646862e3 [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Po Xu96631f92018-09-16 13:27:44 +08002
Po Xu96631f92018-09-16 13:27:44 +08003#include <assert.h>
Po Xu96631f92018-09-16 13:27:44 +08004#include <delay.h>
Po Xu3f118032020-08-04 11:39:47 +08005#include <device/mmio.h>
Po Xu96631f92018-09-16 13:27:44 +08006#include <soc/addressmap.h>
7#include <soc/auxadc.h>
jg_poxua2c6a092019-05-15 11:36:45 +08008#include <soc/efuse.h>
Po Xu96631f92018-09-16 13:27:44 +08009#include <timer.h>
10
11static struct mtk_auxadc_regs *const mtk_auxadc = (void *)AUXADC_BASE;
12
jg_poxua2c6a092019-05-15 11:36:45 +080013#define ADC_GE_A_SHIFT 10
14#define ADC_GE_A_MASK (0x3ff << ADC_GE_A_SHIFT)
15#define ADC_OE_A_SHIFT 0
16#define ADC_OE_A_MASK (0x3ff << ADC_OE_A_SHIFT)
17#define ADC_CALI_EN_A_SHIFT 20
18#define ADC_CALI_EN_A_MASK (0x1 << ADC_CALI_EN_A_SHIFT)
19
20static int cali_oe;
21static int cali_ge;
22static int calibrated = 0;
23static void mt_auxadc_update_cali(void)
24{
25 uint32_t cali_reg;
26 int cali_ge_a;
27 int cali_oe_a;
28
29 cali_reg = read32(&mtk_efuse->adc_cali_reg);
30
31 if ((cali_reg & ADC_CALI_EN_A_MASK) != 0) {
32 cali_oe_a = (cali_reg & ADC_OE_A_MASK) >> ADC_OE_A_SHIFT;
33 cali_ge_a = (cali_reg & ADC_GE_A_MASK) >> ADC_GE_A_SHIFT;
34 cali_ge = cali_ge_a - 512;
35 cali_oe = cali_oe_a - 512;
36 }
37}
Po Xu3f118032020-08-04 11:39:47 +080038
Po Xu96631f92018-09-16 13:27:44 +080039static uint32_t auxadc_get_rawdata(int channel)
40{
Po Xu3f118032020-08-04 11:39:47 +080041 setbits32(&mtk_infracfg->module_sw_cg_1_clr, 1 << 10);
Julius Werner51325702018-11-02 14:48:24 -070042 assert(wait_ms(300, !(read32(&mtk_auxadc->con2) & 0x1)));
Po Xu96631f92018-09-16 13:27:44 +080043
Julius Werner55009af2019-12-02 22:03:27 -080044 clrbits32(&mtk_auxadc->con1, 1 << channel);
Julius Werner51325702018-11-02 14:48:24 -070045 assert(wait_ms(300, !(read32(&mtk_auxadc->data[channel]) & (1 << 12))));
Po Xu96631f92018-09-16 13:27:44 +080046
Julius Werner55009af2019-12-02 22:03:27 -080047 setbits32(&mtk_auxadc->con1, 1 << channel);
Po Xu96631f92018-09-16 13:27:44 +080048 udelay(25);
Julius Werner51325702018-11-02 14:48:24 -070049 assert(wait_ms(300, read32(&mtk_auxadc->data[channel]) & (1 << 12)));
Po Xu96631f92018-09-16 13:27:44 +080050
51 uint32_t value = read32(&mtk_auxadc->data[channel]) & 0x0FFF;
52
Po Xu3f118032020-08-04 11:39:47 +080053 setbits32(&mtk_infracfg->module_sw_cg_1_set, 1 << 10);
Po Xu96631f92018-09-16 13:27:44 +080054
55 return value;
56}
57
Po Xu3f118032020-08-04 11:39:47 +080058unsigned int auxadc_get_voltage_uv(unsigned int channel)
Po Xu96631f92018-09-16 13:27:44 +080059{
jg_poxua2c6a092019-05-15 11:36:45 +080060 uint32_t raw_value;
Po Xu96631f92018-09-16 13:27:44 +080061 assert(channel < 16);
62
jg_poxua2c6a092019-05-15 11:36:45 +080063 if (!calibrated) {
64 mt_auxadc_update_cali();
65 calibrated = 1;
66 }
67
Po Xu96631f92018-09-16 13:27:44 +080068 /* 1.5V in 4096 steps */
jg_poxua2c6a092019-05-15 11:36:45 +080069 raw_value = auxadc_get_rawdata(channel);
jg_poxua2c6a092019-05-15 11:36:45 +080070 raw_value = raw_value - cali_oe;
Po Xu3f118032020-08-04 11:39:47 +080071 return (unsigned int)((int64_t)raw_value * 1500000 / (4096 + cali_ge));
Po Xu96631f92018-09-16 13:27:44 +080072}