Angel Pons | e67ab18 | 2020-04-04 18:51:11 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 2 | |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 3 | #include <assert.h> |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 4 | #include <delay.h> |
Po Xu | 3f11803 | 2020-08-04 11:39:47 +0800 | [diff] [blame] | 5 | #include <device/mmio.h> |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 6 | #include <soc/addressmap.h> |
| 7 | #include <soc/auxadc.h> |
jg_poxu | a2c6a09 | 2019-05-15 11:36:45 +0800 | [diff] [blame] | 8 | #include <soc/efuse.h> |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 9 | #include <timer.h> |
| 10 | |
| 11 | static struct mtk_auxadc_regs *const mtk_auxadc = (void *)AUXADC_BASE; |
| 12 | |
jg_poxu | a2c6a09 | 2019-05-15 11:36:45 +0800 | [diff] [blame] | 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; |
| 23 | static 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 Xu | 3f11803 | 2020-08-04 11:39:47 +0800 | [diff] [blame] | 38 | |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 39 | static uint32_t auxadc_get_rawdata(int channel) |
| 40 | { |
Po Xu | 3f11803 | 2020-08-04 11:39:47 +0800 | [diff] [blame] | 41 | setbits32(&mtk_infracfg->module_sw_cg_1_clr, 1 << 10); |
Julius Werner | 5132570 | 2018-11-02 14:48:24 -0700 | [diff] [blame] | 42 | assert(wait_ms(300, !(read32(&mtk_auxadc->con2) & 0x1))); |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 43 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 44 | clrbits32(&mtk_auxadc->con1, 1 << channel); |
Julius Werner | 5132570 | 2018-11-02 14:48:24 -0700 | [diff] [blame] | 45 | assert(wait_ms(300, !(read32(&mtk_auxadc->data[channel]) & (1 << 12)))); |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 46 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 47 | setbits32(&mtk_auxadc->con1, 1 << channel); |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 48 | udelay(25); |
Julius Werner | 5132570 | 2018-11-02 14:48:24 -0700 | [diff] [blame] | 49 | assert(wait_ms(300, read32(&mtk_auxadc->data[channel]) & (1 << 12))); |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 50 | |
| 51 | uint32_t value = read32(&mtk_auxadc->data[channel]) & 0x0FFF; |
| 52 | |
Po Xu | 3f11803 | 2020-08-04 11:39:47 +0800 | [diff] [blame] | 53 | setbits32(&mtk_infracfg->module_sw_cg_1_set, 1 << 10); |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 54 | |
| 55 | return value; |
| 56 | } |
| 57 | |
Po Xu | 3f11803 | 2020-08-04 11:39:47 +0800 | [diff] [blame] | 58 | unsigned int auxadc_get_voltage_uv(unsigned int channel) |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 59 | { |
jg_poxu | a2c6a09 | 2019-05-15 11:36:45 +0800 | [diff] [blame] | 60 | uint32_t raw_value; |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 61 | assert(channel < 16); |
| 62 | |
jg_poxu | a2c6a09 | 2019-05-15 11:36:45 +0800 | [diff] [blame] | 63 | if (!calibrated) { |
| 64 | mt_auxadc_update_cali(); |
| 65 | calibrated = 1; |
| 66 | } |
| 67 | |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 68 | /* 1.5V in 4096 steps */ |
jg_poxu | a2c6a09 | 2019-05-15 11:36:45 +0800 | [diff] [blame] | 69 | raw_value = auxadc_get_rawdata(channel); |
jg_poxu | a2c6a09 | 2019-05-15 11:36:45 +0800 | [diff] [blame] | 70 | raw_value = raw_value - cali_oe; |
Po Xu | 3f11803 | 2020-08-04 11:39:47 +0800 | [diff] [blame] | 71 | return (unsigned int)((int64_t)raw_value * 1500000 / (4096 + cali_ge)); |
Po Xu | 96631f9 | 2018-09-16 13:27:44 +0800 | [diff] [blame] | 72 | } |