xref: /aosp_15_r20/external/coreboot/src/soc/rockchip/rk3399/saradc.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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)39 u32 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