1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <device/mmio.h> 4 #include <assert.h> 5 #include <delay.h> 6 #include <soc/clock.h> 7 #include <soc/saradc.h> 8 #include <stdint.h> 9 #include <timer.h> 10 11 struct rk3399_saradc_regs { 12 u32 data; 13 u32 stas; 14 u32 ctrl; 15 u32 dly_pu_soc; 16 }; 17 check_member(rk3399_saradc_regs, dly_pu_soc, 0xc); 18 19 struct rk3399_saradc_regs *rk3399_saradc = (void *)SARADC_BASE; 20 21 /* SARADC_STAS: conversion done */ 22 #define ADC_STOP 0 23 24 /* SARADC_CTRL */ 25 #define INT_EN (1 << 5) 26 #define ADC_PWR_CTRL (1 << 3) 27 #define ADC_CHN_SEL_MASK 7 28 #define ADC_CHN_SEL_SHIFT 0 29 30 /* SARADC_DATA, 10[0:9] bits */ 31 #define DATA_MASK 0x3FF 32 33 #define SARADC_HZ (4*MHz) 34 35 #define SARADC_MAX_CHANNEL 6 36 37 #define SARADC_DELAY_PU (1 * 1000 * 1000 * 1000 / SARADC_HZ * 4) 38 get_saradc_value(u32 chn)39u32 get_saradc_value(u32 chn) 40 { 41 u32 adc_value; 42 struct stopwatch sw; 43 44 assert(chn < SARADC_MAX_CHANNEL); 45 rkclk_configure_saradc(SARADC_HZ); 46 47 /* power down adc converter */ 48 clrbits32(&rk3399_saradc->ctrl, ADC_PWR_CTRL); 49 50 /* select channel */ 51 clrsetbits32(&rk3399_saradc->ctrl, 52 ADC_CHN_SEL_MASK << ADC_CHN_SEL_SHIFT, 53 chn << ADC_CHN_SEL_SHIFT); 54 55 /* power up */ 56 setbits32(&rk3399_saradc->ctrl, ADC_PWR_CTRL); 57 58 udelay(SARADC_DELAY_PU); 59 60 stopwatch_init_msecs_expire(&sw, 10); 61 do { 62 if (read32(&rk3399_saradc->stas) == ADC_STOP) { 63 adc_value = read32(&rk3399_saradc->data) & DATA_MASK; 64 return adc_value; 65 } 66 } while (!stopwatch_expired(&sw)); 67 68 return -1; 69 } 70