From mboxrd@z Thu Jan 1 00:00:00 1970 From: Przemyslaw Marczak Date: Fri, 04 Sep 2015 17:04:29 +0200 Subject: [U-Boot] [PATCH 6/7] Exynos: add internal ADC driver In-Reply-To: References: <1440770374-11501-1-git-send-email-p.marczak@samsung.com> <1440770374-11501-7-git-send-email-p.marczak@samsung.com> Message-ID: <55E9B2FD.70306@samsung.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hello, On 09/01/2015 02:33 AM, Simon Glass wrote: > Hi Przemyslaw, > > On 28 August 2015 at 07:59, Przemyslaw Marczak wrote: >> This commit adds driver for Voltage Level Monitor based >> on 12-bit resolution internal ADC with 9-channel multiplexer. >> >> New function: >> - exynos_adc_read_channel(int channel) - returns an 12-bit average >> value after 8 time conversion, done by the hardware. >> The default sample rate is: 600kSPS. The channel range: 0-9. >> >> Signed-off-by: Przemyslaw Marczak >> --- >> arch/arm/mach-exynos/Makefile | 1 + >> arch/arm/mach-exynos/adc.c | 83 +++++++++++++++++++++++++++++++++ >> arch/arm/mach-exynos/include/mach/adc.h | 45 ++++++++++++++++++ >> arch/arm/mach-exynos/include/mach/cpu.h | 4 +- >> 4 files changed, 131 insertions(+), 2 deletions(-) >> create mode 100644 arch/arm/mach-exynos/adc.c > > Can we add this to the device tree? Maybe we should even have a driver > model uclass for ADC? > Ok, I can add a simple ADC uclass. >> >> diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile >> index 8542f89..4b7f91f 100644 >> --- a/arch/arm/mach-exynos/Makefile >> +++ b/arch/arm/mach-exynos/Makefile >> @@ -7,6 +7,7 @@ >> >> obj-y += clock.o power.o soc.o system.o pinmux.o tzpc.o >> >> +obj-$(CONFIG_EXYNOS5420) += adc.o >> obj-$(CONFIG_EXYNOS5420) += sec_boot.o >> >> ifdef CONFIG_SPL_BUILD >> diff --git a/arch/arm/mach-exynos/adc.c b/arch/arm/mach-exynos/adc.c >> new file mode 100644 >> index 0000000..e8dd619 >> --- /dev/null >> +++ b/arch/arm/mach-exynos/adc.c >> @@ -0,0 +1,83 @@ >> +/* >> + * Copyright (C) 2015 Samsung Electronics >> + * Przemyslaw Marczak >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> +#include >> +#include >> +#include >> +#include >> + >> +extern void sdelay(unsigned long loops); >> + >> +struct exynos_adc_v2 *exynos_adc_probe(void) >> +{ >> + struct exynos_adc_v2 *adc; >> + >> + adc = (struct exynos_adc_v2 *)samsung_get_base_adc(); >> + if (!adc) { >> + error("Invalid ADC base address!"); >> + return NULL; >> + } >> + >> + /* Check HW version */ >> + if (readl(&adc->version) != ADC_V2_VERSION) { >> + error("This driver supports only ADC v2!"); >> + return NULL; >> + } >> + >> + /* ADC Reset */ >> + writel(ADC_V2_CON1_SOFT_RESET, &adc->con1); >> + >> + return adc; >> +} >> + >> +static void exynos_adc_start_conversion(struct exynos_adc_v2 *adc, int channel) >> +{ >> + unsigned int cfg; >> + >> + /* Disable INT - will read status only */ >> + writel(0x0, &adc->int_en); >> + >> + /* CON2 - set conversion parameters */ >> + cfg = ADC_V2_CON2_C_TIME(3); /* Conversion times: (1 << 3) = 8 */ >> + cfg |= ADC_V2_CON2_OSEL(OSEL_BINARY); >> + cfg |= ADC_V2_CON2_CHAN_SEL(channel); >> + cfg |= ADC_V2_CON2_ESEL(ESEL_ADC_EVAL_TIME_20CLK); >> + cfg |= ADC_V2_CON2_HIGHF(HIGHF_CONV_RATE_600KSPS); >> + writel(cfg, &adc->con2); >> + >> + /* Start conversion */ >> + cfg = readl(&adc->con1); >> + writel(cfg | ADC_V2_CON1_STC_EN, &adc->con1); >> +} >> + >> +int exynos_adc_read_channel(int channel) >> +{ >> + struct exynos_adc_v2 *adc; >> + int timeout_us = ADC_V2_CONV_TIMEOUT_US; >> + >> + adc = exynos_adc_probe(); >> + if (!adc) { >> + error("Can't init ADC!"); >> + return -ENODEV; >> + } >> + >> + if (channel > ADC_V2_MAX_CHANNEL) { >> + error("ADC: max channel is: %d.", ADC_V2_MAX_CHANNEL); >> + return -ENODEV; >> + } >> + >> + exynos_adc_start_conversion(adc, channel); >> + >> + while (ADC_V2_GET_STATUS_FLAG(readl(&adc->status)) != FLAG_CONV_END) { >> + sdelay(4); >> + if (!timeout_us--) { >> + error("ADC conversion timeout!"); >> + return -ETIME; >> + } >> + } >> + >> + return readl(&adc->dat) & ADC_V2_DAT_MASK; >> +} >> diff --git a/arch/arm/mach-exynos/include/mach/adc.h b/arch/arm/mach-exynos/include/mach/adc.h >> index a0e26d7..228acf4 100644 >> --- a/arch/arm/mach-exynos/include/mach/adc.h >> +++ b/arch/arm/mach-exynos/include/mach/adc.h >> @@ -9,6 +9,38 @@ >> #ifndef __ASM_ARM_ARCH_ADC_H_ >> #define __ASM_ARM_ARCH_ADC_H_ >> >> +#define ADC_V2_CON1_SOFT_RESET (0x2 << 1) >> +#define ADC_V2_CON1_STC_EN (0x1) >> + >> +#define ADC_V2_CON2_OSEL(x) (((x) & 0x1) << 10) >> +#define OSEL_2S (0x0) >> +#define OSEL_BINARY (0x1) >> +#define ADC_V2_CON2_ESEL(x) (((x) & 0x1) << 9) >> +#define ESEL_ADC_EVAL_TIME_40CLK (0x0) >> +#define ESEL_ADC_EVAL_TIME_20CLK (0x1) >> +#define ADC_V2_CON2_HIGHF(x) (((x) & 0x1) << 8) >> +#define HIGHF_CONV_RATE_30KSPS (0x0) >> +#define HIGHF_CONV_RATE_600KSPS (0x1) >> +#define ADC_V2_CON2_C_TIME(x) (((x) & 0x7) << 4) >> +#define ADC_V2_CON2_CHAN_SEL(x) ((x) & 0xf) >> + >> +#define ADC_V2_GET_STATUS_FLAG(x) (((x) >> 2) & 0x1) >> +#define FLAG_CONV_END (0x1) >> + >> +#define ADC_V2_INT_DISABLE (0x0) >> +#define ADC_V2_INT_ENABLE (0x1) >> +#define INT_NOT_GENERATED (0x0) >> +#define INT_GENERATED (0x1) >> + >> +#define ADC_V2_VERSION (0x80000008) >> + >> +#define ADC_V2_MAX_CHANNEL (9) >> + >> +/* For default 8 time convertion with sample rate 600 kSPS - 15us timeout */ >> +#define ADC_V2_CONV_TIMEOUT_US (15) >> + >> +#define ADC_V2_DAT_MASK (0xfff) >> + >> #ifndef __ASSEMBLY__ >> struct s5p_adc { >> unsigned int adccon; >> @@ -21,6 +53,19 @@ struct s5p_adc { >> unsigned int adcmux; >> unsigned int adcclrintpndnup; >> }; >> + >> +struct exynos_adc_v2 { >> + unsigned int con1; >> + unsigned int con2; >> + unsigned int status; >> + unsigned int dat; >> + unsigned int int_en; >> + unsigned int int_status; >> + unsigned int reserved[2]; >> + unsigned int version; >> +}; >> + >> +int exynos_adc_read_channel(int channel); >> #endif >> >> #endif /* __ASM_ARM_ARCH_ADC_H_ */ >> diff --git a/arch/arm/mach-exynos/include/mach/cpu.h b/arch/arm/mach-exynos/include/mach/cpu.h >> index 14a1692..75933e7 100644 >> --- a/arch/arm/mach-exynos/include/mach/cpu.h >> +++ b/arch/arm/mach-exynos/include/mach/cpu.h >> @@ -167,10 +167,11 @@ >> #define EXYNOS5420_USB_HOST_EHCI_BASE 0x12110000 >> #define EXYNOS5420_MMC_BASE 0x12200000 >> #define EXYNOS5420_SROMC_BASE 0x12250000 >> -#define EXYNOS5420_USB3PHY_BASE 0x12500000 >> +#define EXYNOS5420_USB3PHY_BASE 0x12500000 > > unrelated change? > Yes, will remove. >> #define EXYNOS5420_UART_BASE 0x12C00000 >> #define EXYNOS5420_I2C_BASE 0x12C60000 >> #define EXYNOS5420_I2C_8910_BASE 0x12E00000 >> +#define EXYNOS5420_ADC_BASE 0x12D10000 > > Then we can drop this. > Right >> #define EXYNOS5420_SPI_BASE 0x12D20000 >> #define EXYNOS5420_I2S_BASE 0x12D60000 >> #define EXYNOS5420_PWMTIMER_BASE 0x12DD0000 >> @@ -186,7 +187,6 @@ >> #define EXYNOS5420_USBPHY_BASE DEVICE_NOT_AVAILABLE >> #define EXYNOS5420_USBOTG_BASE DEVICE_NOT_AVAILABLE >> #define EXYNOS5420_FIMD_BASE DEVICE_NOT_AVAILABLE >> -#define EXYNOS5420_ADC_BASE DEVICE_NOT_AVAILABLE >> #define EXYNOS5420_MODEM_BASE DEVICE_NOT_AVAILABLE >> #define EXYNOS5420_USB_HOST_XHCI_BASE DEVICE_NOT_AVAILABLE >> >> -- >> 1.9.1 >> > > Regards, > Simon > Thanks, -- Przemyslaw Marczak Samsung R&D Institute Poland Samsung Electronics p.marczak at samsung.com