Angel Pons | bbc99cf | 2020-04-04 18:51:23 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 2 | |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 3 | #include <device/mmio.h> |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 4 | #include <assert.h> |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 5 | #include <delay.h> |
| 6 | #include <soc/clock.h> |
| 7 | #include <soc/saradc.h> |
| 8 | #include <stdint.h> |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 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 | |
Lin Huang | 1df0c57 | 2018-01-31 10:28:47 +0800 | [diff] [blame] | 33 | #define SARADC_HZ (4*MHz) |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 34 | |
| 35 | #define SARADC_MAX_CHANNEL 6 |
| 36 | |
Lin Huang | 1df0c57 | 2018-01-31 10:28:47 +0800 | [diff] [blame] | 37 | #define SARADC_DELAY_PU (1 * 1000 * 1000 * 1000 / SARADC_HZ * 4) |
| 38 | |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 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 */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 48 | clrbits32(&rk3399_saradc->ctrl, ADC_PWR_CTRL); |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 49 | |
| 50 | /* select channel */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 51 | clrsetbits32(&rk3399_saradc->ctrl, |
| 52 | ADC_CHN_SEL_MASK << ADC_CHN_SEL_SHIFT, |
| 53 | chn << ADC_CHN_SEL_SHIFT); |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 54 | |
| 55 | /* power up */ |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 56 | setbits32(&rk3399_saradc->ctrl, ADC_PWR_CTRL); |
Lin Huang | bf48fbb | 2016-03-23 19:24:53 +0800 | [diff] [blame] | 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 | } |