1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <assert.h> 4 #include <delay.h> 5 #include <device/mmio.h> 6 #include <soc/addressmap.h> 7 #include <soc/auxadc.h> 8 #include <soc/efuse.h> 9 #include <timer.h> 10 11 static struct mtk_auxadc_regs *const mtk_auxadc = (void *)AUXADC_BASE; 12 13 #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 20 static int cali_oe; 21 static int cali_ge; 22 static int calibrated = 0; mt_auxadc_update_cali(void)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 } 38 auxadc_get_rawdata(int channel)39static uint32_t auxadc_get_rawdata(int channel) 40 { 41 setbits32(&mtk_infracfg->module_sw_cg_1_clr, 1 << 10); 42 assert(wait_ms(300, !(read32(&mtk_auxadc->con2) & 0x1))); 43 44 clrbits32(&mtk_auxadc->con1, 1 << channel); 45 assert(wait_ms(300, !(read32(&mtk_auxadc->data[channel]) & (1 << 12)))); 46 47 setbits32(&mtk_auxadc->con1, 1 << channel); 48 udelay(25); 49 assert(wait_ms(300, read32(&mtk_auxadc->data[channel]) & (1 << 12))); 50 51 uint32_t value = read32(&mtk_auxadc->data[channel]) & 0x0FFF; 52 53 setbits32(&mtk_infracfg->module_sw_cg_1_set, 1 << 10); 54 55 return value; 56 } 57 auxadc_get_voltage_uv(unsigned int channel)58unsigned int auxadc_get_voltage_uv(unsigned int channel) 59 { 60 uint32_t raw_value; 61 assert(channel < 16); 62 63 if (!calibrated) { 64 mt_auxadc_update_cali(); 65 calibrated = 1; 66 } 67 68 /* 1.5V in 4096 steps */ 69 raw_value = auxadc_get_rawdata(channel); 70 raw_value = raw_value - cali_oe; 71 return (unsigned int)((int64_t)raw_value * 1500000 / (4096 + cali_ge)); 72 } 73